1. 程式人生 > >Python3 連結串列、佇列和棧的實現

Python3 連結串列、佇列和棧的實現

# -!- coding: utf-8 -!-
# !/usr/bin/env python 3.6.3
# author: Vivian
# time: 2018/9/16

# 使用list列表構造棧
class Stack(object):
    def __init__(self):
        # 設定私有變數,不允許修改
        self.__list = []
        # 設定棧的容量
        self.capacity = 5
        # 設定當前棧的元素數量
        self.number = 0

    def push(self, item):
        if self.number < self.capacity:
            self.__list.append(item)
            self.number += 1
        else:
            print("stack is overflow")
            # self.__list.insert(0,item)#規定從前面還是後面新增元素,如果是陣列,則在列表的尾部新增和刪除

    def pop(self):
        if self.number > 0:
            self.number -= 1
            return self.__list.pop()
        else:
            print("stack is empty")  # 這裡print之後,因為函式沒有返回值,預設再列印一個None
            # self.__list.pop(0)#規定從列表的前面還是後面新增元素,如果是單鏈表,則在連結串列的頭部新增和刪除

    def peek(self):
        if self.__list:
            return self.__list[-1]  # 空列表不支援-1下標的查詢
        else:
            return None

    def is_empty(self):
        return self.__list == []  # 是if else 的簡寫形式
        # return not self.__list

    def size(self):
        return len(self.__list)
        # return self.number()


if __name__ == "__main__":
    s = Stack()
    s.push(1)
    s.push(2)
    # s.pop()
    print(s.pop())
    print(s.pop())
    print(s.pop())


# 使用list列表構造佇列
class Queue(object):
    def __init__(self):
        self.array = []

    def enqueue(self, element):
        self.array.append(element)

    def dequeue(self):
        # e=self.array[0]
        # del self.array[0]
        # return e
        return self.array.pop(0)


if __name__ == "__main__":
    q = Queue()
    q.enqueue('a')
    q.enqueue('b')
    print(q.dequeue())
    print(q.dequeue())


class Node(object):
    # 例項化之前都會呼叫的函式
    def __init__(self, element=0):
        self.element = element
        self.next = None

    def log_stack(self, node):
        while node.next is not None:
            print("node", node.element)
            node = node.next


if __name__ == "__main__":
    n = Node()
    n1 = Node(1)
    n2 = Node(2)
    n3 = Node(3)
    n4 = Node(4)
    n1.next = n
    n2.next = n1
    n3.next = n2
    n4.next = n3
    n4.log_stack(n4)


# 單鏈表實現棧
class classicstack(Node):
    def __init__(self):
        self.head = Node()

    def push(self, element):
        # 例項化一個node例項
        n = Node(element)
        n.next = self.head.next
        # 將head拉向新來的
        self.head.next = n

    def pop(self):
        e = self.head.next
        if self.head.next is not None:
            self.head.next = self.head.next.next
            return e.element
        else:
            print("stack is empty")

    # 如果該節點沒有被其他節點的next指向,可以預設被刪除
    # 如果是連結串列儲存的棧,則用pop直接刪除
    def log_stack(self):
        hh = self.head.next
        while hh is not None:
            print("node", hh.element)
            hh = hh.next


if __name__ == "__main__":
    cs = classicstack()
    cs.push('a')
    cs.push('b')
    cs.push('c')
    cs.log_stack()
    print(cs.pop())
    print(cs.pop())
    print(cs.pop())


# 單鏈表(注意插入的時候和刪除的時候對最後一個位置元素和頭一個元素的處理(相當於鏈棧)
class singlelinklist(object):
    def __init__(self):
        self.head = Node()
        self.tail = Node()
        self.number = 0

    def is_empty(self):
        return self.head.next == None

    def add_head(self, item):
        node = Node(item)
        if self.head.next == None:
            self.head.next = node
            self.tail.next = node
        else:
            node.next = self.head.next
            self.head.next = node

    def append_tail(self, item):
        node = Node(item)  # 注意傳入的資料,不是節點
        if self.tail.next == None:
            self.tail.next = node
            self.head.next = node
        else:
            self.tail.next.next = node
            self.tail.next = node

    def insert(self, pos, item):  # 在給定位置pos插入節點
        '''

        :param pos:指定位置新增元素,從1開始計數
        :param item:
        :return:
        '''
        node = Node(item)
        if pos <= 1:
            node.next = self.head.next
            self.head.next = node  # 或者直接使用add_head
        elif pos <= self.length():
            cur = self.head
            for i in range(self.length()):
                p = cur
                q = p.next
                cur = cur.next
            node.next = q
            p.next = node
        else:
            self.tail.next.next = node

    def length(self):
        cur = self.head
        cur.next = self.head.next
        number = 0
        while cur.next is not None:
            number += 1
            cur = cur.next
        return number

    def travel(self):
        cur = self.head
        number = 0
        list = []
        while cur.next is not None:
            number += 1
            print(cur.next.element, end=' ')
            list.append(cur.next.element)
            cur = cur.next
        return list

    def remove(self, item):  # 去掉給定值的節點
        cur = self.head
        if cur.next == None:
            print("single link list is empty")
        elif cur.next.element == item:
            self.head = cur.next
            return

        else:
            while cur.next.next is not None:
                p = cur.next
                q = p.next
                if q.element == item:
                    p.next = q.next
                    break
                else:
                    cur = cur.next
        if cur.next.element == item:  # 最後一個元素要單獨判斷是否刪除
            cur.next.next = None

    def search(self, item):
        cur = self.head
        while cur.next is not None:
            if cur.next.element == item:
                return True
            else:
                cur = cur.next
        return False


if __name__ == "__main__":
    s = singlelinklist()
    print(s.is_empty())
    s.add_head(1)
    s.add_head(2)
    s.add_head(3)
    s.append_tail(1)
    s.append_tail(2)
    s.insert(5, 20)
    print(s.length())
    s.insert(100, 9)

    print("search", s.search(80))
    print("遍歷", s.travel())
    s.remove(3)
    print("遍歷", s.travel())

    s.remove(2)

    print("遍歷", s.travel())

    print("計數", s.length())

class singlelinklist(object):
    #單向迴圈列表
    def __init__(self):
        self.head=Node()
        self.head.next=self.head
    def is_empty(self):
        return self.head.next==None

    def length(self):
        number=0
        cur=self.head
        if self.head.next==self.head:
            return number
        elif self.head.next.next==self.head.next:
            return number+1
        else:
            while cur.next.next is not self.head.next:
                number+=1
                cur=cur.next
            return number+1
    def travel(self):
        cur=self.head
        str=''
        if self.head.next==self.head:
            return str
        elif self.head.next.next==self.head.next:
            print(self.head.next.element)
        else:
            while cur.next.next is not self.head.next:
                print(cur.next.element,end=' ')
            print(cur.next.element,end=' ')

    def add_head(self,item):
        node=Node(item)
        if self.head.next==self.head:
            node.next=self.head.next
            self.head.next=node
        elif self.head.next.next==self.head.next:
            node.next=self.head.next
            self.head.next.next=node
            self.head.next=node
        else:
            node.next=self.head.next

            cur=self.head
            while cur.next.next is not self.head.next:
                cur=cur.next
            cur.next=node
            self.head.next = node