单链表的增删改查,双向链表的删除操作
Yyds干货库存
作者:云晓艺个人主页:云晓洋主页
代码:云小洋(yuxiaoyang 003)-gitee . com
座右铭:你要敢于默默面对自己。强大才是核心。不要等到什么都没有了才下定决心去做。种一棵树最好的时间是十年前,其次是现在!学会和解自己,与过去和解,试着爱自己。希望在春天到来之前,我们一起面朝大海,春暖花开!
专栏:C语言初学者专栏:C语言高级专栏:数据结构与算法
专栏:早期C-高级C-学习Linux
@ TOC
前言今天我们来谈谈:数据结构中链表的双向循环前导表。第一次听到双向循环前导表的同学可能会觉得双向循环前导表很复杂。双向循环前导表的结构确实有点复杂,但是它的操作非常简单,容易操作。那么现在就让云小易带你了解和学习一下双向循环领先榜吧。
——————————————————————————————
首先写几句话:献给坚持创作的我和点击此文进步的你。
1.天下一片恐慌,不过是想破银而已。偏偏这破银能解人间愁绪,能让父母安康,能保护年幼子女的成长,但这破银也打碎了他们童年的梦想,让少年饱经沧桑,背过身去。
2.一瞬间,我抛掉了心中的空虚和匮乏,沏了一杯淡淡的茶,在夕阳下一层一层地洒在桌上。一瞬间,我似乎忘记了过去的阴霾和伤害。林对说,“温柔是必要的,但不是妥协。我们应该从容不迫,坚强起来。
1.链表的分类:单向、双向前导、循环无前导、非循环。
今天我们来说说看似结构复杂的双向循环前导链表:
2.双向链表初始化:方法1:传递双指针Void ListNode init(ListNode * * pphead)
{
* PP head=listnode buy(0);
//ListNodeBuy(0)是一个函数,创建一个存放0的地址,这个函数后面会写。
(* PP head)-next=* PP head;
(* PP head)-prev=* PP head;
}方法二:返回值方法ListNode* ListNodeInit()
{
ListNode * phead=ListNode buy(0);
phead-next=phead;
phead-prev=phead;
返回phead
}加上它在主函数上说:
ListNode * phead=ListNode init();可以完成双向链表的初始化。
PS:当双向循环头链表为空时,即只有头指针时,head- next和head- prev都指向自己(head)
3.双链表打印(1)运行代码:void ListPrint(ListNode* phead)
{
断言(phead);
ListNode * cur=phead-next;
而(cur!=phead)
{
printf(%d ,cur-data);
cur=cur-next;
}
printf( \ n );
}这里记住双向循环前导链表打印的终止条件是:当cur遍历回phead!
(2)运行结果:
4.双链表的尾插入:(1)运行代码:由于插入时需要创建一个变量newnode,所以需要在内存中申请变量的空间存储,变量的值就是插入的值,而且由于每次插入都需要这一步,所以将这一步写成一个函数,使用起来很方便:
ListNode * ListNode buy(lt datatype x)
{
ListNode * new node=(ListNode *)malloc(sizeof(ListNode));
new node-next=NULL;
new node-prev=NULL;
new node-data=x;
返回newnode
}尾部插值函数:
void ListNode推回(ListNode* phead,LTDataType x)
{
断言(phead);
ListNode * tail=phead-prev;
ListNode * new node=ListNode buy(x);
tail-next=new node;
new node-prev=tail;
new node-next=phead;
phead-prev=new node;
}(2)运行结果:
5.双向链表的尾部删除(1)运行代码:void listnode popback(listnode * phead)
{
断言(phead);
//这是调用断言函数,意思是判断phead是否为NULL。
断言(phead- next!=phead);
//这是判断链表是否为空,如果为空则报错。
ListNode * tail=phead-prev;
list node * tail _ prev=tail-prev;
tail _ prev-next=phead;
phead-prev=tail _ prev;
自由(尾巴);
tail=NULL
}断言(ph EAD);//这是调用断言函数,该表达式的意思为判断菲德是否为空值
断言(phead-下一个!=phead//这是判断该链表是否为空链表,若为空链表,则会报错
(2)运行结果:
6.双向链表的头插:(1)运行代码:参见listnode pushfran(listnode * phead,LTDataType x)
{
断言(phead);
listnode * first=phead-next;
listnode * new node=listnode buy(x);
phead-next=新节点;
新节点-下一个=第一个:
new node-prev=phead;
first- prev=newnode:
}注:头插是是将新节点(新节点)插在菲德和第一(头结点后的第一个结点)
(2)运行结果:
7.双向链表的头删:(1)运行代码:请参阅listnode pop front(listnode * phead)
{
断言(phead);
//这是调用断言函数,该表达式的意思为判断菲德是否为空值
断言(phead-下一个!=phead
//这是判断该链表是否为空链表,若为空链表,则会报错
listnode * first=phead-next;
ListNode* second=first- next:
phead- next=秒;
秒-预测=phead
自由(第一);
first=NULL:
}
(2)运行结果:
8.双向链表的查找(1)运行代码:listnode * listnode find(listnode * phead,LTDataType x)
{
断言(phead);
listnode * cur=phead-next;
而(当前值!=phead)
{
if (cur- data==x)
返回当前值;
cur=cur-next;
}
返回空:
}查找后返回的是结点的指针,可以用刷卡机数据=某个数进而修改这个点的值!
(2)运行结果:
9.双向链表的中间插入:(1)运行代码:插入在指定位置的前面
请参阅ListNodeInsert(ListNode* pos、LTDataType x)
{
断言(pos);
ListNode* pos_prev=pos- prev:
listnode * new node=listnode buy(x);
newnode- next=pos:
pos-prev=新节点;
pos_prev- next=newnode:
newnode- prev=pos_prev:
}(2)运行结果:
10.双向链表的中间删除:(1)运行代码:请参阅ListNodeErase(ListNode* pos)
{
断言(pos);
ListNode* pos_prev=pos- prev:
ListNode* next=pos- next:
自由(pos);
pos=NULL:
pos_prev- next=next:
下一预测=pos_prev:
}(2)运行结果:
11.双向链表的销毁:每一次用完链表后销毁是很有必要的,如果不销毁,将会导致内存的泄露,短时间内可能没用什么,且很难被发现,但时间长了,必将导致程序的崩溃,最终将导致时间和金钱的浪费!这里介绍两种销毁:方法一:销毁全部,不保留头结点:
请参阅ListNodeDestroy(ListNode* phead)
{
断言(phead);
listnode * cur=phead
而(当前值!=phead)
{
listnode * next=cur-next;
自由(cur);
cur=null
cur=下一个;
}
自由(phead);
phead=NULL:
}方法二:保留头结点:
请参阅ListNodeDestroy(ListNode* phead)
{
断言(phead);
listnode * cur=phead
而(当前值!=phead)
{
listnode * next=cur-next;
自由(cur);
cur=null
cur=下一个;
}
}具体选择哪一种,需要看实际需要!
12.完整代码:(1)附表h文件定义CRT_SECURE_NO_WARNINGS 1
#杂注一次
#包括标准视频
#包括标准库
#include assert.h包含断言
typedef int ltdatatype
typedef结构列表节点类型定义结构清单节点
{
结构列表节点*预测:
ltdatatype数据
结构列表节点*下一个
}列表节点
listnode * listnode buy(lt datatype x);
参见listnode init(listnode * * PP head);
见listnode * phead
参见listnode push back(listnode * phead,lt datatype x);
参见listnode pop back(listnode * phead);
参见listnode pushfran(listnode * phead,lt datatype x);
见listnode pop front(listnode * phead);
listnode * listnode find(listnode * phead,lt datatype x);
请参阅ListNodeInsert(ListNode* pos、lt datatype x);
请参阅listnode erase(listnode * pos);
参见listnode destroyer(listnode * phead);(2)附表c文件:#includeList.h
# define _ CRT _ secure _ no _ warnings 1
listnode * listnode buy(lt datatype x)
{
listnode * new node=(listnode *)malloc(sizeof(listnode));
newnode- next=NULL:
newnode- prev=NULL:
节点数据=x:
返回新节点;
}
请参阅ListNodeInit(ListNode** pphead)
{
* PP head=listnode buy(0);
(* pphead)下一个=* pphead
(*pphead)预测=* pphead
}
ListNode* ListNodeInit()
{
listnode * phead=listnode buy(0);
ph head-next=ph head;
ph EAD-prev=ph EAD;
返回phead
}
请参阅ListPrint(ListNode* phead)
{
断言(phead);
listnode * cur=phead-next;
而(当前值!=phead)
{
printf("% d,cur-日期");
cur=cur-next;
}
printf(" \ n ");
}
请参阅listnode推回(listnode * phead,LTDataType x)
{
断言(phead);
ListNode* tail=phead- prev(列表节点*尾部=phead-预测):
listnode * new node=listnode buy(x);
尾部-下一个=新节点:
newnode- prev=tail(新节点-预测=尾部):
new node-next=phead;
phead-prev=新节点;
}
请参阅ListNodePopBack(ListNode* phead)
{
断言(phead);
断言(phead-下一个!=phead
ListNode* tail=phead- prev(列表节点*尾部=phead-预测):
ListNode* tail_prev=tail- prev:
tail _ prev-next=phd;
phead- prev=tail_prev:
自由(尾部);
尾部=空:
}
请参阅listnode pushfran(listnode * phead,LTDataType x)
{
断言(phead);
listnode * first=phead-next;
listnode * new node=listnode buy(x);
phead-next=新节点;
新节点-下一个=第一个:
new node-prev=phead;
first- prev=newnode:
}
请参阅listnode pop front(listnode * phead)
{
断言(phead);
断言(phead-下一个!=phead
listnode * first=phead-next;
ListNode* second=first- next:
phead- next=秒;
秒-预测=phead
自由(第一);
first=NULL:
}
listnode * listnode find(listnode * phead,LTDataType x)
{
断言(phead);
listnode * cur=phead-next;
而(当前值!=phead)
{
if (cur- data==x)
返回当前值;
cur=cur-next;
}
返回空:
}
请参阅ListNodeInsert(ListNode* pos、LTDataType x)
{
断言(pos);
ListNode* pos_prev=pos- prev:
listnode * new node=listnode buy(x);
newnode- next=pos:
pos-prev=新节点;
pos_prev- next=newnode:
newnode- prev=pos_prev:
}
请参阅ListNodeErase(ListNode* pos)
{
断言(pos);
ListNode* pos_prev=pos- prev:
ListNode* next=pos- next:
自由(pos);
pos=NULL:
pos_prev- next=next:
下一预测=pos_prev:
}
请参阅ListNodeDestroy(ListNode* phead)
{
断言(phead);
listnode * cur=phead
而(当前值!=phead)
{
listnode * next=cur-next;
自由(cur);
cur=null
cur=下一个;
}
}(3)测试。c文件:#includeList.h
# define _ CRT _ secure _ no _ warnings 1
int main(请参阅)
{
listnode * phead=null
listnodeinit(phead);
/* listnodeestback(phead,1);
ListNodePushBack(phead,2);
listnodeestback(phead,3);
listnodeestback(phead,4);
listnodeestback(phead,5);
listnodeestback(phead,6);
list print(phead);
ListNodePopBack(phead,1);
ListNodePopBack(phead,2);
ListNodePopBack(phead,3);
ListNodePopBack(phead,4);
ListNodePopBack(phead,5);
list print(phead);*/
listnodepushferan(phead,1);
listnodepushferan(phead,2);
listnodepushferan(phead,3);
listnodepushfront(菲律宾国防部长,4);
listnodepushferan(phead,5);
listnodepushferan(phead,6);
list print(phead);
/*ListNodePopFront(phead,1);
listnodepofront(phead,2);
listnodepofront(phead,3);
listnodepofront(phead,4);
listnodepofront(phead,5);
list print(phead);*/
listnode * pos=listnode find(phead,3);
刷卡机数据=300:
list print(phead);
ListNodeInsert(位置,1);
list print(phead);
listnode erase(pos);
list print(phead);
listnode destroyer(phead);
返回0;
}最后十分感谢你可以耐着性子把它读完和我可以坚持写到这里,送几句话,对你,也对我:
1.也许你要早上七点起床,晚上十二点睡觉,日复一日,踽踽独行。但只要笃定而努力地活着,即使生不逢时,你人生最坏的结果,也只是大器晚成。
2.这个世界根本不存在""不会""这回事。当你失去所有依靠的时候,你自然就什么都会了。
3.当你足够优秀时,你周围的一切自然都会好起来。
4.人一旦堕落,哪怕是短暂的几年,上帝就会以最快的速度,收走你的天赋和力量。5 .你所做的事情,也许暂时看不到成果,但不要灰心或焦虑,你不是没有成长,而是在扎根。
最后如果觉得我写的还不错,请不要忘记点赞,收藏,加关注哦()
让我们一起为美好的未来而努力,让我们从一个懵懂的菜鸟逐渐成为大人物。加油,夸夸自己!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。