双向链表专题

⽬录
1. 双向链表的结构
2. 实现双向链表
3. 顺序表和双向链表的分析
正⽂开始

1. 双向链表的结构

注意:这⾥的“带头”跟前⾯我们说的“头节点”是两个概念,实际前⾯的在单链表阶段称呼不严
谨,但是为了同学们更好的理解就直接称为单链表的头节点。
带头链表⾥的头节点,实际为“哨兵位”,哨兵位节点不存储任何有效元素,它其实就是编译器生成的随机值然后存这前驱节点和后继节点,只是站在这⾥“放哨
的”
“哨兵位”存在的意义:
遍历循环链表避免死循环。

2. 双向链表的实现

2.1完整代码

 typedef int LTDataType;
 typedef struct ListNode
 {
     struct ListNode* next; //指针保存下⼀个节点的地址
     struct ListNode* prev; //指针保存前⼀个节点的地址
     LTDataType data;
 }LTNode;

//void LTInit(LTNode** pphead);
LTNode* LTInit();
void LTDestroy(LTNode* phead);
void LTPrint(LTNode* phead);
bool LTEmpty(LTNode* phead);
void LTPushBack(LTNode* phead, LTDataType x);
void LTPopBack(LTNode* phead);
void LTPushFront(LTNode* phead, LTDataType x);
void LTPopFront(LTNode* phead);
//在pos位置之后插⼊数据
void LTInsert(LTNode* pos, LTDataType x);
void LTErase(LTNode* pos);
LTNode *LTFind(LTNode* phead,LTDataType x);

2.2具体实现 

老样子先创建三个文件

 在头文件这里定义我们双向循环链表的结构        

2.2.1双向链表结构体

2.2.2LTInit实现

 这里我们传入的是二级指针因为我们原本传入的就是指针,我们需要对头指针进行修改所以这里的形参属于二级指针

 这里初始化需要用到malloc,这里再我们写的头文件里面加上这三个需要用到的头文件

 这里可以看到next和prev都已经指向了自己

 这种方法也是可以的

 我们现在有了一个这样的双向链表那么我们就可以插入数据了接下来就是头插入和尾插了

2.2.3LTPushBack实现

思考:下面的参数哪一个是正确的

 正确答案是第二个

为什么?为什么? 为什么?为什么?为什么? 为什么?

这里可能会有疑问为什么写单项链表的时候传入的是二级指针呢

概念:双向循环链表只存在一个哨兵位(头节点)那么我们叫这个链表为空链表,上文我们说过我们传入二级指针只不过是为了改变指针的数值,但这里的头节点我们在初始化的时候就已经设置好的数值且后期不在需要更改,我们只需要修改头节点(哨兵位)的prev和next就行所以这里只需要传入指针就可。二级指针的作用就是为了改变实参的值而已

尾插需要值插入到尾部需要创建新的节点这里把创建节点封装成一个函数

2.2.3.1LTBuyNode

LTPusBack

 2.2.4LTPrint实现

 2.2.5LTPushFront实现

2.2.6LTPopBack的实现


2.2.7LTPopFront的实现


 2.2.8 LTFind的实现

2.2.9LTInsert的实现

 

2.2.9LTDel的实现

 

2.2.9LTDesTroy的实现

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值