数据结构之双向带头循环链表函数功能实现与详细解析

个人主页点我进入主页

专栏分类:C语言初阶 C语言程序设计------------KTV C语言小游戏C语言进阶

C语言刷题 数据结构初阶

欢迎大家点赞,评论,收藏。

一起努力,一起奔赴大厂。

目录

1.前言

2.带头双向循环链表函数实现

3.总结


1.前言

在前面我们写过单链表,循环链表的博客,今天我主要给大家来带关于双向带头循环链表函数的功能与实现,双向带头循环链表相对于单链表,循环链表非常的容易实现,他的函数的功能和 单链表,循环链表一样,如果你想要快速实现一个链表的所有功能,带头双向循环链表非常的容易,接下来让我们看看带头双向链表的奥妙把,看完你绝对会佩服写出这种结构的人。

2.带头双向循环链表函数实现

cpp 复制代码
#include<stdio.h>
#include<stdlib.h>
#include <assert.h>
typedef struct ListNode {
	int data;
	struct ListNode* prev, * next;
}ListNode;
ListNode* ListCreate(int x)
{
	ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));
	if (newnode == NULL)
	{
		perror("malloc");
		return NULL;
	}
	newnode->next = NULL;
	newnode->prev = NULL;
	newnode->data = x;
	return newnode;
}
ListNode* LInit()
{
	ListNode* head = ListCreate(-1);
	head->next = head;
	head->prev = head;
	return head;
}
void ListDestory(ListNode* phead)
{
	assert(phead);
	ListNode* cur = phead->next, * prev = phead;
	while (prev != phead)
	{
		free(prev);
		prev = cur;
		cur = cur->next;
	}
}
void ListPrint(ListNode* phead)
{
	assert(phead);
	ListNode* cur = phead->next;
	printf("哨兵位<=>");
	while (cur != phead)
	{
		printf("%d<=>", cur->data);
		cur = cur->next;
	}
	printf("\n");
}
void ListPushBack(ListNode* phead, int x)
 {
	assert(phead);
	ListNode* newnode = ListCreate(x);
	ListNode* tail = phead->prev;
	tail->next = newnode;
	newnode->prev = tail;
	newnode->next = phead;
	phead->prev = newnode;
}
void ListPushFrount(ListNode* phead, int x)
{
	assert(phead);
	ListNode* newnode = ListCreate(x);
	ListNode* cur = phead->next;
	phead->next = newnode;
	newnode->prev = phead;
	newnode->next = cur;
	cur->prev = newnode;
}
void ListPopBack(ListNode* phead)
{
	assert(phead && phead->next != phead);
	ListNode* cur = phead->prev;
	cur->prev->next = phead;
	phead->prev = cur->prev;
	free(cur);
}
void ListPopFrount(ListNode* phead)
{
	assert(phead && phead->next != phead);
	ListNode* cur = phead->next;
	phead->next = cur->next;
	cur->next->prev = phead;
	free(cur);
}
ListNode* ListFind(ListNode* phead, int x)
{
	assert(phead);
	ListNode* cur = phead->next;
	while (cur->data != x)
	{
		cur = cur->next;
	}
	return cur;
}
void ListInsert(ListNode* pos, int x)
{
	assert(pos);
	ListNode* newnode = ListCreate(x);
	ListNode* cur = pos->prev;
	cur->next = newnode;
	newnode->prev = cur;
	newnode->next = pos;
	pos->prev = newnode;
}
void ListErase(ListNode* pos)
{
	assert(pos);
	ListNode* cur = pos->next;
	ListNode* prev = pos->prev;
	free(pos);
	cur->prev = prev;
	prev->next = cur;
}
void text1()
{
	ListNode* head = LInit();
	ListPushBack(head, 1);
	ListPushBack(head, 2);
	ListPushBack(head, 3);
	ListPushBack(head, 4);
	ListPushBack(head, 5);
	ListPushFrount(head, 0);
	ListPrint(head);
	ListPopBack(head);
	ListPrint(head);
	ListPopBack(head);
	ListPrint(head);
	ListPopFrount(head);
	ListPrint(head);
	ListPopFrount(head);
	ListPrint(head);
	ListPushBack(head, 4);
	ListPushBack(head, 5);
	ListNode* cur = ListFind(head,3);
	ListPushFrount(head, 1);
	ListPushFrount(head, 0);	
	printf("%d\n", cur->data);
	ListPrint(head);
	ListInsert(head, 10);
	ListPrint(head);
}

3.总结

带头双向循环的链表非常的好,接下俩我们对顺序表和链表的存储空间,随机访问,任意位置插入或删除元素,插入,缓存利用率,应用场景进行分析

|---------------|------------------|------------------|
| 不同点 | 顺序表 | 链表 |
| 存储空间上 | 物理上一定连续 | 逻辑上连续,但物理上不一定连 续 |
| 随机访问 | 支持O(1) | 不支持:O(N) |
| 任意位置插入或者删除元 素 | 可能需要搬移元素,效率低O(N) | 只需修改指针指向 |
| 插入 | 动态顺序表,空间不够时需要扩 容 | 没有容量的概念 |
| 应用场景 | 元素高效存储+频繁访问 | 任意位置插入和删除频繁 |
| 缓存利用率 | 高 | 低 |

相关推荐
tanyongxi6618 分钟前
C++ 特殊类设计与单例模式解析
java·开发语言·数据结构·c++·算法·单例模式
闪电麦坤952 小时前
数据结构:在二叉搜索树中插入元素(Insert in a BST)
数据结构·二叉树··二叉搜索树
闪电麦坤952 小时前
数据结构:用链式队列实现层序遍历 (Level-order Traversal)
数据结构··遍历
星星火柴93612 小时前
关于“双指针法“的总结
数据结构·c++·笔记·学习·算法
艾莉丝努力练剑13 小时前
【洛谷刷题】用C语言和C++做一些入门题,练习洛谷IDE模式:分支机构(一)
c语言·开发语言·数据结构·c++·学习·算法
闪电麦坤9514 小时前
数据结构:迭代方法(Iteration)实现树的遍历
数据结构·二叉树·
Cx330❀14 小时前
【数据结构初阶】--排序(五):计数排序,排序算法复杂度对比和稳定性分析
c语言·数据结构·经验分享·笔记·算法·排序算法
散11214 小时前
01数据结构-Prim算法
数据结构·算法·图论
阿巴~阿巴~15 小时前
深入解析C++ STL链表(List)模拟实现
开发语言·c++·链表·stl·list
..过云雨15 小时前
01.【数据结构-C语言】数据结构概念&算法效率(时间复杂度和空间复杂度)
c语言·数据结构·笔记·学习