美文网首页
双向链表

双向链表

作者: lxr_ | 来源:发表于2022-03-05 21:48 被阅读0次

双向链表是在单链表的每个结点中,在设置一个指向其前驱结点的指针域。如下图所示

双向链表
双向链表也可以是循环表,成为双向循环链表,如下图所示
image.png
可以看出其具有对称性,即p->next->prior=p=p->prior->next
1.双向链表是单链表扩展出来的结构,所以它的很多操作与单链表相同的(用其中一个指针域next或prior即可),如求长度的ListLength,查找元素的GetElem,获得元素位置的LocateELem等。
2.同理,双向循环链表也与单循环链表有很多操作相同
重点看一下双向循环链表的插入和删除:

DuLinkList.h

#pragma once

#pragma once

// 函数结果状态代码
#define OK      1
#define ERROR   0
#define INFEASIBLE  -1
#define OVERFLOW    -2

//Status 是函数的类型,其值是函数结果状态代码
typedef int Status;

//数据类型
typedef int ElemType;

typedef struct DuLNode
{
    ElemType data;
    DuLNode* next, * prior;

}DuLNode, * DuLinkList;

//双向循环链表初始化
Status InitList_DuL(DuLinkList& L);

//返回双向循环链表中第i个结点
DuLNode* LocateElemP_DuL(DuLinkList L, int i);

//在带头结点的双向循环链表L中第i个位置之前插入元素e
Status ListInsert_DuL(DuLinkList& L, int i, ElemType e);

//删除带头结点的双向循环链表L的第i个元素,并用e返回
Status ListDelete_DuL(DuLinkList& L, int i, ElemType& e);

//遍历双向循环链表
void ListTraverse_DuL(DuLinkList L);

DuLinkList.cpp

#include "DuLinkList.h"
#include <iostream>
using namespace std;

//双向循环链表初始化
Status InitList_DuL(DuLinkList& L)
{
    L = new DuLNode;

    L->next = L;                    //头结点的后继为头结点
    L->prior = L;                   //头结点的前驱为头结点
    cout << "初始化成功" << endl;

    return OK;
}

//返回链表中第i个结点
DuLNode* LocateElemP_DuL(DuLinkList L, int i)
{
    DuLNode* p = L->next;           //第一个结点
    int j = 1;
    while (p != L && j < i)         //到最后一个节点或这到第i个结点
    {
        p = p->next;
        j++;
    }
    if (j != i)                     //不相等表示插入位置不合理
    {
        return NULL;
    }
    return p;
}

插入(在第i个结点之前插入新结点):

插入
步骤:
1.先找到第i个结点p
2.新结点s的前驱为结点p的前驱
3.结点p的前驱的后继为新结点s
4.新结点s的后继为结点p
5.结点p的前驱为新结点s
当然,也可找到第i-1个结点q,利用此结点进行插入
//在带头结点的双向循环链表L中第i个位置之前插入元素e
Status ListInsert_DuL(DuLinkList& L, int i, ElemType e)
{
    DuLNode* p = LocateElemP_DuL(L, i);     //返回链表中第i个元素结点,即为要插入结点的后继结点
    if (!p)
    {
        cout << "位置不合理" << endl;
        return ERROR;
    }
    DuLNode* s = new DuLNode;               //建立新结点
    s->data = e;
    s->prior = p->prior;                    //新结点前驱为原来p结点的前驱
    p->prior->next = s;                     //原来p结点前驱的后继本来还是p结点,现在改为新结点
    s->next = p;                            //新结点的后继为p结点
    p->prior = s;                           //p结点的前驱为新结点

    cout << "插入成功" << endl;
    return OK;
}

删除(删除第i个结点p):

删除
步骤:
1.先找到第i个结点p
2.结点p的前驱的后继为p的后继
3.结点p的后继的前驱为p的前驱
//删除带头结点的双向循环链表L的第i个元素,并用e返回
Status ListDelete_DuL(DuLinkList& L, int i, ElemType& e)
{
    DuLNode* p = LocateElemP_DuL(L, i);

    if (!p || p == L)
    {
        cout << "位置不合理" << endl;
        return ERROR;
    }
    p->prior->next = p->next;
    p->next->prior = p->prior;

    e = p->data;
    cout << "删除" << e << "成功" << endl;
    delete p;

    return OK;
}

//遍历双向循环链表
void ListTraverse_DuL(DuLinkList L)
{
    DuLNode* p = L->next;
    while (p != L)
    {
        cout << p->data << " ";
        p = p->next;
    }
    cout << endl;
}

main.cpp

测试:

#include <iostream>
#include "DuLinkList.h"
using namespace std;

int main(int argc, char** argv)
{
    DuLinkList L;
    InitList_DuL(L);            //初始化双向循环链表

    ListInsert_DuL(L, 1, 1);    //双向循环链表第一个位置插入1
    ListInsert_DuL(L, 2, 2);
    ListInsert_DuL(L, 3, 3);

    ListInsert_DuL(L, 5, 5);    //测试插入是否成功

    ListTraverse_DuL(L);        //遍历

    ElemType e;
    ListDelete_DuL(L, 1, e);    //删除第一个元素所在节点
    ListDelete_DuL(L, 2, e);

    ListDelete_DuL(L, 2, e);    //测试删除是否成功

    ListTraverse_DuL(L);

    return 0;
}

相关文章

  • 双向链表&双向循环链表

    链表分为:单链表、单向循环链表、双向链表、双向循环链表本节主要说明:双向链表、双向循环链表 定义结点 一、双向链表...

  • 线性表-双向链表与双向循环链表

    双向链表 双向链表示意图如下: 数据结构定义 创建双向链表 双向链表插入元素 双向链表删除元素 双向链表打印元素 ...

  • day03-双向链表

    双向链表: 单向链表只能单向查找,双向链表可以双向查找。 啥是双向链表? 双向链表可以双向查数据,所以就不存在单向...

  • 线性表--链式存储结构--双向链表

    双向链表 一、双向链表结构 双向链表结点结构 既然单链表可以有循环链表,那么双向链表当然也可以有。 由于这是双向链...

  • 双向链表和双向循环链表

    双向链表 线性表-双向链表的结点结构: 带头结点的双向链表: 1.双向链表初始化 2.遍历双向链表 2.双向链表插...

  • 数据结构与算法之双向链表(3.3)

    目录 双向链表简介双向链表重要方法讲解实战检测双向链表,单向链表性能对比 一 双向链表简介 双向链表-只有一个元素...

  • 双向链表&双向循环链表

    一、双向链表 带有前驱结点、后区节点 双向链表的创建 双向链表插入-逻辑 双向链表删除 删除双向链表指定的元素 二...

  • 9.双向链表DoubleLinkList

    目录:1.双向链表的定义2.双向链表的图解3.双向链表定义操作4.双向链表的实现 1.双向链表的定义 2.双向链表...

  • 双向链表于双向循环链表的终结

    一、双向链表: 1.双向链表的创建:如图 2.双向链表的输出: 3.双向链表的插入: 4.双向链表的删除: 二、双...

  • 双向链表

    双向链表的结构 既然单链表有循环链表,双向链表当然也有双向循环链表,如下图: 问: 双向链表中某个节点p的后继节点...

网友评论

      本文标题:双向链表

      本文链接:https://www.haomeiwen.com/subject/oowbrrtx.html