第六节 单链表简单介绍和python代码实现
概念介绍:
链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。
以“结点的序列”表示线性表称作线性链表(单链表),单链表是链式存取的结构。
链接存储方法:
链接方式存储的线性表简称为链表(Linked List)。
链表的具体存储表示为:
① 用一组任意的存储单元来存放线性表的结点(这组存储单元既可以是连续的,也可以是不连续的)
② 链表中结点的逻辑次序和物理次序不一定相同。为了能正确表示结点间的逻辑关系,在存储每个结点值的同时,还必须存储指示其后继结点的地址(或位置)信息(称
为指针(pointer)或链(link))
链式存储是最常用的存储方式之一,它不仅可用来表示线性表,而且可用来表示各种非线性的数据结构。
结点结构
┌───┬───┐
│data │next │
└───┴───┘
data域--存放结点值的数据域,next域--存放结点的直接后继的地址(位置)的指针域(链域),链表通过每个结点的链域将线性表的n个结点按其逻辑顺序链接在一起的,每个结点只有一个链域的链表称为单链表(Single Linked List)。
头指针head和终端结点
单链表中每个结点的存储地址是存放在其前趋结点next域中,而开始结点无前趋,故应设头指针head指向开始结点。链表由头指针唯一确定,单链表可以用头指针的名字来命名。终端结点无后继,故终端结点的指针域为空,即NULL。
1 class Node(): 2 '''节点类''' 3 def __init__(self, elem): 4 '''节点的两个参数,本身值elem以及指向下一个节点的地址next''' 5 self.elem = elem 6 self.next = None 7 8 9 class SingLeLinkList(): 10 '''单链表''' 11 def __init__(self, node = None): 12 '''链表初始化指向下一个地址的值,刚开始链表为空,指向None''' 13 self.__head = None 14 def sing_append(self, elem): 15 ''' 16 关键在于理解代码是如何不断的通过改变next指向,完成链表的,第一次添加元素后self.__head指向的始终是node1,但是node1中的next指向却在不断通过添加的node实例叠加改变 17 第一次:self__head == node1,node1.next ==> None 18 第二次:self__head == node1,node1.next ==> node2 19 第三次:self__head == node1,node1.next ==> node2 ==> node2.next ==> node3 20 第四次:self__head == node1,node1.next ==> node2 ==> node2.next ==> node3 ==> node3.next==> node4 21 第五次:self__head == node1,node1.next ==> node2 ==> node2.next ==> node3 ==> node3.next==> node4 ==> node4.next==> node5 22 ... 23 ''' 24 node = Node(elem) 25 if self.is_empty(): 26 self.__head = node 27 else: 28 cur = self.__head 29 while cur.next != None: 30 # 循环体内代码,以添加第四次为例,此时形成node1.next = node2,node2.next = node3,node3.next = None 31 # 执行第一次循环,因为node1.next指向node2不为空,进入循环,将node1.next指向的对象即node2赋给cur,再判断因为node2.next指向node3,不为空进入循环,将node3赋值给cur,再判断因为node3.next == None 条件不成立,退出循环,此时cur指向的是node3,循环外执行node.next=node,即将node4赋值给node3.next 32 cur = cur.next 33 cur.next = node 34 35 def is_empty(self): 36 '''判断链表是否为空,第一次传入数据以后self.__head将永远指向node1对象''' 37 return self.__head == None 38 39 def sing_length(self): 40 '''链表长度''' 41 cur = self.__head 42 # 将第一个元素的node实例赋值给cur, 43 count = 0 44 while cur != None: 45 count+=1 46 cur = cur.next 47 return count 48 49 def sing_travel(self): 50 '''遍历整个列表''' 51 cur = self.__head 52 # 即将node1对象赋值给cur 53 while cur != None: 54 print(cur.elem) 55 # 如果已经添加了多个值,那么node1中的next指向便是嵌套的,通过代码cur = cur.next,将其一层层取出,直到去到最后一个对象其next属性为None时结束循环 56 cur = cur.next 57 58 def sing_add(self, item): 59 node = Node(item) 60 node.next = self.__head 61 self.__head = node 62 63 def sint_insert(self, pos, item): 64 x = None 65 cur = self.__head 66 if pos <= 0: 67 self.sing_add(item) 68 elif pos >= self.sing_length(): 69 self.sing_append(item) 70 else: 71 for i in range(pos): 72 x = cur 73 # 取一个中间变量来存储遍历到指定位置时的self.__head.next.next....的对象,x保留的是前半部分,cur.next保留的是后半部分 74 cur = cur.next 75 if i == pos - 1: 76 node = Node(item) 77 x.next = node 78 node.next = cur 79 80 def sing_search(self,item): 81 cur = self.__head 82 while cur != None: 83 cur = cur.next 84 if item == cur.elem: 85 return True 86 return False 87 88 def sing_remove(self, item): 89 cur = self.__head 90 x = None 91 while cur != None: 92 if item == cur.elem: 93 if cur == self.__head: 94 self.__head = cur.next 95 break 96 else: 97 x.next= cur.next 98 break 99 else: 100 x = cur 101 cur = cur.next 102 103 if __name__ == "__main__": 104 ll = SingLeLinkList() 105 ll.sing_append(1) 106 ll.sing_append(2) 107 # ll.sing_add(8) 108 ll.sing_append(3) 109 ll.sint_insert(-1,5) 110 ll.sing_travel() 111 print(ll.sing_search(5)) 112 ll.sing_remove(3) 113 ll.sing_travel()