数据结构:双向链表

本文涉及的产品
可视分析地图(DataV-Atlas),3 个项目,100M 存储空间
简介: 原创:转载请注明 在前面介绍了单项链表, http://blog.itpub.net/7728585/viewspace-2125007/ 在实际的应用中双向链表应用也是非常多的,因为我本生是一名DBA,我知道的在数据库中双向链表应用非常广泛,在双向链表中 我们多了一个*prior 指向前一个节点,那么这样如果我们已知一个节点的指针要求得上一个节点的指针就变得非常简单了, 时间复杂度由O(n)下降到一个常数O(1),关于这个实现函数我觉得没必要写了太简单了。
原创:转载请注明
在前面介绍了单项链表,
http://blog.itpub.net/7728585/viewspace-2125007/
在实际的应用中双向链表应用也是非常多的,因为我本生是一名DBA,我知道的在数据库中双向链表应用非常广泛,在双向链表中
我们多了一个*prior 指向前一个节点,那么这样如果我们已知一个节点的指针要求得上一个节点的指针就变得非常简单了,
时间复杂度由O(n)下降到一个常数O(1),关于这个实现函数我觉得没必要写了太简单了。我准备实现如下一些函数及功能
bool makenode(int datavalue,DULNODEP* p); //makenode next and prior is NULL
void freenode(DULNODEP p); //freenode
bool initlist(LISTHEADP* p); //initlist with no node head last current pointor is NULL
void destroylist(LISTHEADP p); //destroy a list,every list thing is not live
void clearlist(LISTHEADP p);//clear a list,but head is live and head last current pointor is NULL length=0
void insfirst(LISTHEADP h,DULNODEP s);//insfirst  insert one node at first postion length=0
void delfirst(LISTHEADP h); //delete first node current_point to next node
void inslast(LISTHEADP h,DULNODEP s); //inslast  insert one node at last postion
void dellast(LISTHEADP h) ; //delete last node current_point to prior node
void addnode(DULNODEP inode,int postion,LISTHEADP h);//insert one node after postion 
void removenode(int postion,LISTHEADP h) ;//delete node at give postion 
void replacenode(int postion,LISTHEADP h,DULNODEP inode);//replace one node
void viewchain(LISTHEADP h);//show info for chain
void viewheadinfo(LISTHEADP h);//only show head info

我将上一节演示的头结点增加了last指针指向最后一个节点,同时增加了current指针指向操作的指针。结构体如下:
typedef struct listhead
{
        DULNODEP head;
        DULNODEP last;
        DULNODEP current;
        int length;
} LISTHEAD,*LISTHEADP;

这样我们在实现 inslast dellast的时候变得非常简单了,而 delfirstinsfirst本来就是通过head指针实现的,如果大家对栈和队列的实现有了解,着4个函数可以用来实现他们,这个我会在随后进行说明,这里只考虑双线链表,我基本上用注释解释了全部了功能下面一张图大概看看双向链表的结构,假设Noden为插入的节点就是如下,删除也差不多没画




下面以代码的方式给出实现:

点击(此处)折叠或打开

  1. 头文件:
  2. //error(1):delfirst() error list have no
  3. //error(2):getelemp() postion large than lenth or poastion = 0
  4. //error(3):viewchain() list no data

  5. #ifndef _liststr_
  6. #define _liststr_
  7. #define bool int
  8. #define true 1
  9. #define false 0
  10. typedef struct dulnode //node type
  11. {
  12.         int data; //example
  13.         struct dulnode *prior;
  14.         struct dulnode *next;
  15. } DULNODE,*DULNODEP;

  16. typedef struct listhead
  17. {
  18.         DULNODEP head;
  19.         DULNODEP last;
  20.         DULNODEP current;
  21.         int length;
  22. } LISTHEAD,*LISTHEADP;

  23. #define SIZENODE sizeof(DULNODE)
  24. #define SIZELISTHEAD sizeof(LISTHEAD)

  25. bool makenode(int datavalue,DULNODEP* p); //makenode next and prior is NULL
  26. void freenode(DULNODEP p); //freenode
  27. bool initlist(LISTHEADP* p); //initlist with no node head last current pointor is NULL
  28. void destroylist(LISTHEADP p); //destroy a list,every list thing is not live
  29. void clearlist(LISTHEADP p);//clear a list,but head is live and head last current pointor is NULL length=0
  30. void insfirst(LISTHEADP h,DULNODEP s);//insfirst insert one node at first postion length=0
  31. void delfirst(LISTHEADP h); //delete first node current_point to next node
  32. void inslast(LISTHEADP h,DULNODEP s); //inslast insert one node at last postion
  33. void dellast(LISTHEADP h) ; //delete last node current_point to prior node
  34. void addnode(DULNODEP inode,int postion,LISTHEADP h);//insert one elem after postion
  35. void removenode(int postion,LISTHEADP h) ;//delete elem at give postion
  36. void replacenode(int postion,LISTHEADP h,DULNODEP inode);//replace one node
  37. void viewchain(LISTHEADP h);//show info for chain
  38. void viewheadinfo(LISTHEADP h);//only show head info

  39. #endif

