|
| 1 | +# 1.单链表的插入、删除、查找操作; |
| 2 | +# 2.链表中存储的数据类型是Int |
| 3 | +# |
| 4 | +# Author:Lee |
| 5 | + |
| 6 | +class Node(): |
| 7 | + '''链表结构的Node节点''' |
| 8 | + |
| 9 | + def __init__(self, data, next=None): |
| 10 | + '''Node节点的初始化方法. |
| 11 | + 参数: |
| 12 | + data:存储的数据 |
| 13 | + next:下一个Node节点的引用地址 |
| 14 | + ''' |
| 15 | + self.__data = data |
| 16 | + self.__next = next |
| 17 | + |
| 18 | + @property |
| 19 | + def data(self): |
| 20 | + '''Node节点存储数据的获取. |
| 21 | + 返回: |
| 22 | + 当前Node节点存储的数据 |
| 23 | + ''' |
| 24 | + return self.__data |
| 25 | + |
| 26 | + @data.setter |
| 27 | + def data(self, data): |
| 28 | + '''Node节点存储数据的设置方法. |
| 29 | + 参数: |
| 30 | + data:新的存储数据 |
| 31 | + ''' |
| 32 | + self.__data = data |
| 33 | + |
| 34 | + @property |
| 35 | + def next(self): |
| 36 | + '''获取Node节点的next指针值. |
| 37 | + 返回: |
| 38 | + next指针数据 |
| 39 | + ''' |
| 40 | + return self.__next |
| 41 | + |
| 42 | + @next.setter |
| 43 | + def next(self, next): |
| 44 | + '''Node节点next指针的修改方法. |
| 45 | + 参数: |
| 46 | + next:新的下一个Node节点的引用 |
| 47 | + ''' |
| 48 | + self.__next = next |
| 49 | + |
| 50 | + |
| 51 | +class SinglyLinkedList(): |
| 52 | + '''单向链表''' |
| 53 | + |
| 54 | + def __init__(self): |
| 55 | + '''单向列表的初始化方法.''' |
| 56 | + self.__head = None |
| 57 | + |
| 58 | + def find_by_value(self, value): |
| 59 | + '''按照数据值在单向列表中查找. |
| 60 | + 参数: |
| 61 | + value:查找的数据 |
| 62 | + 返回: |
| 63 | + Node |
| 64 | + ''' |
| 65 | + node = self.__head |
| 66 | + if node != None and node.data != value: |
| 67 | + node = node.next |
| 68 | + else: |
| 69 | + return node |
| 70 | + |
| 71 | + def find_by_index(self, index): |
| 72 | + '''按照索引值在列表中查找. |
| 73 | + 参数: |
| 74 | + index:索引值 |
| 75 | + 返回: |
| 76 | + Node |
| 77 | + ''' |
| 78 | + node = self.__head |
| 79 | + pos = 0 |
| 80 | + while node != None and pos != index: |
| 81 | + node = node.next |
| 82 | + pos += 1 |
| 83 | + return node |
| 84 | + |
| 85 | + def insert_to_head(self, value): |
| 86 | + '''在链表的头部插入一个存储value数值的Node节点. |
| 87 | + 参数: |
| 88 | + value:将要存储的数据 |
| 89 | + ''' |
| 90 | + node = Node(value) |
| 91 | + node.next = self.__head |
| 92 | + self.__head = node |
| 93 | + |
| 94 | + def insert_after(self, node, value): |
| 95 | + '''在链表的某个指定Node节点之后插入一个存储value数据的Node节点. |
| 96 | + 参数: |
| 97 | + node:指定的一个Node节点 |
| 98 | + value:将要存储在新Node节点中的数据 |
| 99 | + ''' |
| 100 | + if node == None: # 如果指定在一个空节点之后插入数据节点,则什么都不做 |
| 101 | + return |
| 102 | + |
| 103 | + new_node = Node(value) |
| 104 | + new_node.next = node.next |
| 105 | + node.next = new_node |
| 106 | + |
| 107 | + def insert_before(self, node, value): |
| 108 | + '''在链表的某个指定Node节点之前插入一个存储value数据的Node节点. |
| 109 | + 参数: |
| 110 | + node:指定的一个Node节点 |
| 111 | + value:将要存储在新的Node节点中的数据 |
| 112 | + ''' |
| 113 | + if node == None or self.__head == None: # 如果指定在一个空节点之前或者空链表之前插入数据节点,则什么都不做 |
| 114 | + return |
| 115 | + |
| 116 | + if node == self.__head: # 如果是在链表头之前插入数据节点,则直接插入 |
| 117 | + self.insert_to_head(value) |
| 118 | + return |
| 119 | + |
| 120 | + new_node = Node(value) |
| 121 | + pro = self.__head |
| 122 | + not_found = False # 如果在整个链表中都没有找到指定插入的Node节点,则该标记量设置为True |
| 123 | + while pro.next != node: # 寻找指定Node之前的一个Node |
| 124 | + if pro.next == None: # 如果已经到了链表的最后一个节点,则表明该链表中没有找到指定插入的Node节点 |
| 125 | + not_found = True |
| 126 | + break |
| 127 | + else: |
| 128 | + pro = pro.next |
| 129 | + if not_found == False: |
| 130 | + pro.next = new_node |
| 131 | + new_node.next = node |
| 132 | + |
| 133 | + def delete_by_node(self, node): |
| 134 | + '''在链表中删除指定Node的节点. |
| 135 | + 参数: |
| 136 | + node:指定的Node节点 |
| 137 | + ''' |
| 138 | + if self.__head == None: # 如果链表是空的,则什么都不做 |
| 139 | + return |
| 140 | + |
| 141 | + if node == self.__head: # 如果指定删除的Node节点是链表的头节点 |
| 142 | + self.__head = node.next |
| 143 | + return |
| 144 | + |
| 145 | + pro = self.__head |
| 146 | + not_found = False # 如果在整个链表中都没有找到指定删除的Node节点,则该标记量设置为True |
| 147 | + while pro.next != node: |
| 148 | + if pro.next == None: # 如果已经到链表的最后一个节点,则表明该链表中没有找到指定删除的Node节点 |
| 149 | + not_found == True |
| 150 | + break |
| 151 | + else: |
| 152 | + pro = pro.next |
| 153 | + if not_found == False: |
| 154 | + pro.next = node.next |
| 155 | + |
| 156 | + def delete_by_value(self, value): |
| 157 | + '''在链表中删除指定存储数据的Node节点. |
| 158 | + 参数: |
| 159 | + value:指定的存储数据 |
| 160 | + ''' |
| 161 | + if self.__head == None: # 如果链表是空的,则什么都不做 |
| 162 | + return |
| 163 | + |
| 164 | + if self.__head.data == value: # 如果链表的头Node节点就是指定删除的Node节点 |
| 165 | + self.__head = self.__head.next |
| 166 | + |
| 167 | + pro = self.__head |
| 168 | + node = self.__head.next |
| 169 | + not_found = False |
| 170 | + while node.data != value: |
| 171 | + if node.next == None: # 如果已经到链表的最后一个节点,则表明该链表中没有找到执行Value值的Node节点 |
| 172 | + not_found == True |
| 173 | + break |
| 174 | + else: |
| 175 | + pro = node |
| 176 | + node = node.next |
| 177 | + if not_found == False: |
| 178 | + pro.next = node.next |
| 179 | + |
| 180 | + def delete_last_N_node(self, n): |
| 181 | + '''删除链表中倒数第N个节点. |
| 182 | + 主体思路: |
| 183 | + 设置快、慢两个指针,快指针先行,慢指针不动;当快指针跨了N步以后,快、慢指针同时往链表尾部移动, |
| 184 | + 当快指针到达链表尾部的时候,慢指针所指向的就是链表的倒数第N个节点 |
| 185 | + 参数: |
| 186 | + n:需要删除的倒数第N个序数 |
| 187 | + ''' |
| 188 | + fast = self.__head |
| 189 | + slow = self.__head |
| 190 | + step = 0 |
| 191 | + |
| 192 | + while step <= n: |
| 193 | + fast = fast.next |
| 194 | + step += 1 |
| 195 | + |
| 196 | + while fast.next != None: |
| 197 | + tmp = slow |
| 198 | + fast = fast.next |
| 199 | + slow = slow.next |
| 200 | + |
| 201 | + tmp.next = slow.next |
| 202 | + |
| 203 | + def find_mid_node(self): |
| 204 | + '''查找链表中的中间节点. |
| 205 | + 主体思想: |
| 206 | + 设置快、慢两种指针,快指针每次跨两步,慢指针每次跨一步,则当快指针到达链表尾部的时候,慢指针指向链表的中间节点 |
| 207 | + 返回: |
| 208 | + node:链表的中间节点 |
| 209 | + ''' |
| 210 | + fast = self.__head |
| 211 | + slow = self.__head |
| 212 | + |
| 213 | + while fast.next != None: |
| 214 | + fast = fast.next.next |
| 215 | + slow = slow.next |
| 216 | + |
| 217 | + return slow |
| 218 | + |
| 219 | + def create_node(self, value): |
| 220 | + '''创建一个存储value值的Node节点. |
| 221 | + 参数: |
| 222 | + value:将要存储在Node节点中的数据 |
| 223 | + 返回: |
| 224 | + 一个新的Node节点 |
| 225 | + ''' |
| 226 | + return Node(value) |
| 227 | + |
| 228 | + def print_all(self): |
| 229 | + '''打印当前链表所有节点数据.''' |
| 230 | + pos = self.__head |
| 231 | + if pos == None: |
| 232 | + print('当前链表还没有数据') |
| 233 | + return |
| 234 | + while pos.next != None: |
| 235 | + print(str(pos.data) + ' --> ', end='') |
| 236 | + pos = pos.next |
| 237 | + print(str(pos.data)) |
| 238 | + |
| 239 | + def reversed_self(self): |
| 240 | + '''翻转链表自身.''' |
| 241 | + if self.__head == None or self.__head.next == None: # 如果链表为空,或者链表只有一个节点 |
| 242 | + return |
| 243 | + |
| 244 | + pre = self.__head |
| 245 | + node = self.__head.next |
| 246 | + while node != None: |
| 247 | + pre, node = self.__reversed_with_two_node(pre, node) |
| 248 | + |
| 249 | + self.__head.next = None |
| 250 | + self.__head = pre |
| 251 | + |
| 252 | + def __reversed_with_two_node(self, pre, node): |
| 253 | + '''翻转相邻两个节点. |
| 254 | + 参数: |
| 255 | + pre:前一个节点 |
| 256 | + node:当前节点 |
| 257 | + 返回: |
| 258 | + (pre,node):下一个相邻节点的元组 |
| 259 | + ''' |
| 260 | + tmp = node.next |
| 261 | + node.next = pre |
| 262 | + pre = node # 这样写有点啰嗦,但是能让人更能看明白 |
| 263 | + node = tmp |
| 264 | + return (pre, node) |
| 265 | + |
| 266 | + def has_ring(self): |
| 267 | + '''检查链表中是否有环. |
| 268 | + 主体思想: |
| 269 | + 设置快、慢两种指针,快指针每次跨两步,慢指针每次跨一步,如果快指针没有与慢指针相遇而是顺利到达链表尾部 |
| 270 | + 说明没有环;否则,存在环 |
| 271 | + 返回: |
| 272 | + True:有环 |
| 273 | + False:没有环 |
| 274 | + ''' |
| 275 | + fast = self.__head |
| 276 | + slow = self.__head |
| 277 | + |
| 278 | + while fast.next != None and fast != None: |
| 279 | + fast = fast.next |
| 280 | + slow = slow.next |
| 281 | + if fast == slow: |
| 282 | + return True |
| 283 | + |
| 284 | + return False |
0 commit comments