數據結構和算法-列表

隊列和棧相反python

  • 隊列: 先進先出(FIFO)
  • 棧: 後進先出(LIFO)

類型

  • 循環隊列
    • Disruptor高性能隊列
  • 併發隊列(線程安全)
  • 阻塞隊列

順序隊列

使用python的list結構來模擬, 在右端插入的話時間複雜度是O(n), 在左端彈出的話是O(1)算法

方式一: 每次出隊操做都要移動數組

# coding:utf-8

"""
使用列表模擬單端隊列

左出右進
"""


class Queue(object):
    """
    使用列表模擬實現單端隊列
    """

    def __init__(self):
        self.items = []

    def isEmpty(self):
        return self.items == []

    def size(self):
        return len(self.items)

    def enqueue(self, item):
        self.items.append(item)

    def dequeue(self):
        """
        每次出隊全部元素都會向前移動
        :return:
        """
        if self.isEmpty():
            raise Exception("empty queue")
        res = self.items.pop(0)
        return res

方式二

定義兩個指針head和tail, 每次出隊時不用再移動全部元素, 只有當入隊時若是tail指針在最尾部, 檢測數組是否還有空間數組

  • 若是還有空間, 移動全部元素後再添加
  • 若是沒有空間, 返回錯誤
# coding:utf-8


class Queue(object):
    """
    隊列

    使用固定數組的形式, 優勢是出隊操做不用再每次都移動數組

    只有當入隊操做的時候, 若是數組內還有空餘位置, 可是tail已經在最尾部了, 此時須要進行數據搬移

    """

    def __init__(self, length):
        self.items = [0 for _ in range(length)]
        self.head = 0
        self.tail = 0
        self.length = length

    def size(self):
        return self.tail - self.head

    def enqueue(self, item):
        if self.tail >= self.length:
            if self.head == 0:
                raise Exception("Full")
            # 進行數據搬移
            for i in range(self.head, self.tail):
                self.items[i - self.head] = self.items[i]
            # 移動完畢後從新更新head和tail
            self.tail = self.tail - self.head
            self.head = 0

        self.items[self.tail] = item
        self.tail += 1

    def dequeue(self):
        if self.head >= self.tail:
            raise Exception("Empty")
        data = self.items[self.head]
        self.head += 1
        return data


if __name__ == "__main__":
    q = Queue(10)
    for i in range(10):
        q.enqueue(i)

    print(q.dequeue())
    print(q.dequeue())

    q.enqueue(11)
    q.enqueue(12)

    res = []
    while True:
        try:
            res.append(q.dequeue())
        except Exception as e:
            print(e)
            break
    print(res)


"""
0
1
Empty
[2, 3, 4, 5, 6, 7, 8, 9, 11, 12]
"""

鏈式隊列

# coding:utf-8

"""
基於鏈表實現的複雜度
"""


class Node(object):
    def __init__(self, data, next_=None):
        self.data = data
        self.next_ = next_


class Queue(object):
    def __init__(self):
        self.head = None
        self.tail = None
        self.length = 0

    def size(self):
        return self.length

    def enqueue(self, item):
        if self.head == None:
            self.head = Node(item)
            self.tail = self.head
        else:
            self.tail.next_ = Node(item)
            self.tail = self.tail.next_
        self.length += 1

    def dequeue(self):
        if self.head == None:
            raise Exception("Empty")
        data = self.head.data
        self.head = self.head.next_
        self.length -= 1
        return data


if __name__ == "__main__":
    q = Queue()
    for i in range(10):
        q.enqueue(i)

    res = []
    while True:
        try:
            res.append(q.dequeue())
        except Exception as e:
            print(e)
            break
    print(res)

循環隊列

模擬隊列是一個環, 一樣須要定義head和tail指針, 該類型隊列能夠避免移動元素的操做,
如判斷循環隊列是否已滿的條件是(tail + 1) % n = head安全

# coding:utf-8

"""
循環隊列
"""


class QueueLoop(object):
    def __init__(self, length):
        self.items = [0 for _ in range(length)]
        self.head = 0
        self.tail = 0
        self.length = length + 1    # 循環隊列會多用一位, 由於當tail指向最後一個空位置時認爲已經滿了

    def enqueue(self, item):
        if self.is_full():
            raise Exception("Full")
        self.items[self.tail] = item
        self.tail += 1

    def dequeue(self):
        if self.is_empty():
            raise Exception("Empty")
        data = self.items[self.head]
        self.head = self.head + 1
        return data

    def is_empty(self):
        if self.head == self.tail:
            return True
        else:
            return False

    def is_full(self):
        """
        當tail指向head的前一位的時候認爲隊列已滿
        :return: 
        """
        if (self.tail + 1) % self.length == self.head:
            return True
        else:
            return False



if __name__ == "__main__":
    q = QueueLoop(10)

    for i in range(10):
        q.enqueue(i)

    res = []
    while True:
        try:
            res.append(q.dequeue())
        except Exception as e:
            print(e)
            break
    print(res)


"""
Empty
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

"""
    
"""
Empty
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

"""

資料

  • < <大話數據結構> >-程傑
  • 數據結構和算法之美-王爭
相關文章
相關標籤/搜索