《数据结构与算法(Python语言描述)》第三章 链表反转

发现书中的一点点的小失误


在本书的 3.44 链表反转的实现代码中,q._next = p应该是写错了,如果你按着书上的写,会出现以下情况:

>>>m1 = LList()
>>>for i in range(i):
...    m1.prepend(i)
...
>>>m1.printall()
9 ,  8 ,  7 ,  6 ,  5 ,  4 ,  3 ,  2 ,  1 ,  0
>>>m1.rev() # 调用反转方法
>>>m1.printall()
0

解决方法是将q._next = p,改成q.next = p

下面是我的问题分析,可略过,欢迎指正,谢谢!


为什么会出现这种情况呢?(建议大家像书上一样,画出链表图)

我们逐条分析一下这个rev方法

while self._head is not None:
# 当self._head为空时,即当表内所有结点都已经处理完毕时,结束循环
    q = self._head
    # 将当前的首端结点赋值给 p 
    self._head = q.next
    # 更新self._head,使其指向下一个结点
    q._next = p
    # 重点来了,这条语句创建了一个新的“结点属性” self._next,
    # 并指向新表 p 的原首端结点
    p = q
    #p 指向新的首端结点,至此,一次插入操作完成。
self._head = p
# 旧表的所有结点处理完毕后,self._head为None,
# 将新表 p 赋值给 self._head

看到没?我们新创建了一个结点属性_next,这个属性里保存了反转链表后的正确顺序,我们并没有更新结点的self.next属性;也就是说,self.next属性仍然保存着没反转的顺序!

我们找到了问题的源头,修改正确就可以了;

But,这完全不能满足我们的好奇心啊

我们更想知道的是,为啥问题会以这种形式表现出来呢?

上面说了,self.next依旧保持着原来的样子,原来是啥,反转完之后就还是啥;
那么原表的尾端结点,也就是最后一个取下来的结点,它的next域依然还是None
而当所有原来表的结点都操作完成后,原表的尾端结点就变成了新表p的首端结点,其next域None
rev方法的最后语句,将新表p赋值给self._head,现在我们知道了,self._head指向的首端结点,它的nextNone

以这个为例,原来的顺序是从小到大:
链表图

使用printall方法时出现的显示不正确,那么我们看一下这个方法:

def printall(self):
    p = self._head # 将首端结点赋值给 变量p 
    while p is not None: # 如果p不为None,则循环继续;否则,退出
        print(p.elem, end = " ")
        if p.next is not None: # 如果当前p的next域不为None
            print(", ", end = " ")
        p = p.next # 将p的next域所代表的下一个结点赋值给 p
    print(" ")

可以来走一下这个流程:
1. 首先拿到首端结点;我们判断p是否为None,显然不是,那么程序继续。
2. 打印了p.elem的值。
3. 判断p.next是否为None,当然是None,那么跳过if块的内容。
4. 将p.next所代表的值赋值p,现在pNone
5. 回到第一步,判断p是否为None;至此循环结束。

扫描二维码关注公众号,回复: 288432 查看本文章

看一下我们思考了什么:

  • 当结果不符合我们的要求时,首先看一下出错的函数部分:printall方法(定位错误);
  • 如果pythonall方法没有错误,那么就是我们添加的方法有错误,经过梳理程序,我们发现原来next没有更新。
  • 将这种情况保留,通过模拟带入的方式,得到错误出现的原因(不止这一种方法)。

总结

本来这篇文章不应该这么长,到解决方法那里就可以结束了,可是能学到什么呢?大家一看:“哦,原来这么改就行了”;错误为什么是那样依旧不清楚,这样得到的东西很少很少,只要有时间,就多琢磨琢磨,当你知道为什么后,你可以想出其他的解决办法,说不定会比这个解决方法更高效。

初学者也要写出自己的想法,能写出来,或者给别人讲清楚,你就真的熟悉了;在接受别人提问和质疑的时候,是深入了解你所学的东西的好方法,所以大胆的写出来,别觉得没什么可写的,把你看的东西复述出来也行。

关于这本书,尽管写出你的博客,然后可以在评论里告诉我博客地址,我们一起讨论(我也是初学)。


紧...紧张

猜你喜欢

转载自blog.csdn.net/qq_39672528/article/details/79850448