单链表怎么用(单链表基础操作)
导语:入门单链表
链表简介链表(linked list)作为一种常见的数据结构,通常由数据和指针组合而成。在一些没有指针结构的程序语言中,如 python、java等,指针被引用所代替。链表中的每个节点通过指针或引用相连接,你可以通过指针或者引用来遍历节点。
下图为单个节点的构成:
链表也有很多种形式,有单链表、循环链表、双向链表,下面我们介绍一种常用的单链表:
在单链表中,每个节点包括指向下一个节点的指针。但是单链表的首尾节点却特立独行,头结点只有指针,却没有数据;尾节点恰好相反,只有数据,没有指针,也就是提示我们链表后面不再有其他的节点。当我们找到第一个节点的时候,我们可以很轻松的获取链表其余节点。
这就像小时候玩游戏,一群小伙伴排成一排,手拉着手。左手被别人握紧,右手也紧紧握住别人的左手。左手就代表数据,右手代表指针。从第一个同学开始,这种通过左右手建立的联系,使我们很轻松的就找到了每一个人的位置。如果有一个小伙伴要加入,他会被分配在自己最好的朋友的前面,姑且将其记作“友人A”,我们就从第一个小伙伴开始遍历,如果找到了一个右手握住“友人A”的同学,姑且记作“同学B”,我们就停下来。先让这个小伙伴紧紧抓住“友人A”的右手,再让“同学B”握住他的左手。这样,这位小伙伴就找了自己的归宿。如果走遍了这条长长的队伍,还有没有找到属于自己的联系,那就稍稍有些寂寞了。如果有的人最好的”朋友C”变心了,他要出局了。我们还是要从第一个人开始遍历这条长长的队伍,一旦我们找到这个人前面的“同学D”,让“同学D”握住”朋友C“的手,然后再断开这个人与”朋友C“之间的羁绊,这个人重又恢复了自由身,尽管有少许的寂寞。
下面我们用 python 实现简单的单链表:
创建一个节点建立一个节点很简单,我们只要给节点对象的数据和指针属性赋值即可。头结点和尾节点稍稍有些不同,头结点数据为 None,尾节点指针为 None。
拿上面的例子说,就是没有人握住第一个小朋友的左手,所以说他的数据为空;最后一个小朋友也无法握住别人的左手,所以说他的指向为空。而其他小朋友,左手被别人紧紧握住,右手则紧紧握住别人,即数据与指向都不为空。
class Node(object): def __init__(self, data, pointer): self.data = data self.next = pointer 末尾追加节点 new_node = Node(data, None) self.point.next = new_node self.point = new_node
插入节点
在特定节点前面插入数据:新建一个节点,然后找到特定节点的前驱结点,然后让新节点的next
指向特定节点,而前驱结点也要指向新节点。
但是有些新来的人不甘心站在队伍的末尾,因为末尾的人没有”珍贵之物“(右手没有紧紧握住的对象),他想在队伍中找到命中之人。他就从头一个一个的寻找,直到发现有一个人握住了他的意中人。他就握住意中人的左手,再让前一个人握住他的左手。
def insert(self, data, find): 删除节点 get_size()改变了 self.point 的指向 length = self.get_size() i, j = 0, 0 flag = 1 while i < length: self.point = self.head.next while j < length - i - 1: if self.point.data > self.point.next.data: temp = self.point.data self.point.data = self.point.next.data self.point.next.data = temp self.point = self.point.next j += 1 flag = 0 if flag: break i += 1 j = 0
求中间节点 只允许遍历一次
如果可以多次遍历的话,我们大可以求出链表的大小,再算出中间节点。但只让遍历一次的话,我们就要用到快慢指针的方法了。形象地说,就是有两个同学在操场上跑步,记为A,B。A 同学跑步速度是 B 同学的二倍,也就是说,A 同学跑完一圈的时候,B 同学刚好跑完半圈。同理,我们用快慢指针来遍历链表,快指针到达尾节点时,慢指针正好指向了中间节点。 代码中体现为,快指针每次前进两个节点,而慢指针只前进一个节点。当快指针指向尾节点时,停止遍历。
打印结点 self.point = self.head while self.point.next: self.point = self.point.next print('{} ->'.format(self.point.data), end=' ') print('')
删除尾节点
根据链表大小,找到尾节点,然后类似删除节点的操作。
def delete_by_tail(self, num): size = self.get_size() assert (num <= size) assert (num > 0) pos = size - num count = 0 self.point = self.head while count < size: count += 1 self.point = self.point.next if count == pos: pointer = self.point.next self.point.next = self.point.next.next del pointer
我犯的错误
head 的 next 就指向 node 节点,再让 node 节点指向 head.next,就相当于 node 节点指向了自身,所以循环打印时,永远跳不出循环。
自身指向自身 打印值时出不去node = Node(4,None)head = Node(4,node)node.next = head.nexti = 0while node.next: i += 1 print(node.data) if i > 12: break
这就是本节的全部内容了,看完了要多多用编程巩固一下哦。
本文内容由小洁整理编辑!