双链表的每个节点都有两个指针域,分别指向它的前一个节点和后一个节点,因此在双链表中插入和删除节点要考虑到这两个指针域的变动。也正是由于双链表节点的双向引用特点,使得在链表尾部插入和删除节点的操作性能得到了改善。

双链表的节点删除

本文实现的双链表结构如下图所示,即带有尾节点引用域的双链表结构。

 

class DLNode: #双链表节点类
    def __init__(self,elem,prev=None,next=None):
        self.elem = elem
        self.prev = prev
        self.next=next

#自定义异常,在链表为空时访问元素抛出
class LinkListUnderflow(ValueError):
    pass


#双链表类(带链表尾部引用域)
class DLList: 
    def __init__(self):
        self._head=None    #链表头部引用域
        self._rear=None    #链表尾部引用域

    #判断是否为空表
    def is_empty(self):
        return self._rear is None

    #表头插入数据
    def prepend(self,elem):
        p=DLNode(elem)
        if self._head is None:  #空表
            self._rear=p
        else:
            p.next=self._head
            self._head.prev=p
        self._head=p

    # 在表尾插入数据
    def append(self,elem):
        p = DLNode(elem)
        if self._head is None:  #空表
            self._head=p
        else:
            p.prev= self._rear
            self._rear.next = p
        self._rear = p

    #删除表头节点
    def pop(self):
        if self._head is None:
            raise LinkListUnderflow("in pop")
        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 LinkListUnderflow("in pop_last")
        e = self._rear.elem
        self._rear=self._rear.prev
        if self._rear is not None:
            self._rear.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:
                print("->", end="")
            p = p.next
        print()

#测试部分
if __name__ == '__main__':
    dllist=DLList()

    # dllist.pop()

    for i in range(10):
        dllist.append(i)
    dllist.printall()

    dllist.pop()
    dllist.printall()

    e=dllist.pop_last()
    dllist.printall()

    dllist.prepend(e)
    dllist.printall()

输出结果为:

0->1->2->3->4->5->6->7->8->9
1->2->3->4->5->6->7->8->9
1->2->3->4->5->6->7->8
9->1->2->3->4->5->6->7->8

更多推荐