数据结构 | 链接表
节点类
class LNode: def __init__(self,elems,next_=None): self.elem = elems self.next = next_
注意:节点是一个二元组,所以初始化时,要将数据域和链接域写上。链接域,默认为None。
定义异常类
class LinkedListUnderFlow(ValueError): pass
一、单链表
class LList: def __init__(self): self._head = None def is_empty(self): return self._head == None def length(self): p,n =self._head,0 while p is not None: n += 1 p = p.next return n def prepend(self,elem): self._head = LNode(elem,self._head) def pop(self): if self._head is not None: raise LinkedListUnderFlow("in pop") e = self._head.elem self._head = self._head.next return e def append(self,elem): if self._head is None: self._head = LNode(elem,None) return p = self._head while p.next is not None: p = p.next p.next = LNode(elem,None) def pop_last(self): if self._head is None: raise LinkedListUnderFlow("in pop_last") p = self._head while p.next.next is not None: p = p.next e = p.next.elem p.next = None return e def printall(self): p = self._head while p is not None: print(p.elem,end="," if p.next is not None else "") p = p.next print("") def for_each(self): p = self._head while p is not None: print(p.elem) p = p.next def filter(self,pred): p = self._head while p is not None: if pred(p.elem): yield p.elem p = p.next
二、含尾结点的单链表
class LList1(LList): def __init__(self): LList.__init__(self) self._rear = None def prepend(self,elem): if self._head is None: self._head = LNode(elem,self._head) self._rear = self._head else: self._head = LNode(elem, self._head) def append(self,elem): if self._head is None: self._head = LNode(elem,self._head) self._rear = self._head else: self._rear.next = LNode(elem,None) # None 可以不写 self._rear = self._rear.next def pop_last(self): if self._head is None: raise LinkedListUnderFlow("in pop_last") p = self._head if p.next is None: e = p.elem self._head = None return e while p.next.next is not None: p = p.next e = p.next.elem p.next = None self._rear = p return e
mlist1 = LList1() mlist1.prepend(99) for i in range(11,20): mlist1.append(i) mlist1.printall() for x in mlist1.filter(lambda y:y%2 == 0): print(x)
''' 99,11,12,13,14,15,16,17,18,19 12 14 16 18 '''
三、循环单链表 ******
class LCList: def __init__(self): self._rear = None def is_empty(self): return self._rear == None def prepend(self,elem): p = LNode(elem) if self._rear is None: # 空节点 p.next = p self._rear = p else: p.next = self._rear.next self._rear.next = p def append(self,elem): self.prepend(elem) self._rear = self._rear.next def pop(self): if self.is_empty(): raise LinkedListUnderFlow("in pop_last") p = self._rear.next if self._rear is p: # 单节点 self._rear = None else: self._rear.next = p.next return p.elem def printall(self): if self.is_empty(): return p = self._rear.next while True: print(p.elem) if p is self._rear: break p = p.next
四、双链表
先定义双链表的节点类
class DNode(LNode): def __init__(self,elem,next_=None,prev=None): LNode.__init__(self,elem,next_) self.prev = prev
class DLList(LList1): def __init__(self): LList1.__init__(self) def prepend(self,elem): p = DNode(elem,None,self._head) if self._head is None: self._rear = p else: p.next.prev = p self._head = p def append(self,elem): p = DNode(elem,self._rear,None) if self._head is None: self._head = p else: p.prev.next = p self.rear = p def pop(self): if self._head is None: raise LinkedListUnderFlow("in pop of DLList") e = self._head.elem self._head = self._head.next if self._head is not None: self._head.prev = None return e def pop_last(self): if self._head is None: raise LinkedListUnderFlow("in pop of DLList") e = self.rear.elem self.rear = self.rear.next if self.rear is None: self.head = None else: self.rear.next = None return e
五、两个链表的操作
1. 单链表反转
class LList: def __init__(self): self._head = None def reverse(self): p = None while self._head is not None: q = self._head self._head = q.next q.next = p p = q self._head = p mlist = LList() for i in range(10): mlist.prepend(i) for i in range(11,20): mlist.append(i) mlist.printall() mlist.reverse() mlist.printall() ''' 9,8,7,6,5,4,3,2,1,0,11,12,13,14,15,16,17,18,19 19,18,17,16,15,14,13,12,11,0,1,2,3,4,5,6,7,8,9 '''
2. 链表反转
采用插入排序的方法
- 先看一下顺序表排序
def list_sort(lst): for i in range(1,len(lst)): x = lst[i] j = i while j>0 and lst[j-1]>x: lst[j] = lst[j-1] j -= 1 lst[j] = x return lst lst = [2,3,1,5,4,0] print(list_sort(lst)) ''' [0, 1, 2, 3, 4, 5] '''
- 基于移动元素的单链表排序算法
class LList: def __init__(self): self._head = None def sort1(self): if self.is_empty(): return crt = self._head.next while crt is not None: x = crt.elem p = self._head # 从head开始扫描 while p is not crt and p.elem<x: p = p.next while p is not crt: y = p.elem p.elem = x x = y p = p.next # 通过后移,while循环实现正确位置之后的排序 crt.elem = x crt = crt.next mlist = LList() for i in range(5): mlist.prepend(i) mlist.sort1() mlist.printall()
- 通过调整链接的方式实现插入排序

浙公网安备 33010602011771号