雙向循環鏈表的實現

其實雙向循環鏈表與單鏈表的區別在於每個節點的結構發生了改變,具體的說是,每個節點多了一個指針域,用於指向上一個節點。其他的如鏈表對象就不需要進行改變了。
新的節點類:

class LNode:
    def __init__(self, elem=0, prev=None, next_=None):
        self.prev = prev
        self.elem = elem
        self.next = next_

實現代碼大同小異:

# 節點對象
class LNode:
    def __init__(self, elem=0, prev=None, next_=None):
        self.prev = prev
        self.elem = elem
        self.next = next_ # 加個下劃線,爲了區分python中的next關鍵字

class listObj:
    def __init__(self):
        self.rear = None
        self.nodenum = 0

# 接下來是一個鏈表類的實現(意思是:支持鏈表的一些特定的操作)
class LinkedListUndeflow(ValueError):
    pass

# 我們要知道,對於雙鏈表的循環結構,我們要做的就是
# 將鏈表的第一個節點的prev域指向表尾,鏈表的最後一個域的nex域指向表首

class LList:
    # 建立一個空表
    def __init__(self):
        self.kerear = listObj()
        self.head = None
        # 初始化一個鏈表對象,該鏈表對象存儲有鏈表的節點數和鏈表第一個節點的引用
        # head就是一個鏈表實例的屬性
    # 判斷鏈表是不是空,直接判斷鏈表的表頭是不是空就行了
    def isEmpty(self):
        return self.head is None

    # 接下來就是對元素的添加
    def prepend(self, elem): # 表頭插入
        if not self.head:
            self.head = LNode(elem, self.kerear.rear, self.head)
            self.kerear.rear = self.head
            # 建立一個循環,
        else:
            self.head = LNode(elem, self.kerear.rear, self.head)
        self.kerear.nodenum += 1

    def append(self, elem):
        if not self.head:
            self.head = LNode(elem, self.kerear.rear, self.head)
            self.kerear.rear = self.head
        else:
            self.kerear.rear.next = LNode(elem, self.kerear.rear, self.head)
            self.kerear.rear = self.kerear.rear.next
        self.kerear.nodenum += 1


    def popfirst(self): # 表頭刪除,要求返回刪除元素
        if not self.head:
            raise LinkedListUndeflow("空表不可刪除")
        e = self.head.elem
        self.head.next.prev = self.kerear.rear
        self.head = self.head.next
        self.kerear.nodenum -= 1
        return e

    def poplast(self): # 表尾刪除
        if not self.head:
            raise LinkedListUndeflow("空表不可刪除")
        if not self.head.next:
            e = self.head.elem
            self.head = self.kerear.rear
            self.kerear.nodenum = 0
            return e
        # 如果是有兩個及以上的元素,那麼將倒數第二個元素的next指向None就可以了
        # 所以要緊的是找到倒數第二個元素
        e = self.kerear.rear.elem
        self.kerear.rear.prev.next = self.head
        self.kerear.rear = self.kerear.rear.prev
        self.kerear.nodenum -= 1
        return e
    def printall(self):
        # 這個遍歷從頭開始遍歷的
        # 是一個空鏈表,一個元素的鏈表,多個元素的鏈表
        p = self.head
        while p:
            print(p.elem, end = '')
            print(',', end = '')
            if p.next == self.head:
                break
            p = p.next
        print("\n")
    #
    # def element(self):
    #     p = self.kerear.head
    #     while p:
    #         yield p.elem
    #         p = p.next
    #     # 利用生成器函數,生成一個迭代器(python中進行便利的工具)

mlist1 = LList() # 一個空的鏈表對象
print(mlist1.isEmpty())
for i in range(10):
    # 從首部加入是個元素
    mlist1.prepend(i)
print(mlist1.kerear.nodenum, "節點數", sep='--')
mlist1.printall()
# 看看首部加入是否成功
for i in range(10, 20):
    mlist1.append(i)
print(mlist1.kerear.nodenum, "節點數", sep='--')
mlist1.printall()
# 看看尾部加入是否成功

print(mlist1.popfirst(),"首部刪除返回的", sep = '--')
print(mlist1.kerear.nodenum, "節點數", sep='--')
mlist1.printall()
# 看看首部刪除是否成功

print(mlist1.poplast(), "尾部刪除節點", sep='--')
print(mlist1.kerear.nodenum, "節點數", sep='--')
mlist1.printall()
# 看看尾部刪除是否成功

# for i in mlist1.element():
#     print(i)




下一章會對鏈表進行一些總結。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章