目录
-
节点结构
- 表元素域elem
- 存放具体的数据
- 链接域next
- 存放下一个结点的位置(python中的标识)
- 表元素域elem
-
单链表
- 节点
- 头结点
- 尾节点
- 地址存放None
- 中间节点
- 变量p
- 指向链表的头节点的位置,从p出发能找到表中的任意节点
-
操作
- 增
- add(item) 链表头部添加元素,O(1)
- append(item) 链表尾部添加元素,O(N)
- insert(pos, item) 指定位置添加元素,O(N)
- 删
- remove(item) 删除指定元素,O(N)
- pop()删除最后一个元素,O(N)
- delete(pos)删除指定位置的元素,O(N)
- clear()清空链表,O(1)
- 查
- is_empty() 链表是否为空,O(1)
- length() 链表长度,O(N)
- travel() 遍历整个链表,O(N)
- search(item) 查找指定元素首次出现的位置,O(N)
- search_index(pos)查找指定位置的节点,O(N)
- 增
-
单链表和列表对比
- 节点
-
双链表
-
操作
- 增
- add(item) 链表头部添加元素,O(1)
- append(item) 链表尾部添加元素,O(N)
- insert(pos, item) 指定位置添加元素,O(N)
- 删
- remove(item) 删除指定元素,O(N)
- pop()删除最后一个元素,O(N)
- delete(pos)删除指定位置的元素,O(N)
- clear()清空链表,O(1)
- 查
- is_empty() 链表是否为空,O(1)
- length() 链表长度,O(N)
- travel() 遍历整个链表,O(N)
- search(item) 查找指定元素首次出现的位置,O(N)
- search_index(pos)查找指定位置的节点,O(N)
- 增
-
-
单向循环链表
-
操作
- 增
- add(item) 链表头部添加元素,O(N)
- append(item) 链表尾部添加元素,O(N)
- insert(pos, item) 指定位置添加元素,O(N)
- 删
- remove(item) 删除指定元素,O(N)
- pop()删除最后一个元素,O(N)
- delete(pos)删除指定位置的元素,O(N)
- clear()清空链表,O(1)
- 查
- is_empty() 链表是否为空,O(1)
- length() 链表长度,O(N)
- travel() 遍历整个链表,O(N)
- search(item) 查找指定元素首次出现的位置,O(N)
- search_index(pos)查找指定位置的节点,O(N)
- 增
-
-
链表操作对比
-
增
-
删
-
改查
-
总结
-
列表和链表对比
- 列表的O(1)操作更多,链表只有单链表的add为O(1),其余全为O(N)
-
链表对比
- 不同点
- 1、循环不同
- 1、循环条件不同,普通链表判空,循环链表判是否为头节点
- 2、循环结束后结点指向不同,普通指向空,循环指向尾节点
- 3、循环结束后,普通不同单独处理尾节点,循环需要单独处理尾节点
- 2、链表的操作,只有头增法不一致。普通链表为O(1),循环链表为O(N)
- 1、循环不同
- 相同点
- 除头增法以外的所有操作,时间复杂度均为O(N)
- 不同点
-
-
-
python实现
-
单链表
-
-
class SingleNode(object): # 元组也可以实现节点的构造(elem, next) """单链表的节点""" def __init__(self, elem): self.elem = elem self.next = None class SingleLinkList(object): def __init__(self, node=None): """初始化链表""" self.__head = node # 变量p,指向链表头结点的位置 def is_empty(self): """判空""" return self.__head is None def length(self): """计算长度""" cur = self.__head # 游标,记录当前节点,用于遍历节点 count = 0 # 用于计数 while cur is not None: count += 1 cur = cur.next return count def travel(self): """遍历""" cur = self.__head # 游标,记录当前节点,用于遍历节点 while cur is not None: print(cur.elem, end=' ') cur = cur.next print('\n') def search(self, item): """查找指定元素的首次出现的位置""" cur = self.__head # 游标,记录当前节点,用于遍历节点 i = 0 while cur is not None: if cur.elem == item: print(f"元素{item}的位置为{i}") return i cur = cur.next i += 1 print("没找到指定元素") def search_index(self, pos): """查找指定位置的元素""" lent = self.length() if self.is_empty() or pos < 0 or pos >= lent: # 如果指定位置超过链表长度,添加失败 print("查找失败,不在链表指定范围内,查找范围为:0-%d" % (lent-1)) else: print("第%d位的元素为:" % pos, end='') cur = self.__head while cur is not None and pos != 0: pos -= 1 cur = cur.next print(cur.elem) def add(self, item): """链表头部添加元素""" node = SingleNode(item) if self.is_empty(): self.__head = node else: node.next = self.__head self.__head = node def append(self, item): """链表尾部添加元素""" node = SingleNode(item) if self.is_empty(): self.__head = node else: cur = self.__head # 游标,记录当前节点,用于遍历节点 while cur.next is not None: cur = cur.next cur.next = node def insert(self, item, pos): """指定位置添加元素""" node = SingleNode(item) cur = self.__head lent = self.length() if pos < 0 or pos > lent: # 如果指定位置超过链表长度,添加失败 print("添加失败") elif pos <= 0: self.add(item) elif pos >= lent: self.append(item) else: for i in range(pos-1): cur = cur.next node.next = cur.next cur.next = node def delete(self, pos): """删除指定位置的节点""" lent = self.length() if self.is_empty() or pos < 0 or pos >= lent: print("删除失败") return if lent <= 1: self.__head = None else: if pos >= lent-1: # 删除尾节点 self.pop() elif pos <= 0: # 删除首节点 self.__head = self.__head.next else: aft = self.__head cur = self.__head pre = self.__head while aft is not None and pos != -1: pos -= 1 pre = cur cur = aft aft = aft.next pre.next = aft def pop(self): """删除最后一个节点""" cur = self.__head pre = self.__head while cur.next is not None: pre = cur cur = cur.next pre.next = None def remove(self, item): """删除首次出现的指定节点""" pos = self.search(item) self.delete(pos) def clear(self): """清空链表""" self.__head = None sll = SingleLinkList() sll.append(1) sll.append(2) sll.append(3) sll.append(4) sll.append(5) sll.add(6) sll.insert(7, 3) sll.travel() sll.search_index(5) sll.search(5) sll.pop() sll.travel() sll.delete(2) sll.travel() sll.remove(7) sll.travel() sll.clear()
双链表
-
class Node(object): def __init__(self, item=0, next=None, prev=None): self.elem = item self.next = next self.prev = prev class DoubleLinkList(object): def __init__(self, node=None): self.__head = node def is_empty(self): """判空""" return self.__head is None def length(self): """计算长度""" cur = self.__head # 游标,记录当前节点,用于遍历节点 count = 0 # 用于计数 while cur is not None: count += 1 cur = cur.next return count def travel(self): """遍历""" cur = self.__head # 游标,记录当前节点,用于遍历节点 while cur is not None: print(cur.elem, end=' ') cur = cur.next print('\n') def add(self, item): node = Node(item) node.next = self.__head self.__head.prev = node self.__head = node def append(self, item): """链表尾部添加元素""" node = Node(item) if self.is_empty(): self.__head = node else: cur = self.__head # 游标,记录当前节点,用于遍历节点 while cur.next is not None: cur = cur.next cur.next = node node.prev = cur def insert(self, item, pos): """指定位置添加元素""" node = Node(item) cur = self.__head lent = self.length() if pos < 0 or pos > lent: # 如果指定位置超过链表长度,添加失败 print("添加失败") elif pos <= 0: self.add(item) elif pos >= lent: self.append(item) else: for i in range(pos-1): # 找到指定位置的前一个节点 cur = cur.next node.next = cur.next node.prev = cur cur.next.prev = node cur.next = node def delete(self, pos): """删除指定位置的节点""" lent = self.length() if self.is_empty() or pos < 0 or pos >= lent: print("删除失败") return if lent <= 1: self.__head = None else: if pos <= 0: # 删除首节点 self.__head = self.__head.next self.__head.prev = None elif pos >= lent-1: # 删除尾节点 self.pop() else: cur = self.__head for i in range(pos): # 找到指定位置的节点 cur = cur.next aft = cur.next pre = cur.prev aft.prev = pre pre.next = aft def pop(self): """删除最后一个节点""" cur = self.__head while cur.next is not None: cur = cur.next cur.prev.next = None def clear(self): """清空链表""" self.__head = None sll = DoubleLinkList() sll.append(1) sll.append(2) sll.append(3) sll.append(4) sll.append(5) sll.add(6) sll.insert(7, 3) sll.travel() sll.pop() sll.travel() sll.delete(2) sll.travel() sll.clear()
单向循环链表
-
class Node(object): # 元组也可以实现节点的构造(elem, next) """单链表的节点""" def __init__(self, elem): self.elem = elem self.next = None class SingleCycleLinkList(object): def __init__(self, node=None): """初始化链表""" self.__head = node # 变量p,指向链表头结点的位置 if node: node.next = node def is_empty(self): """判空""" return self.__head is None def length(self): """计算长度""" if self.is_empty(): return 0 cur = self.__head # 游标,记录当前节点,用于遍历节点 count = 1 # 用于计数 !!!!!和单链表不同,count从1开始计数 while cur.next != self.__head: count += 1 cur = cur.next return count def travel(self): """遍历""" if self.is_empty(): return cur = self.__head # 游标,记录当前节点,用于遍历节点 while cur.next != self.__head: print(cur.elem, end=',') cur = cur.next print(cur.elem) # cur指向尾节点,但是未进入循环,因此需要另外打印 def search(self, item): """查找指定元素的首次出现的位置""" if self.is_empty(): return -1 cur = self.__head # 游标,记录当前节点,用于遍历节点 i = 0 while cur.next != self.__head: if cur.elem == item: print(f"元素{item}的位置为{i}") return i cur = cur.next i += 1 # 由于cur指向尾节点之后,无法进入循环,因此需要单独判断尾节点 if cur.elem == item: print(f"元素{item}的位置为{i}") else: print("没找到指定元素") def search_index(self, pos): """查找指定位置的元素""" lent = self.length() if self.is_empty() or pos < 0 or pos >= lent: # 如果指定位置超过链表长度,添加失败 print("查找失败,不在链表指定范围内,查找范围为:0-%d" % (lent-1)) else: print("第%d位的元素为:" % pos, end='') cur = self.__head while cur.next != self.__head and pos != 0: pos -= 1 cur = cur.next print(cur.elem) def add(self, item): """链表头部添加元素""" node = Node(item) if self.is_empty(): self.__head = node node.next = node else: # 先找到尾节点 cur = self.__head while cur.next != self.__head: cur = cur.next # 循环结束,cur指向尾节点 cur.next = node node.next = self.__head self.__head = node def append(self, item): """链表尾部添加元素""" node = Node(item) if self.is_empty(): self.__head = node node.next = node else: cur = self.__head # 游标,记录当前节点,用于遍历节点 while cur.next != self.__head: cur = cur.next cur.next = node node.next = self.__head def insert(self, item, pos): """指定位置添加元素""" node = Node(item) cur = self.__head lent = self.length() if pos < 0 or pos > lent: # 如果指定位置超过链表长度,添加失败 print("添加失败") return if pos <= 0: self.add(item) elif pos >= lent: self.append(item) else: for i in range(pos-1): cur = cur.next node.next = cur.next cur.next = node def delete(self, pos): """删除指定位置的节点""" lent = self.length() if self.is_empty() or pos < 0 or pos >= lent: print("删除失败") return if lent <= 1: self.__head = None else: if pos >= lent-1: # 删除尾节点 self.pop() elif pos <= 0: # 删除首节点 self.del_init() else: # 删除中间节点 aft = self.__head cur = self.__head pre = self.__head while aft.next != self.__head and pos != -1: pos -= 1 pre = cur cur = aft aft = aft.next pre.next = aft def del_init(self): cur = self.__head while cur.next != self.__head: cur = cur.next cur.next = self.__head.next self.__head = self.__head.next def pop(self): """删除最后一个节点""" cur = self.__head pre = self.__head while cur.next != self.__head: # *** # pre = cur cur = cur.next pre.next = self.__head # *** # def remove(self, item): """删除首次出现的指定节点""" pos = self.search(item) self.delete(pos) def clear(self): """清空链表""" self.__head = None sll = SingleCycleLinkList() sll.append(1) sll.append(2) sll.append(3) sll.append(4) sll.append(5) sll.add(6) sll.insert(7, 3) sll.travel() sll.search_index(5) sll.search(5) sll.pop() sll.travel() sll.delete(2) sll.travel() sll.remove(7) sll.travel() sll.clear()