V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
station
V2EX  ›  C

初学链表,这段代码看的有些浑

  •  
  •   station · 2020-02-27 19:09:37 +08:00 · 3762 次点击
    这是一个创建于 1512 天前的主题,其中的信息可能已经有所发展或是发生改变。

    链表这部分,书( C 语言程序设计现代方法 )上写得我觉得不是很详细(估摸着是有些涉及数据结构,没细讲,所以我是跟着视屏+搜索来的) 这几天看书看的有些发昏了

    前面我都还能明白是什么意思,到了第⑦步时我就有些浑了 (不知道我下面的释义是否正确,如有错误请指出)

    1. 第四步的时候 head=tail=link,所以这三个指针均指向首结点的首地址

    2. 第七步: 将 tail 指向首结点成员 Next ( 此时为 NULL ),而 link 又被赋值给 Next,此时首结点成员 Next 保存的是 link 的首地址

    • tail 在尚未执行 tail=tail->Next 时,还是在指向首结点的头部,执行完 tail=tail->Next 后,tail 指向首结点的指针域(此时为 NULL)

    • 执行 tail->Next=link;为首结点的指针域赋值,指向新结点的首地址

    我看了很多示例都是两条语句来完成这个链接,是不能直接 tail->Next 吗 ?

    是否可以理解为 tail 是一个专门用于操作指针域的指针 ?

    额,现在脑袋一团乱,能想到问题暂时就这两个。。。。

    3ajeRU.png

    17 条回复    2020-02-28 06:22:11 +08:00
    MOONLIGHTT
        1
    MOONLIGHTT  
       2020-02-27 19:18:29 +08:00
    这个程序一次性向链表中添加很多元素,第 7 步是当链表的头指针不为空时执行的。
    we21x
        2
    we21x  
       2020-02-27 19:23:01 +08:00
    1. 第一步的代码不是判断 Data 的值是否为 1,而是判断 scanf 是否成功( scanf 返回接受输入的个数)。
    2. 第七步 tail = tail->Next; 应该在 tail->Next = link; 后面,也就是 tail->Next = link;tail = tail->Next;
    先把尾结点的后继指向新节点,然后将尾结点更新为新节点,下次循环就是用上次的新节点指向这次的新节点。
    station
        3
    station  
    OP
       2020-02-27 19:23:44 +08:00
    上面编辑有缺失: 我看了很多示例都是两条语句来完成这个链接,是不能直接 tail->Next=link 吗 ?
    ccpp132
        4
    ccpp132  
       2020-02-27 19:27:34 +08:00
    这代码错了,应该先 [1]tail->next = link 再 [2]tail = tail->next
    tail 就是最后一个结点的位置,[1]就插入,[2]就是插入之后,tail 就不是最后的结点的位置了,再重新找到。
    loryyang
        5
    loryyang  
       2020-02-27 19:29:29 +08:00
    这代码写错了吧,第一次进来,tail = link,所以 tail->Next 是 NULL,第二次进来,tail = tail->Next = NULL,后面还怎么 tail->Next。。。
    找了一下,他的写法和这个网站( https://www.sanfoundry.com/c-program-create-linked-list-display-elements/)的写法基本一样,可以看这里面的代码
    loryyang
        6
    loryyang  
       2020-02-27 19:37:04 +08:00
    @station #3 你要保持 tail 永远是最后一个,如果只做一次 tail->Next=link,那 tail 就已经不是 tail 了,link 才是 tail 的位置。所以需要做一次赋值,tail = link 或者 tail = tail->Next,这两个是等价的
    loryyang
        7
    loryyang  
       2020-02-27 19:39:12 +08:00
    另外,这个代码风格也太烂了吧,Data 和 Next 的首字母大写简直就像是一个初学者写出来的
    station
        8
    station  
    OP
       2020-02-27 19:52:34 +08:00
    @loryyang 🤭,代码风格确实不好
    BBCCBB
        9
    BBCCBB  
       2020-02-27 20:19:44 +08:00
    ```c
    else {
    tail->next = link;
    tail = tail->next;
    }
    ```
    这样就对了,楼主. 你需要先把 link 连到链表的尾节点上, 然后再把 link(此时已经是原尾节点的下一个节点, 也就是 tail.next) 作为链表的尾节点
    BBCCBB
        10
    BBCCBB  
       2020-02-27 20:22:14 +08:00
    或者你直接
    ```c
    else {
    tail->next = link;
    tail = link;
    }
    ```

    这样都可以
    JerryCha
        11
    JerryCha  
       2020-02-27 20:29:04 +08:00
    看懵了,这代码有问题吧。
    链表为空的时候,head、tail 均指向第一个节点,即循环第一次时创建的 link
    循环第二次。link 创建前:head 和 tail 均指向第一个节点; link 创建后,head 指向第一个节点、tail 应该此时即将成为倒数第二个节点。那么完成这个转换的操作应该是 tail->next = link。
    但是给出的代码是先把 tail 调整指向 NULL,然后获取 NULL 的 next。。。
    station
        12
    station  
    OP
       2020-02-27 20:48:39 +08:00
    @loryyang
    意识到顺序反了, tail->next=link; 再执行 tail=tail->next

    比方说我一共创建两个结点,第一次进循,tail = link,首结点 Next 是 NULL,第二次进来,将新建的结点地址通过指针 tail 访问成员赋值给 next , 此时首结点的指针域保存了下个结点的地址

    tail=tail->next 将新结点的地址赋值给 tail,让其指向 link 正在指向的结点,此后循环依次类推

    若只执行 tail->next=link,只是保存了首结点的下个地址,若不执行 tail=tail->next,tail 依然指向首结点,再次创建新结点的话,则无法指向第三结点

    这回应该对了。。。
    station
        13
    station  
    OP
       2020-02-27 20:58:06 +08:00
    @station 若不执行 tail=tail->next,tail 依然指向首结点,再次创建新结点的话,则无法指向第三结点

    描述错误,改为: 无法为第三与第二结点创建链接
    zifangsky
        14
    zifangsky  
       2020-02-27 21:57:00 +08:00
    个人觉得还是用 Java 学数据结构对初学者比较友好啊
    darksword21
        15
    darksword21  
       2020-02-27 22:26:30 +08:00
    推荐看下 如果天空不死的博客
    bug4c
        16
    bug4c  
       2020-02-28 00:50:00 +08:00 via iPhone
    楼主这什么字体,有点好看
    station
        17
    station  
    OP
       2020-02-28 06:22:11 +08:00
    @bug4c source code pro
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   4041 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 05:19 · PVG 13:19 · LAX 22:19 · JFK 01:19
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.