![算法零基础一本通(Python版)](https://wfqqreader-1252317822.image.myqcloud.com/cover/51/44510051/b_44510051.jpg)
3-8 与链表有关的Python程序
这一节笔者将教导读者使用Python建立链表指标及遍历链表。
3-8-1 建立链表
想要建立链表,首先要建立此链表的节点,我们可以使用下列Node类别建立此节点。
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P44_61163.jpg?sign=1739690215-V6L2NQzmITgN4ch0joBx6T99l9Inub18-0-23340523eea046535f51a4ea1910a256)
Node类别有2个属性,其中data是存储节点数据,next是存储指标,此指标未来可指向下一个节点,在尚未设定前我们可以使用None。
程序实例ch3_1.py:建立一个含3个节点的链表,然后打印此链表。
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P44_51163.jpg?sign=1739690215-sf3ixiNEqqelKL6dGmgVigyH6w80Cy6w-0-1c5d53405b0b5c597e53e407a3690c11)
执行结果
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P45_47825.jpg?sign=1739690215-CSdXKKpWTqHDdTO9FX0lfogbZPzzB6OF-0-58015b4e8a2e8c11fcee7e19ba41fd53)
上述执行第8~10行后,可以在内存内建立下列3个节点。
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P45_47826.jpg?sign=1739690215-5vWGiqlCYGYgiGERGrhTcoQsp1yTH0zN-0-207658252b50dbc2bd22d4a88879512e)
执行第11行后链表节点内容如下:
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P45_47827.jpg?sign=1739690215-bVVC71imTYGIfyjkQRM9RQfijDyKP2V5-0-15ebe5d7a4127251d994a0823f7c57f4)
执行第12行后链表节点内容如下:
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P45_47828.jpg?sign=1739690215-4cTPbbmLkmyQN2lNXy0EterynWVYkOv7-0-957fd72ee87e6d6613eb465eea57b337)
执行第13行后会多一个指标ptr:
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P45_47829.jpg?sign=1739690215-VJgw7fJvCnHd1QjTV3vp77iRRM6KfTxX-0-cde86e8856f956205ee5e6cd0834fb30)
第14~16行可以打印此链表,得到5、15、25。
3-8-2 建立链表类别和遍历此链表
其实前一节笔者已经用实例讲解了建立链表的方式,也说明了遍历链表,这一节主要讲解建立一个链表Linked_list类别,在这个类别内我们使用__init__( )设计链表的第一个节点,同时使用print_list( )打印链表。
程序实例ch3_2.py:以建立Linked_list类别方式重新设计ch3_1.py。
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P46_51166.jpg?sign=1739690215-4ZTUOinvWFVgSpBm2fKVirx1UtQODmns-0-737391b50ba46a3982ff2125c6ce545a)
执行结果 与ch3_1.py相同。
3-8-3 在链表第一个节点前插入一个新的节点
在链表的应用中,常常需要插入新的节点数据,这一节重点是将新节点插入链表的第一个节点之前,也就是插在链表开头的位置。
程序实例ch3_3.py:扩充ch3_2.py,新建数据是100的节点,同时将100插入链表开头的位置。
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P46_51167.jpg?sign=1739690215-G6mD2Zb6AJWRBTBe3VW8j5s99pRlioQm-0-df157ef815990ccfe762ecc9a578e173)
执行结果
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P47_47833.jpg?sign=1739690215-dkXbfPmzDPhgFWYXbvyYlbuOQYWqGjiH-0-31be8501a1957e71caea40f360f17436)
上述程序第34行是调用begining( )方法,同时传递新节点值100,当执行第22行后,链表节点内容如下:
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P47_47834.jpg?sign=1739690215-D7uEZCO9Yv0PIjfTjItoiJZ4DBmijNZR-0-bd97501ee755e3740e416cd3f6448046)
当执行第23行后,链表节点内容如下:
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P47_47835.jpg?sign=1739690215-QVM29QDqDJnrIzXEOVkpXVyVX1Qf2Oos-0-f7207294bb7aa814f52370e20e872bcf)
当执行第24行后,链表节点内容如下:
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P48_47836.jpg?sign=1739690215-81btblqT5obpeS6kyDaS8PNaEr04kARq-0-653a87109a7f7359541d081621de0d4a)
3-8-4 在链表末端插入新的节点
程序实例ch3_4.py:在链表的末端插入新的节点。
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P48_51170.jpg?sign=1739690215-Zb2laZIsPj2bObpijcEiaq7RiSZCg9ig-0-f68193fb205aec0e283d9c355170e21c)
执行结果
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P49_47838.jpg?sign=1739690215-3XrK5hPqR6gG4fDjavHvdUSijssnjfSD-0-8d439c93d725aa72f6fc92c1753ce59a)
对于在链表末端插入节点,程序在第20~29行使用了ending( )方法,当执行第26行后,链表节点内容如下:
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P49_47839.jpg?sign=1739690215-kSsbSnxeAcIQnEh7hmsM77h96JAo8XSv-0-0292d2cc1ebd5ca583500f32dde23000)
当执行第27~28行后,链表节点内容如下:
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P49_47840.jpg?sign=1739690215-9upWiB4FqdeF9WUTvnrq7VOKKiTiScHo-0-2258031ed54fc8d0530917422aa86057)
当执行第29行后,链表节点内容如下:
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P49_47841.jpg?sign=1739690215-OH4ZtGX4CM5cIp6EKUaV9qT2w2NOo8AC-0-13e3f1efaf22cb70f0a11274261e43c6)
3-8-5 在链表中间插入新的节点
程序实例ch3_5.py:在链表n2节点的后面插入新的节点。
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P49_51172.jpg?sign=1739690215-8OycnwdZ8kXgDdPWBz05rIS3bo79TR5V-0-86750eded7516f00282f3616297c3d53)
执行结果
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P50_47844.jpg?sign=1739690215-kXdJDbCDlHeISerdVFGwbq3PpxECreHZ-0-3456e265e4d9402996b5f15607be0bc7)
对于在链表中间插入节点,程序在第20~28行使用了between( )方法,调用这个方法需要使用2个参数,第1个参数pre_node是指出要将新数据插入哪一个节点,第2个参数是新节点的值,当执行第26行后,链表节点内容如下:
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P50_47845.jpg?sign=1739690215-cEH6n0P8Rny1Ij8yVQ5WbpdhNW4wXCEr-0-affcbb256d652a30ba06cca0d4e074df)
当执行第27行后,链表节点内容如下:
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P50_47846.jpg?sign=1739690215-H1VcV47lZBQ7ze5Jz431grOM8GScE8LY-0-89c18136415f1469f70bd39874a2b425)
当执行第28行后,链表节点内容如下:
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P51_47847.jpg?sign=1739690215-urwkcF7luwsTfhJLEhoiHrV5EMQQiFII-0-6e8655ecabf3e98b4ec92e8430a3e230)
3-8-6 在链表中删除指定内容的节点
程序实例ch3_6.py:在链表中删除指定的节点前,先建立链表,此链表含有5、15、25这3个节点,然后删除15这个节点。
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P51_51176.jpg?sign=1739690215-2RwtomA2JEUB0ufs61u2esz2Tc7MNACx-0-f36862ae68a8089540f136eb12c05b05)
执行结果
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P52_47850.jpg?sign=1739690215-uTmuutaoEZWRsQiaXdO27X05nnQiv813-0-759cec069905c3b34b980cea1775eb6c)
上述程序第33行是建立暂时指标ptr,指向链表的第一个节点,第41~42行是建立暂时指标的前一个指标prev,未来找到删除节点时(ptr所指的节点),prev.next指向ptr.next,这样就算是删除暂时指标ptr所指的节点了,可以参考第45行。第43~44行主要是用在找不到指定节点时,可以直接返回。
3-8-7 建立循环链表
如果想要建立循环链表,只要将链表末端节点指向第1个节点即可。
程序实例ch3_7.py:建立循环链表,此列表有3个节点,打印6次。
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P52_51179.jpg?sign=1739690215-kYQrk2WmGEqxZGKQGuo0lyAer6W5SlOn-0-b3ab739426435a131365b4a479dcb327)
执行结果
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P53_47852.jpg?sign=1739690215-ILfMwKGekxr7wHz0RF7jwY4n0ZeIa0XQ-0-eb5cb997e346d8a252bf0ed68eda7d5c)
上述执行第12行后链表节点如下所示:
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P53_47853.jpg?sign=1739690215-tHrfZPD8Cx8jhXnYeSShja1byOh9oYVD-0-20a01044877bfb511e80f66ff628701f)
上述执行第13行后链表节点如下所示:
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P53_47854.jpg?sign=1739690215-OAmUBFQrmt4hhtDj4xc9emaEKy2FsNtu-0-09e278b2ad8bb36f906dfdd889f60a7d)
这样就完成了循环链表。
3-8-8 双向链表
如果要建立双向链表,每个节点必须有向前指标和向后指标,可以使用下列方式定义此节点。
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P53_47855.jpg?sign=1739690215-F0BRgtMaeqbaThO6fb2mVtHwysyNGVeo-0-a0b053968dad7d0feefae9cee4af7c9b)
程序实例ch3_8.py:建立双向链表,在建立节点过程中,每次均从头部打印一次双向链表,最后从尾部打印一次双向链表。
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P53_51183.jpg?sign=1739690215-gYr9wAKxv4P62oRVvhlF5Ev6C4A0VRR3-0-e9923bef17eb9f139faf26242a163fcd)
执行结果
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P54_47858.jpg?sign=1739690215-PFJHKIQdu5lrDdjZsZRAbCM0Qi9iY6UR-0-18b08d73a893b5e1257a8f66e88ebcd6)
这个程序第15~27行使用了add_double_list( )方法,将每个节点加入链表,第17行主要是确定所增加的数据是双向链表的节点,再执行18~26行。其中19~22行是增加第一个节点,当执行完第19行,链表节点内容如下:
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P55_47859.jpg?sign=1739690215-eXIaRoy8GTLABJjOCTqfiaNBlieQnMQX-0-a1f8204d3a45143be9034718a255d64d)
当执行完第20行,链表节点内容如下:
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P55_47860.jpg?sign=1739690215-9n8tu7FprH4giyiRUNNq9qKDlqylDXUZ-0-c4467b77a6aa381aea57e2167373dbe9)
当执行完第21行,链表节点内容如下:
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P55_47861.jpg?sign=1739690215-zjSs64ZVGeXvRwL2cLf2PcCjUpxz57Uu-0-1a1ed7cf5e91637312af8b81c98783ca)
当执行完第22行,链表节点内容如下:
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P55_47862.jpg?sign=1739690215-JfGYfQkZIdoiYaTP6einLWQHeoHIvKdP-0-7f92e77068c4678ce273bb116b4940fe)
上述就是建立双向链表的第一个节点过程。程序第24~26行是建立双向链表第2个(含)以后的节点过程,当执行完第24行,链表节点内容如下:
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P55_47863.jpg?sign=1739690215-MIn4wMT5rQajD8KFy6UGcifdZk2dHv8E-0-6a83817ec4dde271e28738976999da08)
当执行完第25行,链表节点内容如下:
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P55_47864.jpg?sign=1739690215-Hkn2mdfgS60LGXhSqVxLm61hnBOi8H8U-0-b337b7bc5acc1c0e48d78e64f97f3a51)
当执行完第26行,链表节点内容如下:
![](https://epubservercos.yuewen.com/6BDBC6/23721658309542706/epubprivate/OEBPS/Images/Figure-P56_47865.jpg?sign=1739690215-Mrp6R99fjmkyioOdG0XKALIrZ6IbVnAF-0-2965e6f92ccaa6f1cb5f97f87c24fedc)
程序第29~34行的print_list_from_head( )是从双向链表前端打印到末端,程序第36~41行的print_list_from_tail( )是从双向链表末端打印到前端。