点击(此处)折叠或打开

  1. 功能函数文件:
  2. #include<stdlib.h>
  3. #include<stdio.h>
  4. #include <string.h>
  5. #include"dulnode.h"

  6. static DULNODEP getelemp(const LISTHEADP h,int postion) ;

  7. //makenode
  8. bool makenode(int datavalue,DULNODEP* p)
  9. {
  10.         *p = (DULNODEP) malloc (SIZENODE);
  11.         if(!(*p))
  12.         {
  13.                 return false;
  14.         }
  15.         else
  16.         {
  17.                 memset(*p,0,SIZENODE);
  18.                 (*p)->data = datavalue;
  19.                 (*p)->next = NULL;
  20.                 (*p)->prior = NULL;
  21.                 return true;
  22.         }
  23. }

  24. //freenode

  25. void freenode(DULNODEP p)
  26. {
  27.         free(p);
  28. }

  29. //initlist with no node

  30. bool initlist(LISTHEADP* p)
  31. {
  32.         *p = (LISTHEADP)malloc(SIZELISTHEAD);
  33.         if(!*p)
  34.         {
  35.                 return false;
  36.         }
  37.         else
  38.         {
  39.                 memset(*p,0,SIZELISTHEAD);
  40.                 (*p)->head = NULL;
  41.                 (*p)->last = NULL;
  42.                 (*p)->current = NULL;
  43.                 (*p)->length = 0;
  44.                 return true;
  45.         }
  46. }
  47. //destroy a list,every list thing is not live
  48. void destroylist(LISTHEADP p)
  49. {
  50.         DULNODEP npc;
  51.         DULNODEP npn;
  52.         int i = 0;

  53.         if(npc = p->head)
  54.         {
  55.                 npn = p->head->next;
  56.                 for(i=0;i<p->length;i++)
  57.                 {
  58.                         free(npc);
  59.                         npc = npn;
  60.                         if(npn) //last one is null null->next will
  61.                         {
  62.                                 npn = npn->next;
  63.                         }
  64.                 }
  65.         }

  66.         free(p);
  67. }
  68. //clear a list,but head is live
  69. void clearlist(LISTHEADP p)
  70. {
  71.         DULNODEP npc;
  72.         DULNODEP npn;
  73.         int i = 0;

  74.         if(npc = p->head)
  75.         {
  76.                 npn = p->head->next;
  77.                 for(i=0;i<p->length;i++)
  78.                 {
  79.                         free(npc);
  80.                         npc = npn;
  81.                         if(npn) //last one is null null->next will
  82.                         {
  83.                                 npn = npn->next;
  84.                         }
  85.                 }
  86.         }
  87.         p->head = NULL;
  88.         p->last = NULL;
  89.         p->current = NULL;
  90.         p->length = 0;
  91. }

  92. //insfirst insert one node at first postion

  93. void insfirst(LISTHEADP h,DULNODEP s)
  94. {
  95.         if(!(h->head)) //list is empty or not
  96.         {
  97.                 h->head = s;
  98.                 h->last = s;
  99.                 h->current = s;
  100.                 h->length++;
  101.         }
  102.         else
  103.         {
  104.                 h->head->prior = s;
  105.                 s ->next = h->head;
  106.                 h->head = s;
  107.                 h->current = s;
  108.                 h->length++;

  109.         }

  110. }


  111. //delfirst
  112. void delfirst(LISTHEADP h) //delete first node current_point to next node
  113. {
  114.         DULNODEP p;
  115.         if(!(h->head))
  116.         {
  117.                 printf("error(1):delfirst() error list have no node!\n");
  118.                 exit(1);
  119.         }
  120.         else if(!(h->head->next)) //only one node
  121.         {
  122.                 free(h->head);
  123.                 h->head = NULL;
  124.                 h->current = NULL;
  125.                 h->last = NULL;
  126.                 h->length--;
  127.         }
  128.         else
  129.         {
  130.                 p = h->head ;
  131.                 h->head->next->prior = NULL;
  132.                 h->head = h->head->next;
  133.                 h->current = h->head;
  134.                 h->length--;
  135.                 free(p);
  136.         }
  137. }


  138. //inslast insert one node at last postion

  139. void inslast(LISTHEADP h,DULNODEP s)
  140. {
  141.         if(!(h->head)) //list is empty or not
  142.         {
  143.                 h->head = s;
  144.                 h->last = s;
  145.                 h->current = s;
  146.                 h->length++;
  147.         }
  148.         else
  149.         {
  150.                 h->last->next = s;
  151.                 s->prior = h->last;
  152.                 h->last = s;
  153.                 h->current = s;
  154.                 h->length++;
  155.         }
  156. }



  157. //dellast

  158. void dellast(LISTHEADP h) //delete last node current_point to prior node
  159. {
  160.         DULNODEP p;
  161.         if(!(h->head))
  162.         {
  163.                 printf("error(1):delfirst() error list have no node!\n");
  164.                 exit(1);
  165.         }
  166.         else if(!(h->head->next)) //only one node
  167.         {
  168.                 free(h->head);
  169.                 h->head = NULL;
  170.                 h->current = NULL;
  171.                 h->last = NULL;
  172.                 h->length--;
  173.         }
  174.         else
  175.         {
  176.                 p = h->last ;
  177.                 h->last->prior->next = NULL;
  178.                 h->last = p->prior;
  179.                 h->current = p->prior;
  180.                 h->length--;
  181.                 free(p);
  182.         }
  183. }


  184. static DULNODEP getelemp(const LISTHEADP h,int postion)
  185. {
  186.         int i=0;
  187.         DULNODEP p;
  188.         if(postion > h->length || postion ==0 )
  189.         {
  190.                 printf("error(2):getelemp() postion large than lenth or poastion = 0\n");
  191.                 exit(2);
  192.         }
  193.         p = h->head;

  194.         while(i<postion-1)
  195.         {
  196.                 i++;
  197.                 p = p->next;
  198.         }
  199.         return p;
  200. }

  201. //addnode add one node after give postion
  202. void addnode(DULNODEP inode,int postion,LISTHEADP h) //insert one elem after postion
  203. {
  204.         DULNODEP p;
  205.         p = getelemp(h,postion);
  206.         if(!p->next) //last node?
  207.         {
  208.                 p->next = inode;
  209.                 inode->prior = p;
  210.                 inode->next = NULL;
  211.                 h->last = inode;
  212.                 h->current = inode;
  213.         }
  214.         else
  215.         {
  216.                 inode->prior = p;
  217.                 inode->next = p->next;
  218.                 p->next->prior = inode;
  219.                 p->next = inode;
  220.                 h->current = inode;
  221.         }
  222.         h->length++;
  223. }

  224. //removenode remove one node at postion and current point to next postion

  225. void removenode(int postion,LISTHEADP h) //delete elem at give postion
  226. {
  227.         DULNODEP p;
  228.         p = getelemp(h,postion);

  229.         if(postion == 1 && !(p->next)) //node one and only one node
  230.         {
  231.                 h->head = NULL;
  232.                 h->current = NULL;
  233.                 h->last = NULL;
  234.                 free(p);
  235.         }
  236.         else if(postion == 1) //node one?
  237.         {
  238.                 p->next->prior = NULL;
  239.                 h->head = p->next;
  240.                 h->current = h->head;
  241.                 free(p);
  242.         }
  243.         else if(!(p->next)) //last node?
  244.         {
  245.                 h->current = NULL;
  246.                 h->last = p->prior;
  247.                 p->prior->next = NULL;
  248.                 free(p);
  249.         }
  250.         else
  251.         {
  252.                 h->current = p->next;
  253.                 p->next->prior = p->prior;
  254.                 p->prior->next = p->next;
  255.                 free(p);
  256.         }
  257.         h->length--;
  258. }


  259. //replacenode replace one node


  260. void replacenode(int postion,LISTHEADP h,DULNODEP inode)
  261. {
  262.         DULNODEP p;
  263.         p = getelemp(h,postion);

  264.         if(postion == 1 && !(p->next)) //node one and only one node
  265.         {
  266.                 h->head = inode;
  267.                 h->current = inode;
  268.                 h->last = inode;
  269.                 free(p);
  270.         }
  271.         else if(postion == 1)
  272.         {
  273.                 inode->next = h->head->next;
  274.                 h->head->next->prior = inode;
  275.                 h->head = inode;
  276.                 h->current = inode;
  277.                 free(p);
  278.         }
  279.         else if(!(p->next))
  280.         {
  281.                 inode->prior = p->prior;
  282.                 p->prior->next = inode;
  283.                 h->current = inode;
  284.                 h->last = inode;
  285.                 free(p);
  286.         }
  287.         else
  288.         {
  289.                 inode->prior = p->prior;
  290.                 inode->next = p->next;
  291.                 p->prior->next = inode;
  292.                 p->next->prior = inode;
  293.                 h->current = inode;
  294.                 free(p);
  295.         }
  296. }


  297. void viewchain(LISTHEADP h)
  298. {
  299.         int i=1;
  300.         DULNODEP p;
  301.         p = h->head;
  302.         if(!p)
  303.         {
  304.                 printf("error(3):viewchain() list no data\n");
  305.                 exit(3);
  306.         }

  307.         printf("Max chain length is:%d,current_pointor is:%p,head_pointor is:%p,last_pointor is:%p\n",h->length,h->current,h->head,h->last);
  308.         do
  309.         {
  310.                 printf("node:%d values is: %d\n",i,p->data);
  311.                 i++;

  312.         }while(p=p->next);
  313. }

  314. void viewheadinfo(LISTHEADP h)
  315. {

  316.         printf("Max chain length is:%d,current_pointor is:%p,head_pointor is:%p,last_pointor is:%p\n",h->length,h->current,h->head,h->last);
  317. }

