双向链表

Posted buanxu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了双向链表相关的知识,希望对你有一定的参考价值。

    之前说了单链表,下面来说一下双向链表。和单链表不同,双向链表中的每个节点都有两个指针,分别用来指向它的前驱和后继。所以从双向链表中的

任意一个节点开始,都可以很方便地访问到他的钱去纪念和后继结点。下面给张图来展示一下什么是双向链表

技术图片

    这就是双向链表,每个结点都有两个指针,其中表头结点的前驱指针prior始终是空的NULL,表头结点的data域可以给个值也可以不给,不过建议给个初始

值,防止出现野值。

    下面给出创建双向链表的代码,用头插法,类似单链表,不过和单链表有点小区别;其中从第23行到30行理解起来有点绕,建议最好画个图演示一下,画个图你就懂了

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 typedef struct LNode
 4 {
 5     int data;
 6     struct LNode *next,*prior;
 7 }LNode,*LinkList;
 8 
 9 LinkList create_LinkList()
10 {  
11        LinkList head;   //声明头指针
12        int  e;  //用来标记第一个插入的元素
13        char ch;  
14        LNode * p=NULL;
15        head=(LinkList)malloc(sizeof(LNode));  //头插法创建链表需要创建表头
16        head->data=-1;   //表头结点初始化为-1,不用!
17        head->prior=NULL;    //表头结点的prior始终是空的NULL
18        head->next=NULL;    
19        do{
20           p=(LinkList)malloc(sizeof(LNode));  //p是当前待插入的结点
21           scanf("%d",&e);
22           p->data=e;
23           p->next=head->next;  //插入在头部,让当前节点的next指向它的后继
24           p->prior=head;     //让当前节点的prior指向它的前驱也就是表头结点
25           if(head->next==NULL)    //当插入第一个元素时,表头结点没有后继,只需要令表头结点的next指向它的后继也就是p即可
26               head->next=p;
27           else  //特别强调,else中两条语句的顺序不能颠倒!!!
28           {
29               head->next->prior=p;   //让p的后继结点的prior指向前驱,即指向p
30               head->next=p;      //令表头的next指向它的后继即p
31           }     
32        }while((ch=getchar())!=
);
33        return head;   //返回头指针
34 } 
35 int main()
36 {
37     LinkList head,p;
38     head=create_LinkList();
39     p=head->next;    //链表有头节点,让p跳过头结点,指向双链表中的第一个结点
40     while(p!=NULL)
41     {
42         if(p->prior==head)  //双链表中的第一个元素
43             printf("当前结点为:%d   没有前驱   后继为:%d
",p->data,p->next->data);
44         if(p->next==NULL)  //双链表中的最后一个元素
45             printf("当前结点为:%d   前驱为:%d   没有后继
",p->data,p->prior->data);
46         printf("当前结点为:%d   前驱为:%d   后继为:%d
",p->data,p->prior->data,p->next->data);
47         p=p->next;
48     }
49     printf("
");
50     return 0;
51 }

    另外说一下,代码有一点小问题,调试了很久,实在是找不出哪里错了。不过整体没有问题,看测试结果吧

技术图片

    有没有发现输出结果出现了问题,就在输出结果的第三行,按理说在输出了第一个节点后应该继续输出第二个节点呀?但是竟然又输出了一次第一个结点?why ?

不晓得哪里出错了,而且输出的前驱竟然是表头结点里的data域的值,按理说第一个结点是没有前驱的,即便又重复输出了一次,但起码应该和上次输出的结果一样吧?

虽然后继是正确的,但是为什么这次和上次输出的不一样?更邪门的是接下来的输出结果都是正确的。真的想不通哪里有问题了,如果有大佬看出哪里有问题的话,欢

迎指出,万分感激!

    另外还有一个问题,就是一般在程序输出完结果后,会立马出现“请按任意键继续”这句话,但是运行的结果却不是这个样子,在输出完数据后没有立马出现这句话后,

而是过了5、6秒后才出现,看一下图吧,竟然还给了我截图的时间  技术图片

 

 技术图片

    真的是脑壳疼,我感觉这个问题要比上个还不好想。如果后续发现错误了,会及时更新并说明错误。

 

2020-04-30        22:01:39

以上是关于双向链表的主要内容,如果未能解决你的问题,请参考以下文章

带头节点的双向链表

《链表》之带头双向循环链表

7L-双线链表实现

代码模板实现双向链表的去重拼接合并排序

数据结构之带头结点的循环双向链表详细图片+文字讲解

双向链表 - 是啥导致我的代码引发编译器错误,我该如何解决?