文章目录

  • 双向链表简介
  • 结构体构建
  • 创建结点
  • 头插法插入结点
  • 正反向打印链表
  • 删除指定元素
  • 完整代码及用例测试
  • 执行结果
  • 双向链表优缺点分析

双向链表简介

我们知道,单链表(singly linked list)只有一个指向直接后继的指针来表示结点间的逻辑关系,可以方便地查找下一个结点,但是找前驱结点就非常困难。这时,我们就需要用上双向链表(doubly linked list)来解决这个问题。

结构体构建

第一个动作和单链表类似,我们使用结构体来定义出这种数据类型。代码:

typedef struct DLinkNode{int data;struct DLinkNode *prev;struct DLinkNode *next;
}DLNode,*DLNodePtr;
DLNodePtr head;//定义一个全局的头指针

创建结点

为了便于后续操作,我们写一个创建结点的函数。在之后需要创建结点的操作中直接调用此函数,减少代码的重复性。代码:

DLNodePtr GetNewNode(int x){DLNodePtr newNode = (DLNodePtr)malloc(sizeof(DLNodePtr));newNode->data = x;newNode->prev = NULL;newNode->next = NULL;return newNode;
}

头插法插入结点


//头插法插入节点
void InsertAtHead(int x){DLNodePtr temp = GetNewNode(x);//1.链表为空,则将head设置为新节点的地址if(head==NULL){head = temp;return ;} //2.链表不为空,在头部插入head->prev = temp;temp->next = head;head = temp;
}

正反向打印链表

//正向打印
void Print(){DLNodePtr p = head;printf("正向输出:"); while(p!=NULL){printf("%d ",p->data);p=p->next;}printf("\n");
}
//反向打印
void ReversePrint() {DLNodePtr p = head;if(p==NULL){return ;}//到达最后一个结点while(p->next!=NULL){p = p->next;} printf("反向打印:");while(p!=NULL){printf("%d ",p->data);p=p->prev;}printf("\n");
}

删除指定元素

void deleteElement(int n){DLNodePtr p,q,r;p = head;while(p->next!=NULL&&p->next->data!=n){p = p->next;}if(p->next==NULL){printf("不存在此元素"); }q = p->next;r = q->next;p->next = r;if(r!=NULL){r->prev = p;}free(q);
}

完整代码及用例测试

#include<stdio.h>
#include<malloc.h>
typedef struct DLinkNode{int data;struct DLinkNode *prev;struct DLinkNode *next;
}DLNode,*DLNodePtr;
DLNodePtr head;//定义一个全局的头指针
DLNodePtr GetNewNode(int x){DLNodePtr newNode = (DLNodePtr)malloc(sizeof(DLNodePtr));newNode->data = x;newNode->prev = NULL;newNode->next = NULL;return newNode;
}
//头插法插入节点
void InsertAtHead(int x){DLNodePtr temp = GetNewNode(x);//1.链表为空,则将head设置为新节点的地址if(head==NULL){head = temp;return ;} //2.链表不为空,在头部插入head->prev = temp;temp->next = head;head = temp;
}
//正向打印
void Print(){DLNodePtr p = head;printf("正向输出:"); while(p!=NULL){printf("%d ",p->data);p=p->next;}printf("\n");
}
//反向打印
void ReversePrint() {DLNodePtr p = head;if(p==NULL){return ;}//到达最后一个结点while(p->next!=NULL){p = p->next;} printf("反向打印:");while(p!=NULL){printf("%d ",p->data);p=p->prev;}printf("\n");
}
//删除指定元素
void deleteElement(int n){DLNodePtr p,q,r;p = head;while(p->next!=NULL&&p->next->data!=n){p = p->next;}if(p->next==NULL){printf("不存在此元素"); }q = p->next;r = q->next;p->next = r;if(r!=NULL){r->prev = p;}free(q);
}
//主函数
int main (){InsertAtHead(1);InsertAtHead(3);InsertAtHead(5);InsertAtHead(9);InsertAtHead(99);Print();ReversePrint();deleteElement(5);Print();ReversePrint();}

执行结果

双向链表优缺点分析

1.优点:
反转双向链表非常容易。
它可以在执行期间轻松分配或重新分配内存。
与单链表一样,它是最容易实现的数据结构。
这个双向链表的遍历是双向的,这在单链表中是不可能的。
与单链表相比,删除节点很容易。单链表删除需要一个指向要删除的节点和前一个节点的指针,但在双链表中,它只需要要删除的指针。
2.缺点:
与数组和单链表相比,它使用额外的内存(增加了指针)。
由于内存中的元素是随机存储的,因此元素是按顺序访问的,不允许直接访问。

