双向链表实现

注意事项:

  1. 双向链表的头结点的prior指向最后的结点。最后一个结点的next指向头结点
  2. 在初始化链表时,前驱后继指针均指向头结点。
  3. 双向链表是循环链表的一个扩充。但是使用的是头结点。
#include<stdio.h>
#include<stdlib.h>
typedef struct DuLNode
{
	int data;
	struct DuLNode *prior, *next;
}DuLNode, *DuLinkList;
 
DuLinkList Creat() //正序,尾插
{
	DuLinkList L = (DuLinkList)malloc(sizeof(DuLNode));
	L->next = L->prior = L;
	L->data = -1;
	printf("Please enter the number:\n");
	int n;
	scanf_s("%d", &n);
	printf("the number:\n");
	DuLinkList q = L; //需要一个指针作为建立链表时表示其前一个结点。
	for (int i = 0; i < n; i++)
	{
		DuLinkList p = (DuLinkList)malloc(sizeof(DuLNode));
		scanf_s("%d", &p->data);
		p->next = L;
		q->next = p;
		p->prior = q;
		q = p;
	}
	return L;
 
}
void Destroy(DuLinkList L)//实际上是clearlist不销毁链表,如果销毁需要把头结点一起释放
{
	DuLinkList q;
	q = L->next;
	while (q != L)
	{
		q = q->next;
		free(q->prior);
	}
	L->next = L->prior = L;
}
void Insert(DuLinkList L, int val, int index)
{
	DuLinkList q, p;
	p = (DuLinkList)malloc(sizeof(DuLNode));
	p->data = val;
	q = L->next;
	int i = 1;
	while (q != L && i < index - 1)
	{
		i++;
		q = q->next;
	}
	p->next = q->next;
	q->next->prior = p;//这里需要注意一下,需要把新插入的结点的后一个结点指向新节点
	q->next = p;
	p->prior = q;
}
void Delete(DuLinkList L, int index)
{
	DuLinkList q = L->next;
	int i = 1;
	while (q != L && i < index)//这里找到第i个结点而不是i-1个
	{
		i++;
		q = q->next;
	}
	q->prior->next = q->next;//这里运用了双向链表的优势
	q->next->prior = q->prior;//不需要额外一个指针指向前一个
	free(q);
}
void Traverse(DuLinkList L)
{
	DuLinkList q = L->next;
	while (q != L)
	{
		printf("%d->", q->data);
		q = q->next;
	}
	printf("NULL\n");
}
 
int main()
{
	DuLinkList L = Creat();
	Traverse(L);
	Insert(L, 5, 3);
	Traverse(L);
	Delete(L, 3);
	Traverse(L);
	Destroy(L);
	Traverse(L);
}

上一篇:03.双向链表(五)


下一篇:朴素贝叶斯