python-链表

单向链表
单向链表最简单的实现形式就是由多个节点的集合共同构成一个线性序列。每个节点存储一个对象的引用,这个引用指向序列中的一个元素,即存储指向列表中的下一个节点
链表的第一个节点和最后一个结点分别为列表的头节点和尾节点

实现单向链表的代码如下


class Node:#节点
    def __init__(self,elem):
        self.elem=elem
        self.next=None #初始下一节点为空
class SingleLinkList:
    #单链表
    def __init__(self,node=None):#初始化链表
        self._head=node
    def is_empty(self):#判断链表是否为空
        return self._head==None
    def length(self):
        cur=self._head
        count=0
        while cur!=None:
            count+=1
            cur=cur.next
        return count
    def travel(self):#遍历整个链表
        cur=self._head
        while cur!=None:
            print(cur.elem,end=' ')
            cur=cur.next
        print('\n')
    def add(self,item):#向链表头部添加元素
        node=Node(item)
        node.next=self._head
        self._head=node
    def append(self,item):#向链表尾部添加元素
        node=Node(item)
        if self.is_empty():
            self._head=node
        else:
            cur = self._head
            while cur.next!=None:
                  cur=cur.next
            cur.next=node
    def insert(self,pos,item):#指定位置插入元素
        if pos<=0 or pos>self.length()+1:
            return False
        else:
            node=Node(item)
            if pos==1:
                node.next=self._head
                self._head=node
            else:
                j=1
                cur=self._head
                while j<pos-1:
                    j+=1
                    cur=cur.next
                node.next=cur.next
                cur.next=node
            return True
    def remove(self,item):
            cur=self._head
            pre=None
            flag=1
            while cur!=None and flag:
                if cur.elem==item:
                    if cur==self._head:
                        self._head=cur.next
                    else:
                        pre.next=cur.next
                    flag=0
                else:
                    pre=cur
                    cur=cur.next
    def search(self,item):
        #查找结点是否存在
        cur=self._head
        while cur!=None:
            if cur.elem==item:
                return True
            cur=cur.next
        return False
L=SingleLinkList()

用单链表实现栈
用单链表实现栈首先需要决定用链表的头部或尾部来实现栈顶。最好的选择是在头部,因为只有在头部我们才能在一个常数时间内有效地插入和删除元素由于所有操作都会影响栈顶,因此规定栈顶在链表的头部

class Empty:
    pass
class LinkedStack:
  class _Node:
    def __init__(self,element,next):
        self._element=element
        self._next=next
  def __init__(self):
      self._head=None
      self._size=0
  def __len__(self):
      return self._size
  def is_empty(self):
      return self._size==0
  def push(self,e):
      self._head=self._Node(e,self._head)
      self._size+=1
  def top(self):
      if self.is_empty():
          raise Empty('Stack is Empty')
      return self._head._element
  def pop(self):
      if self.is_empty():
          raise Empty('Stack is Empty')
      e=self._head._element
      self._head=self._head._next
      self._size-=1
      return e
  def travel(self):
      cur=self._head
      while cur!=None:
          print(cur._element,end=' ')
          cur=cur._next
      print('\n')
LS=LinkedStack()
LS.push(5)
LS.push(4)
LS.push(3)
LS.travel()
print(LS.top())
print(LS.pop())
LS.travel()

用单向链表实现队列
由于需要对队列的两端执行操作,我们显示地为每个队列维护一个_head和一个_tail指针作为实例变量,将队列的前端和链表的头部对应,队列的后端与链表的尾部对应

class Empty:
    pass
class LinkedQueue:
    class _Node:
        def __init__(self,element,next):
            self._element=element
            self._next=next
    def __init__(self):
        self._head=None
        self._tail=None
        self._size=0
    def __len__(self):
        return self._size
    def is_empty(self):
        return self._size==0
    def first(self):
        if self.is_empty()==True:
            raise Empty('Queue is Empty')
        return self._head._element
    def dequeue(self):
        if self.is_empty():
            raise Empty('Queue is Empty')
        e=self._head._element
        self._head=self._head._next
        self._size-=1
        if self.is_empty():
            self._tail=None
        return e
    def enqueue(self,e):
        node=self._Node(e,None)
        if self.is_empty():
            self._head=node
        else:
            self._tail._next=node
        self._tail=node
        self._size+=1
Q=LinkedQueue()
Q.enqueue(3)
Q.enqueue(4)
Q.enqueue(5)
print(Q.dequeue())
print(Q.dequeue())
print(Q.dequeue())

循环链表
在链表中,可以使链表的尾部节点的"next"指针指向链表的头部,我们称这种结构为循环链表

