链接表的变形

单链表的简单变形

为单链表添加一个尾节点,使尾端加入新元素的操作时间为 O(1)

class LList1(LList):  #继承自LList类,添加了一个新的域名来保存结尾的链接
    def __init__(self):
        LList.__init__(self)
        self._rear = None
#空表的每次操作都会涉及到_rear,尾端的变动操作也会涉及到_rear,_rear中保存的链接永远都是最后一个元素的链接。
    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)
            self._rear =self._rear.next

    def pop_last(self):
        if self._head is None:
            raise LinkedListUnderflow('in pop_list')
        p = self._head
        if p.next is None:
            e = p.elem
            self._head = None
            self._rear = 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

循环单链表

链表的最后一个元素的链接域保存第一个元素的链接,为一个环状结构,这种情况下链表对象指向尾元素更合适,可以在 O(1) 时间内查找到表头和表尾。

class LCList:
    def __init__(self):
        self._rear = None

    def is_empty(self):
        return self._rear is None

    def propend(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):  #和前端加入相同,区别在于_rear是否变动
        self.propend(elem)
        self._rear = self._rear.next

    def pop(self):  #前端删除
        if self._rear in None:
            raise LinkedListUnderflow("in pop of CLList")
        p = self._rear.next
        if self._rear.next 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:  #判断p为尾元素时结束
                break
            p = p.next

双链表

单链表每次删除元素都需要找到他之前的元素,不能同时支持首尾两端的操作都为 O(1) ,为每个节点再添加一个指向他前面的元素的链接,这样就得到了双链表,可以提高两边的高效操作。
双链表的节点中再添加一个引用域 prev 来保存上一个元素的链接。
link text
当删除一个元素 p 时,把他前后的元素的域链接好就行:

p.prev.next = p.next
p.next.prev = p.prev

当然得考虑一下前后无节点的情况。
当在元素m后加入一个元素 p <script type="math/tex" id="MathJax-Element-7">p</script>时:

m.next.prev = p
p.next = m.next
m.next = p
p.prev = m

双链表类

  • 节点类
class DLNode(LNode):
    def __init__(self, elem, prev=None, next_=None):
        LNode.__init__(self, elem, next_)
        self.prev = prev

class DLList(LList1):
    def __init__(self):
        LList1.__init__(self)

#is_empty,find,filter,printall都可以继承

    def prepend(self, elem):
        p = DLNode(elem, None, self._head)  #p作为首端元素插入时,next的值确定为self._head
        if self._head is None:
            self._head = p
            self._rear = p
        else:
            self._head.prev = p
            self._head = p

    def append(self, elem):
        p = DLNode(elem, self._rear, None)
        if self._head is None:
            self._head = p
            self._rear = p
        else:
            self._rear.next = p
            self._rear = p

#   def pop(self):
#       if self._head is None:
#           raise LinkedListUnderflow("in pop of DLList")
#       p = self._head
#       if p.next is None:             #拿到第一个元素
#           self._head = None          #改第二个元素的prev
#           self._rear = None          #改self._head
#       else:                          #分三种情况:空表,只有一个元素的表,含有多个元素的表
#           p.next.prev = None
#           self._head = p.next
#       return p.elem

    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_last of DLList")
#        p = self._rear
#        if p.prev is None:
#           self._head = None
#           self._rear = None
#       else:
#           p.prev.next = None
#           self._rear = p.prev
#       return p.elem

    def pop_last(self):
        if self._head is None:
           raise LinkedListUnderflow("in pop_last of DLList")
        e = self._rear.elem
        self._rear =self._rear.prev
        if self._rear is None:
            self._head = None
        else:
            self._rear.next =None
        return e
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值