链表中的双向链表

实际中链表的结构非常多样,以下情况组合起来就有8种链表结构:1. 单向或者双向2. 带头或者不带头3. 循环或者非循环(循环链表指定指向第一个节点,带环链表可能指向任意节点)实际中最常用的是这两种:单项无头不循环链表和双向带头循环链表1. 无头单向非循环链表:结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结构的子结构,如哈希桶、图的邻接表等等。另外这种结构在笔试面试中出现很多。2. 带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构.
摘要由CSDN通过智能技术生成
实际中链表的结构非常多样,以下情况组合起来就有8种链表结构:
1. 单向或者双向
2. 带头或者不带头
3. 循环或者非循环(循环链表指定指向第一个节点,带环链表可能指向任意节点)
实际中最常用的是这两种:单项无头不循环链表和双向带头循环链表
1. 无头单向非循环链表: 结构简单,一般不会单独用来存数据。实际中更多是作为 其他数据结构的子结 ,如哈希桶、图的邻接表等等。另外这种结构在 笔试面试中出现很多。
2. 带头双向循环链表: 结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,实现反而简单了,后面我们代码实现了就知道了。
下面来完成带头双向循环链表的实现
说是实现,其实逻辑比单链表简单的多,完全可以在看完本文后自己实现(前提是链表的题解部分都不看代码自己写了一遍,再完全通过自己调试解决问题)(调试是很重要的技能!)
所以这里就大概说一下思路,剩下的自己检查一下自己链表学的怎么样。
友情提示1:写的时候没有把握可以画图理解
友情提示2:写的时候先解决一般情况,再考虑特殊情况
List.c中
#define _CRT_SECURE_NO_WARNINGS 1
#include"List.h"
ListNode* ListInit(ListNode* phead) //链表的初始化
{
        phead = (ListNode*)malloc(sizeof(ListNode));
        if (phead == NULL)
        {
               return NULL;
        }
        phead->val = 0;
        phead->prev = phead; //因为是带头双向循环链表,所以在只有头结点时要指向自己
        phead->next = phead;
        return phead;
}
void ListDestroy(ListNode* phead) //链表结束的销毁,应该在最后写,这里保持结构,和初始化放在了一起
//友情提示3:这个函数别忘写了
{
        assert(phead);
        ListNode* cur = phead->next;
        while (cur != phead)
        {
               ListNode* next = cur->next;
               free(cur);
               cur = next;
        }
        free(phead); //最后free头结点是因为先free就没有循环结束条件了
}
void printList(ListNode* phead)
{
        assert(phead);
        ListNode* cur = phead->next;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值