点击(此处)折叠或打开

  1. 主函数文件:
  2. #include<stdlib.h>
  3. #include<stdio.h>
  4. #include"dulnode.h"



  5. int main(void)
  6. {
  7.         LISTHEADP headp=NULL;
  8.         DULNODEP p1=NULL;
  9.         DULNODEP p2=NULL;
  10.         DULNODEP p3=NULL;
  11.         DULNODEP p4=NULL;

  12.         DULNODEP p5=NULL;
  13.         DULNODEP p6=NULL;

  14.         if(!(initlist(&headp)))
  15.                 {
  16.                         printf("initlist error\n");
  17.                 }
  18.         if(!(makenode(1,&p1)))
  19.                 {
  20.                         printf("makenode error\n");
  21.                 }
  22.         if(!(makenode(2,&p2)))
  23.         {
  24.                 printf("makenode error\n");
  25.         }
  26.         if(!(makenode(3,&p3)))
  27.         {
  28.                  printf("makenode error\n");
  29.         }
  30.         if(!(makenode(4,&p4)))
  31.         {
  32.                 printf("makenode error\n");
  33.         }

  34.         if(!(makenode(5,&p5)))
  35.         {
  36.                 printf("makenode error\n");
  37.         }

  38.         if(!(makenode(6,&p6)))
  39.         {
  40.                 printf("makenode error\n");
  41.         }

  42.         insfirst(headp,p1);
  43.         insfirst(headp,p2);
  44.         insfirst(headp,p3);
  45.         inslast(headp,p4);

  46.         viewchain(headp);

  47.         delfirst(headp);
  48.         viewchain(headp);
  49.         dellast(headp);
  50.         viewchain(headp);

  51.         addnode(p5,1,headp);
  52.         viewchain(headp);
  53.         replacenode(2,headp,p6);
  54.         viewchain(headp);
  55.         removenode(2,headp);
  56.         viewchain(headp);
  57.         clearlist(headp);
  58.         destroylist(headp);
  59.         return 0;

  60. }

