根据带头/不带头、单向/双向、循环/不循环链表可分为8种


双向链表分为前驱节点和后继节点,不仅能找到当前节点的下一个节点还可以找到上一个节点,使用起来也是很方便的。

带头链中的头节点,不存储任何有效数据,只用来站岗放哨,我们也称之为"哨兵位" 在之前的单链表学习中,我们有时候也会把第一个节点表述为头节点,其实这个称呼是不严谨的只是为了方便理解。

循环链表的尾节点->next指向头节点
今天我们就来学习其中之一的带头双向循环链表

双向链表中由一个一个的节点组成,这里的节点有三个组成部分,定义我们放在.h文件中
List.h:
//定义双向链表结构
typedef int LTDataType;
typedef struct ListNode
{
LTDataType data;
struct ListNode* prev;//指向上一个节点的指针
struct ListNode* next;//指向下一个节点的指针
}LTNode;在双向链表中哨兵位的头节点是需要初始化一下的,数据随便给个不用的,然后前驱指针和后继指针都指向自己就可以了
void LTInit(LTNode** pphead)
{
*pphead = (LTNode*)malloc(sizeof(LTNode));
if (*pphead==NULL)
{
perror(malloc);
exit(1);
}
(*pphead)->data = -1;//随便给个不用的就行
(*pphead)->next = (*pphead)->prev = *pphead;
*pphead = LTBuyNode(-1);
}#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int LTDataType;
typedef struct ListNode
{
LTDataType data;
//前驱指针,指向前一个指针
struct ListNode* prev;
//后继指针,指向后一个指针
struct ListNode* next;
}ListNode;
//初始化头节点
void LTInit(ListNode** pphead);#include"List.h"
//头节点初始化
void LTInit(ListNode** pphead)
{
ListNode* ph = (ListNode*)malloc(sizeof(ListNode));
if (ph==NULL)
{
perror("malloc fail!");
exit(1);
}
*pphead = ph;
(*pphead)->data = -1;//随便给个不用的就行
(*pphead)->prev = *pphead;
(*pphead)->next = *pphead;
}#include"List.h"
void test1()
{
ListNode* plist = NULL;
LTInit(&plist);
}
int main()
{
test1();
return 0;
}往期回顾:
总结:这篇博客的内容较少,主要给大家区分了链表的总类以及各个特性,完成了双线链表的初始化,下篇博客将带着大家完成剩余所有接口,希望大家坚持下去,如果文章对你有帮助的话,欢迎评论,点赞,收藏加关注,感谢大家的支持。 🌹🌹🌹