首页 > 其他分享 >数据结构:双向链表

数据结构:双向链表

时间:2024-07-25 15:54:14浏览次数:9  
标签:结点 next 链表 prior 双向 数据结构 节点 指针

文章目录


单链表的链式存储结构的结点中只有一个指示直接后继的指针域,由此,从某个结点出发只能顺指针向后寻查其他结点。若要寻查结点的直接前驱,则必须从表头指针出发。换句话说。在单链表中,查找直接后继结点的执行时间为0(1),而查找直接前驱的执行时间为0(n)。为克服单链表这种单向性的缺点,可利用双向链表(Double Linked List)。
顾名思义,在双向链表的结点中有两个指针域,一个指向直接后继,另一个指向直接前驱。

1.双链表的结构定义

typedef struct DuLNode {  
    ElemType data;  
    struct DuLNode *prior;  
    struct DuLNode *next;  
}DuLnode,*DuLinkList;

双向循环链表
和单链的循环表类似,双向链表也可以有循环表

  • 让头结点的前驱指针指向链表的最后一个结点
  • 让最后一个结点的后继指针指向头结点。

2.双链表结构的对称性

p->prior->next = p = p->next->prior

在双向链表中有些操作(如:istLength、GetElem等),因仅涉及一个方向的指针,故它们的算法与线性链表的相同。但在插入、删除时,则需同时修改两个方向上的指针,两者的操作的时间复杂度均为O()。

2.双向链表的插入

  1. s->prior=p->prior;
  2. p->prior->next=s;
  3. s->next=p;
  4. p->prior=s;
void insertBefore(Node** head, Node* p, int value) {
    Node* s = (Node*)malloc(sizeof(Node)); // 创建新节点
    if (!s) return; // 内存分配失败处理

    s->data = value; // 设置新节点的数据
    s->next = p;     // 设置新节点的后继为p
    s->prior = p->prior; // 设置新节点的前驱为p的前驱

    if (p->prior) { // 如果p不是头节点
        p->prior->next = s; // 更新p的前驱的后继指向新节点
    } else { // 如果p是头节点
        *head = s; // 更新头指针
    }

    p->prior = s; // 更新p的前驱指向新节点
}

3.双向链表的删除

  1. p->prior-next=p->next;
  2. p->next->prior=p->prior;
void deleteNode(Node** head, Node* p) {
    if (p == NULL) return; // 检查p是否为NULL

    // 更新前驱节点的后继指针
    if (p->prior != NULL) {
        p->prior->next = p->next;
    } else {
        *head = p->next; // 如果p是头节点,更新头指针
    }

    // 更新后继节点的前驱指针
    if (p->next != NULL) {
        p->next->prior = p->prior;
    }

    // 释放被删除节点的内存
    free(p);
}

4.顺序表和链表的比较

链式存储结构的优点

  • 结点空间可以动态申请和释放;
  • 数据元素的逻辑次序靠结点的指针来指示,插入和删除时不需要移动数据元素。
    链式存储结构的缺点
  • 存储密度小,每个结点的指针域需额外占用存储空间。当每个结点的数据域所占字节不多时,指针域所占存储空间的比重显得很大。
  • 链式存储结构是非随机存取结构。对任一结点的操作都要从头指针依指针链查找到该结点,这增加了算法的杂度。
    存储结构
比较项目顺序表链表
预先分配,会导致空间闲置或溢出现象×
动态分配,不会出现存储空间闲置或溢出现象×
不用为表示结点间的逻辑关系而增加额外的存储开销,存储密度等于1×
需要借助指针来体现元素间的逻辑关系,存储密度小于1×
随机存取,按位置访问元素的时间复杂度为O(1)×
顺序存取,按位置访问元素时间复杂度为O(n)×
平均移动约表中一半元素,时间复杂度为O(n),时间复杂度为O(1)×
不需移动元素,确定插入、删除位置后,时间复杂度为O(1)×

适用情况

  • 顺序表:
    1. 表长变化不大,且能事先确定变化的范围
    2. 很少进行插入或删除操作,经常按元素位置序号访问数据元素
  • 链表:
    1. 长度变化较大
    2. 频繁进行插入或删除操作