C语言双向链表的实现相关推荐

  1. linux下c语言 双向链表

    C/C++ code /* sgx 2008-10-30 c语言 双向链表 */ #include <stdio.h> #include <assert.h> #include ...

  2. c语言结点初始化,C语言双向链表简单实现及图示(初始化/插入节点/删除节点)...

    -------------------------------------------- 双向链表 - - - - - - - - - - - - - - - - - - - - - - - - - ...

  3. 基于链表的快速排序C语言,双向链表的快速排序算法,编译通过,程序会崩溃,求助一下各位...

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 要求就是在双向链表上实现快速排序:(.cpp文件) #include #include #define TRUE 1 #define FALSE 0 #d ...

  4. C语言 双向链表的增删改查

    主题:双向链表 功能:分别实链表的插入.删除.查找.打印(正序.逆序)操作 提示:如果需要进入下一步操作,输入3个ctrl z即可 //主题:双向链表 //功能:分别实链表的插入.删除.查找操作 // ...

  5. c语言双向链表 快速排序,双向链表的快速排序(swift版本)

    面试经常会被问到的单向链表的快速排序or双向链表的快速排序,现在用swift写了一个双向链表的快速排序,直接上代码 获取源码 //初始化 var linkList = LinkList() linkL ...

  6. c语言双向链表的作用,C语言实现双向链表

    关于双向链表的解释就不多说了,书本上介绍的挺详细的了,只需要记住每个节点有一个指向下一个节点的指针变量和指向前一个节点的指针变量即可.下面直接上代码. DualLinkedList.h的代码如下所示: ...

  7. c语言双向链表实现航班系统,双向链表C语言实现

    #ifndef __STDLIST_H__ #define __STDLIST_H__ typedef struct tagSTDNODE       STDNODE, *LPSTDNODE; typ ...

  8. C语言---双向链表(详解)---数据结构

    双向链表所需要头文件 首先重定义类型名 意义我前几篇讲过几次了,这里就不在赘述了,(顺序表,单链表的开头都有说明) 然后我们需要一个结构体 结构体包含 : 存储数据的 a 指向一个节点的指针 next ...

  9. C语言双向链表的插入与删除

    数据结构复习1.2--双向链表的插入与删除 插入元素 删除元素 代码:和单链表差不多,不会就画一画,就写出来了 //双向链表的插入与删除 #include<stdio.h> #includ ...

  10. c语言双向链表重组写法,一个C语言做的双向链表程序,请高手帮忙改错

    #include #include #include typedef bool Status; typedef int HeadEType; #define OK 1 #define ERROR 0 ...

最新文章

  1. 先为成功的人工作,再与成功的人合作,最后是让成功的人为你工作
  2. int数组,找小于右边所有数,大于左边所有数的数
  3. SOA:A note on RPC
  4. 回溯法解决01背包问题
  5. 如何在 C# 中使用 MSMQ
  6. P2571 [SCOI2010]传送带
  7. linux内核源码代码量,Linux内核源代码数量已经超过1000万行
  8. 用yum装程序 报[Errno 12] Timeout on Trying other mirror.
  9. pytorch中的gather函数_Pytorch中Emdedding函数的解释及使用方法
  10. nvidia-smi每0.1s实时显示显存使用情况,且数字变化处有白底
  11. 克服大数据集群的挑战
  12. Android开发4: Notification编程基础、Broadcast的使用及其静态注册、动态注册方式...
  13. Paypal 在线支付接口应用从零开始,第1节,[建立沙盒测试环境]
  14. 低代码快速对接淘宝订单数据(超详细教程)
  15. Vue.js:从安装到快速创建脚手架项目,解决刚创建完出现的parsing error:No Bable config file detected报错
  16. 【大杂烩】杂7杂8的东西
  17. 一点思考 less interests more interest 选好一个行业慢慢积淀
  18. 【Shell秒懂系列】引用及转义(单引号/双引号/反斜杠/反引号)
  19. 音频信号处理(二)语音信号采集处理与基音周期
  20. 世界第一位计算机程序员传奇一生

热门文章

  1. ubuntu下各种软件下载
  2. python 图标题上移_请问如何在这个Python中将标题一起爬下来啊
  3. 【从Northwind学习数据库】数据更新
  4. C#实现的基于SMTP协议的E-MAIL电子邮件发送客户端软件
  5. 邮件群发怎么发?解密邮件群发软件小技巧
  6. 2021-6-26 激光的工业应用
  7. Python网络爬虫简单入门
  8. fiddler安装安全证书
  9. Android Handler机制 - MessageQueue如何处理消息
  10. 您尝试安装的Adobe Flash Player版本不是最新版本解决办法