V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
station
V2EX  ›  C

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

  •  
  •   station · Feb 27, 2020 · 4657 views
    This topic created in 2265 days ago, the information mentioned may be changed or developed.

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

    这样都可以
    JerryCha
        11
    JerryCha  
       Feb 27, 2020
    看懵了,这代码有问题吧。
    链表为空的时候,head、tail 均指向第一个节点,即循环第一次时创建的 link
    循环第二次。link 创建前:head 和 tail 均指向第一个节点; link 创建后,head 指向第一个节点、tail 应该此时即将成为倒数第二个节点。那么完成这个转换的操作应该是 tail->next = link。
    但是给出的代码是先把 tail 调整指向 NULL,然后获取 NULL 的 next。。。
    station
        12
    station  
    OP
       Feb 27, 2020
    @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
       Feb 27, 2020
    @station 若不执行 tail=tail->next,tail 依然指向首结点,再次创建新结点的话,则无法指向第三结点

    描述错误,改为: 无法为第三与第二结点创建链接
    zifangsky
        14
    zifangsky  
       Feb 27, 2020
    个人觉得还是用 Java 学数据结构对初学者比较友好啊
    darksword21
        15
    darksword21  
    PRO
       Feb 27, 2020
    推荐看下 如果天空不死的博客
    bug4c
        16
    bug4c  
       Feb 28, 2020 via iPhone
    楼主这什么字体,有点好看
    station
        17
    station  
    OP
       Feb 28, 2020
    @bug4c source code pro
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   1710 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 48ms · UTC 16:23 · PVG 00:23 · LAX 09:23 · JFK 12:23
    ♥ Do have faith in what you're doing.