python單連結串列

morra發表於2017-03-14
#!/usr/bin/env python3
# -*- coding:utf-8 -*-


class LNode:
    """
    結點類
    """

    def __init__(self, elem, next_=None):
        self.elem = elem
        self.next = next_


class LinkedListUnderflow(ValueError):
    """
    自定義異常
    """
    pass


class LList:
    """
    連結串列類
    """

    def __init__(self):
        self._head = None

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

    # 操作pop刪除表頭結點並返回這個結點裡的資料
    def pop(self):
        if self._head is None:
            raise LinkedListUnderflow("in pop")
        e = self._head.elem
        self._head = self._head.next
        return e

    # 在表頭插入元素
    def prepend(self, elem):
        self._head = LNode(elem, self._head)

    # 在連結串列最後插入元素
    def append(self, elem):
        if self._head is None:
            self._head = LNode(elem)
            return None
        # 如果連結串列為空則直接把表頭指向需要插入的元素即可在。實際上是在操作_head域

        p = self._head
        while p.next is not None:
            p = p.next
        p.next = LNode(elem)
        # 如果不為空,則先從頭掃描連結串列,找到最後的結點,然後把最後結點的next指向需要插入的元素即可。實際上是在操作next域

    # 刪除最後一個結點
    def pop_last(self):
        if self._head is None:  # 空表
            raise LinkedListUnderflow("in pop_last")
        p = self._head
        if p.next is None:  # 如果表長為1,則清空之,並返回原來的元素
            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
        return e
        # 如果表長大於1,則從頭掃描,找到倒數第二個結點,把倒數第二個結點的next域置空,並返回最後一個結點

    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

    def elements(self):  # 寫一個生成器,使連結串列支援for操作
        p = self._head
        while p is not None:
            yield p.elem
            p = p.next


class LList1(LList):  # 派生一個變形單連結串列類
    def __init__(self):
        LList.__init__(self)
        self._rear = None

    def prepend(self, elem):  # 重構prepend方法
        if self._rear 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_last")
        p = self._head
        if p.next is None:
            self._head = None
            return p.elem
        while p.next.next is not None:
            p = p.next
        e = p.next.elem
        p.next = None
        self._rear = p
        return e


相關文章