双向,带头节点,带环链表的基本操作

本文详细介绍了带头节点和环的双向链表的各种基本操作,包括初始化、尾插、尾删、头插、头删、指定位置插入与删除、查找、按值删除节点以及链表的销毁和长度统计等操作的实现思路和代码示例。
摘要由CSDN通过智能技术生成

        前面已经介绍过了不带头节点,不带环的双向链表,以下将介绍带头节点,带环的双向链表的基本操作。

        不带头结点时,用一个头指针代表整个链表。带头节点,则用头结点来表示整个链表。此时,头结点的数据域是没有意义的,对其任意赋值即可。如下图:


        当链表是单向时,只有一个next指针指向下一个节点。而双向时,除有next指向下一个节点外,还有一个prev指针指向前一个结点。

        当链表不带环时,链表的最后一个元素的next域为空,而带环时,链表的最后一个结点的next域要指向头结点,而头结点的prev域要指向链表的最后一个节点。这样,整个链表就呈一个环状。

       通过上述分析,便可知道,当双向链表为空时,头结点的next域和prev域均指向头结点。

1. 链表的结点结构

        上述分析已经知道,双向链表的一个节点包括三部分:数据域,next域,prev域,所以,结点结构定义如下:

typedef char DlinklistType;//将节点的数据域类型统一表示                                                                               

//定义双向链表的节点结构
typedef struct DlinkNode
{
    DlinklistType data;//数据域
    struct DlinkNode* next;//指向下一个节点
    struct DlinkNode* prev;//指向上一个节点
}DlinkNode;

2. 双向链表的初始化

        因为该链表是带头节点的,所以初始化时,要创建一个头结点来表示整个链表,此时,还没有真正的节点,所以链表为空,所以将头结点的next指针和prev指针均指向自己,数据任意赋值。

        因为初始化时,要使头指针指向头结点,即要改变头指针的指向,所以,在函数传参时,传的是头指针的地址,即二级指针(在测试函数中定义的是头指针,即DlinkNode*类型的变量)。

代码如下:

//创建结点
DlinkNode* CreateNode(DlinklistType value)
{
    DlinkNode* new_node = (DlinkNode*)malloc(sizeof(DlinkNode));
    new_node->data = value;
    new_node->next = new_node;//初始时,使节点的两个指针域均指向自身                                                                  
    new_node->prev = new_node;
    return new_node;
}

//初始化双向链表
void InitDlinklist(DlinkNode** phead)
{
    if(phead == NULL)
    {   
        //非法输入
        return;
    }   
    //申请头结点,使头指针指向新节点
    *phead = CreateNode(0);
    return;
}

         因为再对头指针初始化后,头指针始终指向头结点,对链表进行以下操作(不包括销毁链表)时,改变的是头结点的相关指针域,而未改变头指针的指向,所以,在函数传参时传的均是头指针,即一级指针。

3. 对双向链表进行尾插

        在尾插时,首先要找到尾节点,因为链表是带环的双向链表,所以,可以通过头结点的prev指针找到尾节点。然后在尾节点后面创建一个新节点进行插入。

         在插入时,需要改变四个指针的指向,两两一组,分别为:

(1)原尾节点的next域要指向新节点,新节点的prev要指向原尾节点;

(2)新节点的next域要指向头结点,头结点的prev要指向新节点。

代码如下:

//对双向链表进行尾插
//head为双向链表的头指针,value为要插入的值
void DlinklistPushBack(DlinkNode* head,Dlinklis
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值