數據結構與算法(八):順序隊列、棧式隊列

和棧一樣,隊列也是一種操作受限的線性表,其操作滿足“先進先出”規則。

 今天使用Python分別實現順序隊列、棧式隊列。

一、順序鏈表

規則:

  • 使用數組/列表存儲,包括頭尾指針;
  • 入隊時尾部指針後移,出隊時頭部指針後移;
  • 尾部指針到達數組長度且頭部指針不在首地址,則需數據搬移。

廢話少說,直接上碼:

class SequentialQueue(object):
    """順序隊列:
        使用數組/列表存儲,包括頭尾指針;
        入隊時尾部指針後移,出隊時頭部指針後移;
        尾部指針到達數組長度且頭部指針不在首地址,則需數據搬移。
    """
    def __init__(self, max_length = 100):
        self._q = []
        self._max_length = max_length
        self._head = 0
        self._tail = 0
        
    def enqueue(self, x):
        # 如果隊滿則入隊失敗
        if self._tail - self._head == self._max_length:
            return False
        # 如果隊列未滿,且尾指針不在最大長度上,則直接入隊
        if self._tail != self._max_length:
            self._q.append(x)
            self._tail += 1
        # 否則,先進行隊列搬移,將隊中元素移動到以隊首開始的隊列,再進行入隊
        else:
            self._q = self._q[self._head:]
            self._q.append(x)
            self._tail = self._tail - self._head + 1
            self._head = 0
        return True
    
    def dequeue(self):
        # 如果隊首指針小於隊尾指針,則出隊,否則返回空。
        if self._head < self._tail:
            ret = self._q[self._head]
            self._head += 1
            return ret
        else:
            return None
    
    def __repr__(self) -> str:
        values = []
        for i in range(self._head, self._tail):
            values.append(self._q[i])
        
        return "->".join(str(value) for value in values)
    
if __name__ == "__main__":
    q = SequentialQueue(max_length=5)
    for i in range(6):
        if q.enqueue(i):
            print("%d入隊後:"%i,q)
        else:
            print('%d入隊失敗!'%i)

    print("-----------------------------")
    for i in range(7):
        ret = q.dequeue()
        if ret is not None:
            print("%d出隊後:"%(ret),q)
        else:
            print("第%d次出隊,出隊失敗!"%(i+1))

測試結果:

二、棧式隊列

規則:

理論上,棧式隊列可以無限入隊,因此這裏不做長度限制;

出隊則需要判斷是否隊空;

廢話少說,直接上碼:

class Node(object):
    def __init__(self, data, _next=None):
        self.data = data
        self._next = _next
    
class ChainQueue(object):
    def __init__(self):
        node = Node(None)
        self._head = node
        self._tail = node
    def enqueue(self,x):
        if not isinstance(x,Node):
            x = Node(x)
        self._tail._next = x
        self._tail = x
        return True

    def dequeue(self):
        
        if self._head != self._tail:
            ret = self._head._next.data
            self._head = self._head._next
            return ret
        else:
            return None

    def __repr__(self) -> str:
        values = []
        current = self._head._next
        while current:
            values.append(current.data)
            current = current._next
        return "->".join(str(value) for value in values)

        
if __name__ == "__main__":
    q = ChainQueue()
    for i in range(9):
        q.enqueue(i)
        print("%d入隊後:"%i, q)

    for i in range(10):
        ret = q.dequeue()
        if ret is not None:
            print("%d出隊後:"%(ret),q)
        else:
            print("第%d次出隊,出隊失敗!"%(i))

測試結果:

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