C语言实现双向循环链表贼旮旯详细

C语言实现双向循环链表贼旮旯详细,第1张

C语言实现双向循环链表贼旮旯详细

1.首先了解一下双向循环链表:

 

1.首先需要一个头节点head,里面的data没有意义 .

2.结构体含a.prev b.data  c.next

a:保存前驱的地址

b.数据域

c.保存后继节点的地址

2.头节点的前驱保存的是最后一个节点的地址,最后一个节点的后继地址保存的是头节点的地址.

3.接下来进行双向循环链表的基本 *** 作(注释很详细):

#include 
#include 
#include 
typedef struct linklist {//双向链表的结构体
	int data;
	struct linklist* prev;//指向前驱节点
	struct linklist* next;//指向后面节点
}node;
//1.创建头节点
node* CreatHeadnode() {
	node* newnode = (node*)malloc(sizeof(node));
	newnode->next = newnode;//让自己指向自己
	newnode->prev = newnode;//同上
	return newnode;
}
//2.创建节点
node* Creatnode(int x) {
	node* newnode = (node*)malloc(sizeof(node));
	newnode->data = x;
	newnode->next = NULL;
	newnode->prev = NULL;
	return newnode;
}
//3.打印双向链表
void NodePrint(node* head) {
	assert(head);
	node* cur = head->next;//让指针指向头节点的后一个
	while (cur!=head) {//因为是双向循环链表所以不能一直打印打印一遍即可
		printf("%d ", cur->data);
		cur = cur->next;
	}
	printf("n");
}
//4.双向链表的尾插
void Pushback(node* head, int x) {
	assert(head);
	node* newnode = Creatnode(x);//创建新节点
		newnode->next = head;//新节点的下一个指向头节点
		newnode->prev = head->prev;//新节点的前驱指向头的前驱
		head->prev->next = newnode;//头节点的前驱的下一个指向新节点
		head->prev = newnode;//头节点的前驱指向新节点
	
}
//5.双向链表的查找
node* Findnode(node* head,int x) {//便利链表寻找
	assert(head);
	node* cur = head->next;
	while (cur!= head) {
		if (cur->data == x) {
			return cur;
		}
		else {
			cur = cur->next;
		}
	}
	return NULL;
}
//6.链表的尾删
void Popback(node* head) {
	assert(head);
	if (head->next == NULL) {
		return ;
	}
	else {
		node* cur = head->prev;//把头的前驱用cur指
		head->prev = cur->prev;//尾节点的前驱赋给头的前驱
		cur->prev->next = head;//把头赋予尾节点的前驱的next
		free(cur);//删除尾节点
	}
}
//6.链表的头插
void PushFront(node* head, int x) {
	assert(head);
	node* newnode = Creatnode(x);
	newnode->next = head->next;//新节点的next赋值头节点的next
	newnode->prev = head;//新节点的前驱赋值
	head->next->prev = newnode;//断链
	head->next = newnode;//断链
}
//7.链表的头删
void Popfront(node* head) {
	assert(head);
	node* cur = head->next;
	head->next = cur->next;//头节点的next指向待删节点的next
	cur->next->prev = head;//待删节点的next的前驱赋值为head
	free(cur);
}
//8.链表任意位置插入
void InsertNode(node* pos, int x) {
	assert(pos);
	if (pos == NULL) {
		return;
	}
	node* newnode = Creatnode(x);
	newnode->next = pos;//链接新节点的next
	newnode->prev = pos->prev;//链接新节点的prev
	pos->prev->next = newnode;//断开pos的前驱的next并链接新节点
	pos->prev = newnode;//链接pos前驱
}
//9.链表任意位置删除
void DeletNode(node* pos) {
	pos->prev->next = pos->next;//pos的前驱的next指向其后继
	pos->next->prev = pos->prev;//pos的next的前驱指向pos的前驱
	free(pos);
}
//10.链表的销毁
void Destorynode(node* head) {
	node* cur = head->next;
	while (cur != head) {//头删
		head->next = cur->next;
		cur->next->prev = cur->prev;
		free(cur);
		cur = head->next;
	}
	head = NULL;
	cur == NULL;
}
void test1() {
	node* head = CreatHeadnode();//创建头节点
	Pushback(head, 1);//尾插1
	Pushback(head, 2);//尾插2
	Pushback(head, 3);//尾插3
	Pushback(head, 4);//尾插4
	Pushback(head, 5);//尾插5
	NodePrint(head);// 打印  1 2 3 4 5
	Popback(head);//尾删
	NodePrint(head);//打印   1 2 3 4
	PushFront(head, 0);//头插0
	NodePrint(head);//打印   0 1 2 3 4
	Popfront(head);//头删
	NodePrint(head);//打印   1 2 3 4
	InsertNode(Findnode(head, 4), 3);//在4的前面插入3
	InsertNode(Findnode(head, 1), 0);//在1的前面插入0
	NodePrint(head);//打印   0 1 2 3 3 4
	DeletNode(Findnode(head, 3));//删除3
	DeletNode(Findnode(head, 1));//删除1
	NodePrint(head);//打印   0 2 3 4
	Destorynode(head);//销毁链表
}
void test() {
	test1();
}
int main() {
	test();
	return 0;
}

4.运行结果:

 

5.分析测试结果 :

1.首先创建头节点

2.尾插1 2 3 4 5

3.打印1 2 3 4 5

4.尾删

5.打印1 2 3 4

6.头插0

7.打印 0 1 2 3 4

8.头删

9.打印 1 2 3 4

10.在4 前面插入3,在1前面插入0

11.打印 0 1 2 3 3 4

12.删除3,1

13.打印  0 2 3 4

14.销毁链表

学会了吗铁汁?学会了扣1,没学会扣脚~

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5634660.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-15
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存