zoukankan      html  css  js  c++  java
  • 双向链表

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

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

        这就是双向链表,每个结点都有两个指针,其中表头结点的前驱指针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

  • 相关阅读:
    解决margin 外边距合并问题
    tsx 校验 以及写法
    tsx 引入文件找不到
    Ubuntu 16.04安装和卸载软件命令
    Java8 中使用Stream 让List 转 Map使用总结
    Java8 Stream流式编程浅析
    浅析IOC 和 DI
    [ Java面试题 ]Java 开发岗面试知识点解析
    Intellij Idea 常用快捷键总结+实用小技巧
    Intellij Idea基础设置
  • 原文地址:https://www.cnblogs.com/buanxu/p/12811399.html
Copyright © 2011-2022 走看看