前言
❤️ 铁子们大家好,欢迎大家来到出小月的博客里,今天给大家带来的是【数据结构】之带头双向循环链表的增、删、查、改,这可是很重要的东西哦❗
希望大家看完我这篇文章都能够“涨芝士”,感觉小月写的还不错的话,记得👍🏻点赞加关注😘鼓励一下博主哦,不然下次可找不到我啦❗❗
作者介绍
❤️作者的gitee:出小月;
❤️ 作者的主页:出小月的《程序员历险记》
❤️专栏:《数据结构初级》
❤️跟大家分享一勺鸡汤:请做足够多的努力,让自己有足够多的选择,让我们一起干了这碗鸡汤
文章目录
一、双向带头循环链表
上一篇呢我们说了无头单向非循环链表,它有什么特点呢?
它的结构简单,一般不会单独存储数据,实际中更多作为其他数据结构的子结构。
今天我们来说,带头双向循环链表,它呢,结构最复杂🤨🤨,虽然结构很复杂,但是使用代码实现以后会发现结构带来了很多优势😍😍,反而容易实现,后面我们实现代码就知道啦❗❗
🤨🤨就比如说,之前我们单链表需要删除最后一个元素时,是不是得找到前一个元素,然后把最后一个元素删除,还得把指向前一个元素的指针指向空。但是前一个元素怎么找呢❓❓这是一个问题,于是我们用了前后指针,但是如果用了这个双向的链表,我就不用从头遍历了,直接就找到了❗❗❗
二、具体实现
1.结构
typedef double dldatatype;
typedef struct dlist
{
struct dlist* next;
struct dlist* prev;
dldatatype data;
}dlist;
2.初始化链表
dlist* dlistinit()
{
dlist* dl = createnode(0);
dl->next = dl;
dl->prev = dl;
return dl;
}
3、产生一个新节点
dlist* createnode(dldatatype x)
{
dlist* newnode = (dlist*)malloc(sizeof(dlist));
newnode->data = x;
newnode->next = NULL;
newnode->prev = NULL;
return newnode;
}
4、头插数据
思路:😁用next记住原来的首元结点,让新节点成为新的首元结点,新节点的next值是next;
void dlistpushfront(dlist* dl, dldatatype x)
{
assert(dl);
dlist* next = dl->next;
dlist* newnode = createnode(x);
dl->next = newnode;
newnode->prev = dl;
newnode->next = next;
next->prev = newnode;
}
5、尾插数据
思路:👍👍尾结点的的下一个值是新节点,这个新节点就是插入后的尾结点
void dlistpushback(dlist* dl, dldatatype x)
{
assert(dl);
dlist* tail = dl->prev;
dlist* newnode = createnode(x);
tail->next = newnode;
newnode->prev = tail;
newnode->next = dl;
dl->prev = newnode;
}
6、头删数据
思路:🤗要删除首元结点,首先记住首元结点的下一个值next,然后让头节点的下一个值置为next(原来首元结点的下一个结点);
void dlistpopfront(dlist* dl)
{
assert(dl);
dlist* cur = dl->next;
dlist* next = cur->next;
free(cur);
dl->next = next;
next->prev = dl;
}
7、尾删数据
思路:🎶🎶删除尾结点,把原来尾节点的前一个值,置为现在的尾结点
void dlistpopback(dlist* dl)
{
assert(dl);
dlist* tail = dl->prev;
dlist* prev = tail->prev;
free(tail);
prev->next = dl;
dl->prev = prev;
}
8、找到任意值的位置
dlist* findval(dlist* dl, dldatatype x)
{
dlist* cur = dl;
while (cur)
{
if (cur->data == x)
return cur;
cur = cur->next;
}
return NULL;
}
9、在任意值前插入
void dlistinsert(dlist* dl, dlist* pos, dldatatype x)
{
dlist* prev = pos->prev;
dlist* newnode = createnode(x);
prev->next = newnode;
newnode->prev = prev;
newnode->next = pos;
pos->prev = newnode;
}
10、删除任意值
void dlistdelete(dlist* dl, dlist* pos)
{
dlist* prev = pos->prev;
dlist* next = pos->next;
free(pos);
prev->next = next;
next->prev = prev;
}
11、打印链表
void printdlist(dlist* dl)
{
dlist* cur = dl->next;
while (cur!=dl)
{
printf("%d", cur->data);
cur = cur->next;
}
}
今天就分享到这里了,友友们看都看到这里了记得点赞👍👍🤗加关注哦!!!有什么不懂的地方可以私信博主哦!