上一篇:Python实现单向链表(上):15种增删改查操作
之前写了一组代码,实现了一些单向链表的操作。作为小白,写的比较臃肿。又把增删改查等类似操作整合了一下,这里的代码对比上一篇中的稍微简洁了些
和上一篇的思路一样,写两个类:
Node类:用于创建结点,并将结点以(人类)能看懂的字符串形式输出,而不是显示内存地址LinkedList类:在这一类下的方法里做了改动。这个类用于将各结点连成链表,并实现对链表进行操作的一些方法调用测试:
n = Node(1) print(n) # 因为写了__repr__方法,所以输出的是Node(1),而不是内存地址准备工作:初始化方法 & 打印字符串方法 想要达到的输出效果类似于: NodeValue(1) --> NodeValue(3) --> NodeValue(4) --> END
class LinkedList: def __init__(self): self.head = None # 初始化头结点 self.tail = None # 初始化尾结点 self.size = 0 # 初始化链表长度 ## 打印链表 def __repr__(self): cursor = self.head string_repr = "" while cursor: # 以f开头,表示在字符串内支持大括号内的python表达式 string_repr += f"{cursor} --> " cursor = cursor.next return string_repr + "END"下面开始是实现方法的代码:
1. get(index) 传入索引,返回在该索引位置的结点
# 传入索引,返回在该索引位置的结点 def get(self, index): """ :param index: 索引,从左数从0开始,从右数从-1开始 """ # 将索引变为从左数开始数的正数索引 if index >= 0: leftindex = index else: leftindex = index + self.size # 返回节点 current = self.head for i in range(leftindex): current = current.next return current2. insert(index, data) 向链表中指定位置插入结点
def insert(self, index, data): # 将索引变为从左数开始数的正数索引 if index < 0: # leftindex最小值为1,最大值为self.size leftindex = self.size + index + 1 else: leftindex = index new_node = Node(data) if (index >= 0 and index > (self.size)) or (index < 0 and leftindex > self.size): # 如果传入的索引越界,报错 self.size -= 1 raise Exception("Index out of range") elif self.size == 0: # 如果当前是一个空链表 self.head = new_node self.tail = new_node self.size += 1 elif index == 0 or (index < 0 and leftindex == 1): # 用户想要在头部插入结点 new_node.next = self.head self.head = new_node self.size += 1 elif index == (self.size-1) or index == -1: # 用户想要在尾部插入结点 print("尾部插入") self.tail.next = new_node self.tail = new_node self.size += 1 else: # 用户想要在中间插入结点 if index >= 0: pre = self.get(index - 1) new_node.next = pre.next pre.next = new_node self.size += 1 else: pre = self.get(leftindex - 1) new_node.next = pre.next pre.next = new_node self.size += 13. remove(index, data) 删除链表中指定位置的结点
def remove(self, index): # 将索引变为从左数开始数的正数索引 if index < 0: # 这里的leftindex最小值为0,最大值为self.size # 和左数正数索引一致 leftindex = index + self.size else: leftindex = index if leftindex < 0 or leftindex >= self.size: # 如果传入的索引越界,报错 raise Exception("Index out of range") if leftindex == 0: # 用户想要删除头部结点 remove_node = self.head self.head = self.head.next elif leftindex == (self.size-1): # 用户想要删除尾部结点 pre = self.get(leftindex-1) remove_node = pre.next pre.next = None self.tail = pre else: # 用户想要中间的结点 pre = self.get(leftindex-1) remove_node = pre.next pre.next = pre.next.next self.size -= 1 return remove_node.data4. reverse() 反转链表
def reverse(self): if self.size == 0 or self.size == 1: return self else: current = self.head pre = None while current: # 储存当前结点的正序下一个结点 next_node = current.next # 让当前结点的下一个结点指向前一个结点 current.next = pre # 前结点后移 pre = current # 当前结点后移 current = next_node # 更改头结点 self.head = pre self.tail = next_node return self