下面我们给出结果来分析:
Max chain length is:4,current_pointor is:0xd210a0,head_pointor is:0xd21080,last_pointor is:0xd210a0
node:1 values is: 3
node:2 values is: 2
node:3 values is: 1
node:4 values is: 4
Max chain length is:3,current_pointor is:0xd21060,head_pointor is:0xd21060,last_pointor is:0xd210a0
node:1 values is: 2
node:2 values is: 1
node:3 values is: 4
Max chain length is:2,current_pointor is:0xd21040,head_pointor is:0xd21060,last_pointor is:0xd21040
node:1 values is: 2
node:2 values is: 1
Max chain length is:3,current_pointor is:0xd210c0,head_pointor is:0xd21060,last_pointor is:0xd21040
node:1 values is: 2
node:2 values is: 5
node:3 values is: 1
Max chain length is:3,current_pointor is:0xd210e0,head_pointor is:0xd21060,last_pointor is:0xd21040
node:1 values is: 2
node:2 values is: 6
node:3 values is: 1
Max chain length is:2,current_pointor is:0xd21040,head_pointor is:0xd21060,last_pointor is:0xd21040
node:1 values is: 2
node:2 values is: 1

首先构造了4个节点前面3个用insfrist 这样就是 3 2 1的排列最后一个用inslast 那么就是 3 2 1 4 可以看到确实如此

