日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

数据结构之优先队列:最小索引优先队列,Python代码实现——15

發(fā)布時(shí)間:2024/7/5 python 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构之优先队列:最小索引优先队列,Python代码实现——15 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

最小索引優(yōu)先隊(duì)列(Min index priority queue)

在之前實(shí)現(xiàn)的最大優(yōu)先隊(duì)列和最小優(yōu)先隊(duì)列,他們可以分別快速訪問(wèn)到隊(duì)列中最大元索和最小元素,但是他們有一 個(gè)缺點(diǎn),就是沒(méi)有辦法通過(guò)索引訪問(wèn)已存在于優(yōu)先隊(duì)列中的對(duì)象,并更新它們。

為了實(shí)現(xiàn)這個(gè)目的,在優(yōu)先隊(duì)列的基礎(chǔ)上,學(xué)習(xí)一種新的數(shù)據(jù)結(jié)構(gòu),索引優(yōu)先隊(duì)列。

接下來(lái)我們以最小索引優(yōu)先隊(duì)列舉列,最大優(yōu)先索引隊(duì)列,有興趣可以自行實(shí)現(xiàn)。

實(shí)現(xiàn)思路

實(shí)現(xiàn)功能的三個(gè)重要數(shù)組

  • 數(shù)組items,儲(chǔ)存無(wú)序插入的元素的數(shù)組
  • 數(shù)組pq,假設(shè)將items儲(chǔ)存的元素進(jìn)行從小到大排序,并且items對(duì)應(yīng)的原索引依舊保持不變,而pq儲(chǔ)存的元素就是items排序過(guò)后元素的原索引(參照下圖可更好地理解)
  • 數(shù)組qp,qp的元素對(duì)應(yīng)pq中的索引, qp的索引對(duì)應(yīng)pq中的元素(也就對(duì)應(yīng)著未排序的items中的元素,與items元素的索引保持一致)
    這樣刪除時(shí)只需要根據(jù)傳入的索引在qp中尋找對(duì)應(yīng)的元素就可以跟快地找到了
  • 實(shí)現(xiàn)的操作方法

  • size()獲取隊(duì)列的大小
  • is_empty()判斷隊(duì)列是否為空
  • less(x, y)對(duì)傳入的兩個(gè)索引對(duì)應(yīng)當(dāng)前隊(duì)列的元素進(jìn)行大小比較
  • swap(i, j)對(duì)傳入的兩個(gè)索引對(duì)應(yīng)當(dāng)前隊(duì)列中的元素進(jìn)行值交換
  • min_elem_index()獲取最小元素的索引
  • is_index_exist()判斷索引在當(dāng)前隊(duì)列中是否對(duì)應(yīng)一個(gè)元素
  • insert(index, item)指定索引index處插入一個(gè)元素item
  • delete_min_elem()刪除最小元素,并返回最小元素插入隊(duì)列時(shí)的索引
  • change_item(idx, itm)指定索引idx處,將該處元素替換為itm
  • swim()上浮排序操作,同之前堆的排序中介紹
  • sink()下沉排序操作,同之前堆的排序中介紹
  • Python代碼實(shí)現(xiàn)

    import operatorclass IndexMinPriorityQueue:def __init__(self, length):self.items = [None for _ in range(length)]# Ascendingly sort items and memorize the item's relative index in itemsself.pq = [None] + [i if self.items[i] else None for i in range(len(self.items))]# Its index is associate with elements in pq, and also syncs with indices of list itemsself.qp = [i if self.pq[i] else None for i in range(len(self.pq))]self.N = 0def size(self):return self.Ndef is_empty(self):return self.N == 0def less(self, i, j):"""Compare the given two items in self.items"""return operator.lt(self.items[self.pq[i]], self.items[self.pq[j]])def swap(self, i, j):"""But change the position of the two items in the subsidiary pq and qp lists"""self.pq[i], self.pq[j] = self.pq[j], self.pq[i]self.qp[self.pq[i]], self.qp[self.pq[j]] = i, jdef min_elem_index(self):"""Find the minimum element's index"""return self.pq[1]def is_index_exist(self, index):"""Judge if the given index is exist in this queue"""return self.qp[index] is not Nonedef insert(self, index, item):"""Insert an element associated with the element's index in this queue"""if self.is_index_exist(index):returnself.items[index] = itemself.N += 1# Now it isn't a orderly queueself.pq[self.N] = indexself.qp[index] = self.N# swim the last element to make list pq orderedself.swim(self.N)def delete_min_elem(self):"""Delete the minimum element, and return its index"""min_index = self.pq[1]# print(f"min_ele: {self.items[min_index]}")self.swap(1, self.N)self.pq[self.N] = Noneself.qp[min_index] = Noneself.items[min_index] = Noneself.N -= 1self.sink(1)return min_indexdef change_item(self, idx, itm):"""Substitute a item which index=idx with a new item which value=itm"""self.items[idx] = itmk = self.qp[idx]self.sink(k)self.swim(k)def swim(self, index):"""Move the smaller element up; We should only change order in pq and qp"""while index > 1:# Compare the current node with its parent node, if smaller, swim upif self.less(index, int(index/2)): # Compare values in itemsself.swap(index, int(index/2)) # But swap the mapping position in pq and qpindex = int(index/2)def sink(self, index):"""Move the bigger element down; We should only change order in pq and qp"""# print(f"SINK: idx:{index} N:{self.N}")while 2*index <= self.N:index_smaller = 2*index if 2*index+1 > self.N else \(2*index if self.less(2*index, 2*index+1) else 2*index+1)# print(f"index_smaller: {index_smaller}")# print(f"index: {index}")if self.less(index, index_smaller):breakself.swap(index, index_smaller)index = index_smaller

    測(cè)試代碼

    if __name__ == '__main__':IMPQ = IndexMinPriorityQueue(10)IMPQ.insert(0, 'C')IMPQ.insert(1, 'E')IMPQ.insert(2, 'A')print(f"After three insert list items now is: {IMPQ.items}")# print(f"pq: {IMPQ.pq}")# print(f"qp: {IMPQ.qp}")# print(f"min_elem_index: {IMPQ.min_elem_index()}")index, item = 0, 'B'IMPQ.change_item(0, 'B')print(f"Changed the item in index[{index}] to {item}, items now is {IMPQ.items}")index, item = 0, 'V'IMPQ.change_item(0, 'V')print(f"Changed the item in index[{index}] to {item}, items now is {IMPQ.items}")while not IMPQ.is_empty():res = IMPQ.delete_min_elem()print(f"Pop the minimum element: {res}")print(f"After delete all elements , its size: {IMPQ.size()}")print(IMPQ.is_index_exist(0))

    測(cè)試結(jié)果

    After three insert list items now is: ['C', 'E', 'A', None, None, None, None, None, None, None] Changed the item in index[0] to B, items now is ['B', 'E', 'A', None, None, None, None, None, None, None] Changed the item in index[0] to V, items now is ['V', 'E', 'A', None, None, None, None, None, None, None] Pop the minimum element: 2 Pop the minimum element: 1 Pop the minimum element: 0 After delete all elements , its size: 0 False

    這里為了測(cè)試結(jié)果直觀,直接將數(shù)組items拿出來(lái)了,注意items中的元素是不會(huì)改變位置的,實(shí)際改變的是用來(lái)定位items中元素的pq和qp數(shù)組

    總結(jié)

    以上是生活随笔為你收集整理的数据结构之优先队列:最小索引优先队列,Python代码实现——15的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。