用循环链表实现队列
因为循环链表尾部的next指针是指向头部的,所以用循环链表实现队列时不需要_head变量 只设一个_tail变量即可

class Empty(Exception):
    pass
class CircularQueue:
    class _Node:
        def __init__(self,element,next):
            self._element=element
            self._next=next
    def __init__(self):
        self._tail=None
        self._size=0
    def __len__(self):
        return self._size
    def is_empty(self):
        return self._size==0
    def first(self):
        if self.is_empty():
            raise Empty('Queue is empty')
        head=self._tail._next
        return head._element
    def dequeue(self):
         if self.is_empty():
             raise Empty('Queue is empty')
         head=self._tail._next
         if self._size==1:
             self._tail=None
         else:
             self._tail._next=head._next
         self._size-=1
         return head._element
    def enqueue(self,e):
        node=self._Node(e,None)
        if self.is_empty():
            node._next=node
        else:
            node._next=self._tail._next
            self._tail._next=node
        self._tail=node
        self._size+=1
    def rotate(self):#现在的头节点变成尾节点
        if self._size>0:
            self._tail=self._tail._next
CQ=CircularQueue()
CQ.enqueue(3)
CQ.enqueue(4)
CQ.enqueue(5)
print(CQ.dequeue())
print(CQ.dequeue())
print(CQ.dequeue())

双向链表
如果一个链表的每个节点都维护了指向其先驱节点以及后继节点的引用 这样的结构被称为双向链表 引入prev 引用其前驱节点
头哨兵和尾哨兵:
在操作接近一个双向链表的边界时,为了避免一些特殊情况,在链表的两端都追加节点 在列表的起始位置添加头节点,在列表的结尾位置添加尾节点 这些特定的节点被称为哨兵。这些节点中并不存储主序列的元素

当使用哨兵节点时,一个空链表需要初始化,使头节点的next 指向尾节点,并令尾节点的prev指向头节点

class Empty(Exception):
    pass
class DoublyLinkedBase:
    class _Node:
       def __init__(self,element,prev,next):
          self._element=element
          self._prev=prev
          self._next=next
    def __init__(self):
        self._header=self._Node(None,None,None)
        self._tailer=self._Node(None,None,None)
        self._header._next=self._tailer
        self._tailer._prev=self._header
        self._size=0
    def __len__(self):
        return self._size
    def is_empty(self):
        return self._size==0
    def _insert_between(self,e,predecessor,successor):
        newest=self._Node(e,predecessor,successor)
        predecessor._next=newest
        successor._prev=newest
        self.size+=1
        return newest
    def _delete_node(self,node):
        predecessor=node._prev
        successor=node._next
        predecessor._next=successor
        successor._prev=predecessor
        self._size-=1
        element=node._element
        node._prev=node._next=node._element=None
        return element

用双向链表实现双端队列

class Empty(Exception):
    pass
class _DoublyLinkedBase:
    class _Node:
       def __init__(self,element,prev,next):
          self._element=element
          self._prev=prev
          self._next=next
    def __init__(self):
        self._header=self._Node(None,None,None)
        self._tailer=self._Node(None,None,None)
        self._header._next=self._tailer
        self._tailer._prev=self._header
        self._size=0
    def __len__(self):
        return self._size
    def is_empty(self):
        return self._size==0
    def _insert_between(self,e,predecessor,successor):
        newest=self._Node(e,predecessor,successor)
        predecessor._next=newest
        successor._prev=newest
        self._size+=1
        return newest
    def _delete_node(self,node):
        predecessor=node._prev
        successor=node._next
        predecessor._next=successor
        successor._prev=predecessor
        self._size-=1
        element=node._element
        node._prev=node._next=node._element=None
        return element
class LinkedDeque(_DoublyLinkedBase):
    def first(self):
        if self.is_empty():
            raise Empty('Deque is empty')
        return self._header._next._element
    def last(self):
        if self.is_empty():
            raise Empty('Deque is empty')
        return self._tailer._prev._element
    def  insert_first(self,e):
        self._insert_between(e,self._header,self._header._next)
    def  insert_last(self,e):
        self._insert_between(e,self._tailer._prev,self._tailer)
    def delete_first(self):
        if self.is_empty():
            raise Empty('Deque is empty')
        return self._delete_node(self._header._next)
    def delete_last(self):
        if self.is_empty():
            raise Empty('Deque is empty')
        return self._delete_node(self._tailer._prev)
LD=LinkedDeque()
LD.insert_first(1)
LD.insert_first(2)
LD.insert_first(3)
LD.insert_first(4)
print(LD.delete_last())
print(LD.delete_first())