标签:结点,next,链表,prior,双向,数据结构,节点,指针
From: https://blog.csdn.net/2303_82176667/article/details/140665780

相关文章

  • 数据结构:线性表的应用
    文章目录1.线性表的合并2.有序表的合并1.线性表的合并问题描述:假设利用两个线性表La和Lb分别表示两个集合A和B,现要求一个新的集合A=AUBLa=(7,5,3,11)Lb=(2,6,3)->La=(7,5,3,11,2,6)算法步骤依次取出Lb中的每个元素,执行以下操作:在La中查找该元素如果找不到,则将......
  • 数据结构专题讲解
    数据结构专题讲解总结:1.绝大多数数据结构体题目本身都比较明显的有共通性,往往可以向树上转化2.对于二维的问题,我们往往可以将一维上建立树然后暴力处理另外一维来解决问题例题一P7476「C.E.L.U-02」苦涩题目简述:在YQH的梦中,他看到自己过去的记忆正在不断浮现在......
  • 【数据结构】二叉树
    二叉树结构描述:#include<iostream>#include<queue>usingnamespacestd;typedefintDataType;classNode{private:DataTypedata;Node*left;Node*right;friendclassBinaryTree;};typedefclassBinaryTree{private:N......
  • Redisson常用的数据结构及应用场景
    Redisson提供了一系列高级数据结构,这些数据结构封装了Redis的原生数据类型,提供了JavaAPI的便利性和分布式特性。以下是Redisson中一些常用的数据结构,场景还在不断完善中:RBucket:这是一个简单的键值对存储,相当于Redis中的String类型。你可以使用它来存储和检索......
  • 数据结构与算法从淬体到元婴day05之栈
    栈数据结构栈(Stack)是一种遵循后进先出(LIFO,LastInFirstOut)原则的有序集合。栈只能在一端(称为栈顶,Top)进行插入(push)和删除(pop)操作,另一端(称为栈底,Bottom)是固定的。这种特性使得栈在解决具有后进先出特性的问题时非常有用,比如函数调用、括号匹配、撤销操作等。栈的基本操作p......
  • 静态链表(C++)
    一,静态链表简介静态链表使用连续的内存,每个结点记录一个数据和指向下一结点的指针。可以高效的进行插入删除操作。是用整形游标代替结点指针的“单链表”。结构结点类型structnode{size_tcurser;intvalue;};静态链表类型链表中储存结点构成的数组str......
  • Java————链表
    目录前言:1.链表的概念2.链表的结构2.1带头的和不带头的2.2单向和双向2.3循环和非循环3.链表的实现3.1双向不带头不循环链表:3.2单向不带头不循环链表:4.LinkedList的使用4.1什么是LinkedList4.2LinkedList的使用5.LinkedList的遍历5.1foreach遍历5.2使用迭代器遍......
  • vue 2 实现自定义组件一到多个v-model双向数据绑定的方法(转)
    原文链接:https://blog.csdn.net/Dobility/article/details/110147985前言有时候我们需要对一个组件绑定自定义v-model,以更方便地实现双向数据,例如自定义表单输入控件。甚至有时候,我们想要实现绑定多个“v-model”,也就是多个“双向绑定”,例如带表单输入的模块框,想同时控制模态......
  • 数据结构(3)(顺序栈)
     栈:      栈是限定仅在栈顶进行插入和删除操作的线性表,在操作的时候,只允许栈顶改变不允许栈底改变,具有后进先出的特征。顺序栈:      顺序栈是一种使用数组实现的栈,也称为数组栈。其基本思路是通过数组来存储栈中的元素,并通过栈顶指针指示栈顶元素在数组中的位......
  • 双向链表<数据结构 C版>
    目录关于链表的分类 双向链表结构体初始化尾插头插打印判断是否为空尾删头删查找指定位置之后的插入指定位置的删除销毁关于链表的分类根据链表的三大特性,单向or双向、带头or不带头、循环or不循环,可将链表分为2*2*2,8种链表,前面我们已经实现了单链表,即:不带头......