链表: 常用于经常添加或删除节点
一、单链表
单链表:从两点出发,节点、链表;每个节点具有两个属性:val和next
1、设计链表并实现以下功能:
''' 设计单链表, 链表的节点包含两个属性:val和next, ''' class Node(object): # 节点 def __init__(self, val): self.val = val # 使用参数值来初始化一个节点 self.next = None class MyLinkedList(object): # 链表 def __init__(self): """ 初始化链表 """ self.head = Node(0) # 初始化一个数据为0的空节点作为头部, 本身不算节点 self.size = 0 # 整个链表的长度初始化为0 def get(self, index: int) -> int: """ 获取链表中第index个节点的值,如果无该索引则返回-1 """ if index < 0 or index >= self.size: return -1 cur = self.head for i in range(index+1): # 获取第index个节点 cur = cur.next return(cur.val) def addAtHead(self, val: int) -> None: """ 在链表的第一个元素之前添加一个值为val的节点,插入后,新节点将成为链表的第一个节点 """ head = self.head cur = Node(val) # 初始化新节点 cur.next = head.next head.next = cur self.size += 1 # self.addAtIndex(0, val) #可直接调用函数addAtIndex def addAtTail(self, val: int) -> None: """ 将值为val的节点追加到链表的末尾 """ prev = self.head for i in range(self.size): # 获取最后一个节点 prev = prev.next cur = Node(val) # 初始化新节点 cur.next = prev.next prev.next = cur self.size += 1 # self.addAtIndex(self.size, val) def addAtIndex(self, index: int, val: int): """ 在链表的第index个节点之前添加值为val的节点, 如果index=size,则该节点附加到链表的末尾;如果index>size,则不插入; 如果index<0,则在头部插入 """ if index < 0: index = 0 prev = self.head for i in range(index): prev = prev.next cur = Node(val) cur.next = prev.next prev.next = cur self.size += 1 def deleteAtIndex(self, index: int) -> None: """ 如果索引有效,则删除链表中的第index个节点 """ if index < self.size: prev = self.head for i in range(index): prev = prev.next prev.next = prev.next.next # list = MyLinkedList() # print(MyLinkedList) # print(list.addAtHead(1)) # print(list.addAtTail(3)) # print(list.addAtIndex(1, 2)) # print(list.get(1)) # print(list.deleteAtIndex(1)) # print(list.get(1))
2、环形链表(双指针)
# 判断链表中是否有环 # 1、使用快慢指针,如果快指针循环赶上了慢指针,则代表链表中有环 # 2、使用哈希表,哈希表中不允许有重复元素(若链表有环,则有重复节点) class Solution: # 使用快慢指针判断链表是否有环 def hasCycle_fs(self, head: Node) -> bool: # head:Node(初始化head节点) fast = head slow = head while fast and slow and fast.next: # 需判断若链表为空/下一个节点为None(while fast and None )或只有一个节点的情况(while fast.next) fast = fast.next.next slow = slow.next if fast.val == slow.val: return True return False def hascycle_set(self,head: Node) -> bool: # 使用哈希表 s1 = set() s1.add(head) cur = head while cur and cur.next: cur = cur.next if cur.next in s1: return True s1.add(cur) return False
3、反转链表:可使用迭代的方法,也可使用栈实现
# 反转链表, 使用next记录链表的下一个节点并迭代链表的节点, 将当前节点插入返回的链表的头部
class Node(object): # 节点
def __init__(self, val):
self.val = val # 使用参数值来初始化一个节点
self.next = None
class Solution(): def reverseList(self, head: Node) -> Node: head_ret = Node(None) cur = head while cur: next = cur.next # 将next指向下个节点 cur.next = head_ret.next # 将当前节点插入head_ret链表头部的后面(返回时不返回定义的头部) head_ret.next = cur cur = next # 迭代当前链表的节点(知道当前节点为空) return head_ret.next l1 = Node(1) l2 =Node(2) l3 =Node(3) l1.next = l2 l2.next = l3 l3.next = None m = Solution() head = m.reverseList(l1) print(head.val) print(head.next.val) print(head.next.next.val)
二、双链表
class double_Node: def __init__(self, val=0): self.val = val self.next = None self.prev = None class double_linklist: def __init__(self): self.size = 0 self.head, self.tail = double_Node(), double_Node()# 给该链表初始化一个虚拟头节点, 该头节点不作数,因此size = 0 self.head.next = self.tail self.tail.prev = self.head def get(self, index: int) -> int: """ 获取链表中的index个节点的值,如果索引无效,则返回-1 """ if index >= self.size or index < 0: return -1 cur = self.head for i in range(index + 1): cur = cur.next return cur.val def addAtHead(self, val: int) -> None: self.addAtIndex(0, val) def addAtTail(self, val: int) -> None: self.addAtIndex(self.size, val) def addAtIndex(self, index: int, val: int) -> None: """ 在链表中的第index个节点之前添加值为val的节点,如果index>size, 则不插入,如果index<0,则在头部插入 """ if index < 0: index = 0 pred = self.head for i in range(index): pred = pred.next cur = double_Node(val) next = pred.next cur.next = next cur.prev = pred next.prev = cur pred.next = cur self.size+=1 def deleteAtIndex(self, index: int) -> None: """ 若索引有效,删除链表中第index个节点 """ pred = self.head if index >= 0 and index < self.size: for i in range(index): pred = pred.next next=pred.next.next pred.next = next next.prev = pred self.size -= 1