含位置信息的列表抽象数据类型

位置实例是一个简单的对象,只支持以下方法
p.element():返回存储在位置p的元素
在位置列表ADT中位置可以充当一些方法的参数或是作为其他方法的返回值。在描述位置列表的行为时,我们介绍如下列表L所支持的访问器方法:
L.first():返回L中第一个元素的位置。如果L为空,则返回None
L.last():返回L中最后一个元素的位置。如果L为空,则返回None
L.before§:返回L中p紧邻的前面元素的位置。如果p为第一个位置,则返回None
L.after§:返回L中p紧邻的后面元素的位置。如果p为最后一个位置,则返回None
L.is_empty():如果L列表不包含任何元素,返回True
Len(L):返回列表元素的个数
Iter(L):返回列表元素的前向迭代器
L.add_first(e)在L前面插入新元素e,返回新元素的位置
L.add_last(e)在L后面插入新元素e,返回新元素的位置
L.add_before(p,e)在L中位置p之前插入一个新元素e,返回新元素的位置
L.add_after(p,e)在L中位置p之后插入一个新元素e,返回新元素的位置
L.replace(p,e):用元素e取代位置p处的元素,返回之前p位置处的元素
L.delete§:删除并且返回L中位置p处的元素,取消该位置

用双向链表实现位置列表类PositionalList

class Empty(Exception):
    pass
class _DoublyLinkedBase:
    class _Node:
       def __init__(self,element,prev,next):
          self._element=element
          self._prev=prev
          self._next=next
    def __init__(self):
        self._header=self._Node(None,None,None)
        self._tailer=self._Node(None,None,None)
        self._header._next=self._tailer
        self._tailer._prev=self._header
        self._size=0
    def __len__(self):
        return self._size
    def is_empty(self):
        return self._size==0
    def _insert_between(self,e,predecessor,successor):
        newest=self._Node(e,predecessor,successor)
        predecessor._next=newest
        successor._prev=newest
        self.size+=1
        return newest
    def _delete_node(self,node):
        predecessor=node._prev
        successor=node._next
        predecessor._next=successor
        successor._prev=predecessor
        self._size-=1
        element=node._element
        node._prev=node._next=node._element=None
        return element
class PositionalList(_DoublyLinkedBase):
    class Position:
        def __init__(self,container,node):
            self._container=container
            self.node=node
        def element(self):
            return self._node._element
        def __eq__(self,other):
            return type(other) is type(self) and other._node is self._node
        def __ne__(self,other):
            return not (self==other)
    def _validate(self,p):
        if not isinstance(p,self.Position):
            raise TypeError('p must be proper Position type')
        if p._container is not self:
            raise ValueError('p does not belong to this container')
        if p._node._next is None:
            raise ValueError('p is no longer vaild')
        return p._node
    def _make_position(self,node):
        if node is self._header  or node is self._tailer:
            return None
        else:
            return self.Position(self,node)
    def first(self):
        return self._make_position(self._header._next)
    def last(self):
        return self._make_position(self._tailer._prev)
    def before(self,p):
        node=self._validate(p)
        return self._make_position(node._prev)
    def after(self,p):
        node=self._validate(p)
        return self._make_position(node._next)
    def __iter__(self):
        cursor=self.first()
        while cursor is not None:
            yield cursor.element()
            cursor=self.after(cursor)
    def _insert_between(self,e,predecessor,successor):
        node=super()._insert_between(e,predecessor,successor)
        return self._make_position(node)
    def add_first(self,e):
        return self._insert_between(e,self._header,self._header._next)
    def add_last(self,e):
        return self._insert_between(e,self._tailer._prev,self._tailer)
    def add_before(self,p,e):
        original=self._validate(p)
        return self._insert_between(e,original._prev,original)
    def add_after(self,p,e):
        original=self._validate(p)
        return self._insert_between(e,original,original._next)
    def delete(self,p):
        original=self._validate(p)
        return self._delete_node(original)
    def replace(self,p,e):
        original=self._validate(p)
        old_value=original._element
        original._element=e
        return old_value

位置列表的排序(直接插入排序)
def insertion_sort(L):#插入排序
    if len(L)>1:
        maker=L.first()
        while maker!=L.last():
            pivot=L.after(maker)
            value=pivot.element()
            if value>maker.element():
                maker=pivot
            else:
                walk=maker
                while walk!=L.first() and L.before(walk).element()>=value:
                    walk=L.before(walk)
                L.delete(pivot)
                L.add_before(walk,value)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值