然后使用delfrist 删除第一个就是3 那么剩下 2 1 4 然后使用dellast 那么删除 4 就是 2 1 可以看到确实如此

然后我们使用addnode 在位置1后面加入元素 5 那么就是 2 5 1 确实如此
然后我们使用replacenode 将位置2的元素 data 5的数据换位 data为 6的数据变为 2 6 1
最后调用removenode将位置2的元素删除变为了 2 1 最后是清空和销毁链表。
整个过程预期和测试结果一致

相关实践学习
DataV Board用户界面概览
本实验带领用户熟悉DataV Board这款可视化产品的用户界面
阿里云实时数仓实战 - 项目介绍及架构设计
课程简介 1)学习搭建一个数据仓库的过程,理解数据在整个数仓架构的从采集、存储、计算、输出、展示的整个业务流程。 2)整个数仓体系完全搭建在阿里云架构上,理解并学会运用各个服务组件,了解各个组件之间如何配合联动。 3&nbsp;)前置知识要求 &nbsp; 课程大纲 第一章&nbsp;了解数据仓库概念 初步了解数据仓库是干什么的 第二章&nbsp;按照企业开发的标准去搭建一个数据仓库 数据仓库的需求是什么 架构 怎么选型怎么购买服务器 第三章&nbsp;数据生成模块 用户形成数据的一个准备 按照企业的标准,准备了十一张用户行为表 方便使用 第四章&nbsp;采集模块的搭建 购买阿里云服务器 安装 JDK 安装 Flume 第五章&nbsp;用户行为数据仓库 严格按照企业的标准开发 第六章&nbsp;搭建业务数仓理论基础和对表的分类同步 第七章&nbsp;业务数仓的搭建&nbsp; 业务行为数仓效果图&nbsp;&nbsp;
相关文章
|
26天前
|
存储 算法 Perl
数据结构实验之链表
本实验旨在掌握线性表中元素的前驱、后续概念及链表的建立、插入、删除等算法,并分析时间复杂度,理解链表特点。实验内容包括循环链表应用(约瑟夫回环问题)、删除单链表中重复节点及双向循环链表的设计与实现。通过编程实践,加深对链表数据结构的理解和应用能力。
52 4
|
19天前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
42 5
|
1月前
|
存储 C语言
【数据结构】手把手教你单链表(c语言)(附源码)
本文介绍了单链表的基本概念、结构定义及其实现方法。单链表是一种内存地址不连续但逻辑顺序连续的数据结构,每个节点包含数据域和指针域。文章详细讲解了单链表的常见操作,如头插、尾插、头删、尾删、查找、指定位置插入和删除等,并提供了完整的C语言代码示例。通过学习单链表,可以更好地理解数据结构的底层逻辑,提高编程能力。
73 4
|
1月前
|
算法 安全 搜索推荐
2024重生之回溯数据结构与算法系列学习之单双链表精题详解(9)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第2.3章之IKUN和I原达人之数据结构与算法系列学习x单双链表精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
1月前
|
存储 Web App开发 算法
2024重生之回溯数据结构与算法系列学习之单双链表【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构之单双链表按位、值查找;[前后]插入;删除指定节点;求表长、静态链表等代码及具体思路详解步骤;举例说明、注意点及常见报错问题所对应的解决方法
|
26天前
|
算法
数据结构之购物车系统(链表和栈)
本文介绍了基于链表和栈的购物车系统的设计与实现。该系统通过命令行界面提供商品管理、购物车查看、结算等功能,支持用户便捷地管理购物清单。核心代码定义了商品、购物车商品节点和购物车的数据结构,并实现了添加、删除商品、查看购物车内容及结算等操作。算法分析显示,系统在处理小规模购物车时表现良好,但在大规模购物车操作下可能存在性能瓶颈。
43 0
|
2月前
|
存储 Java
数据结构第三篇【链表的相关知识点一及在线OJ习题】
数据结构第三篇【链表的相关知识点一及在线OJ习题】
29 7
|
2月前
|
存储 安全 Java
【用Java学习数据结构系列】探索顺序表和链表的无尽秘密(附带练习唔)pro
【用Java学习数据结构系列】探索顺序表和链表的无尽秘密(附带练习唔)pro
27 3
|
2月前
|
算法 Java
数据结构与算法学习五:双链表的增、删、改、查
双链表的增、删、改、查操作及其Java实现,并通过实例演示了双向链表的优势和应用。
20 0
数据结构与算法学习五:双链表的增、删、改、查
【数据结构】——双向链表详细理解和实现
【数据结构】——双向链表详细理解和实现