不能使用for迴圈遍歷Queue

2021-10-18 15:12:58 字數 2085 閱讀 9310

昨天有個朋友問我一道演算法題,給出了他和答案的兩個版本,這道題我看過,並查集問題,左看右看就是沒發現它有問題,於是進行debug,發現資料讀取沒有問題,於是繼續判斷合併是否有誤,發現也沒有問題,最後發現他使用的priorityqueue他使用的for迴圈進行遍歷,好傢伙,我當場好傢伙!

public

static

void

main

(string[

] args)

}

上面的程式有不少人會以為輸出的結果為1 2 3 5 6 7 8 9,但是實際上呢,輸出結果為:1 2 3 5 8 6 9 7

原因的話,學過堆排序的朋友就應該知道,在priorityqueue中實際上內部是維持著一棵二叉排序樹,利用堆排序的規則實現的,具體的可以看priorityqueue的原始碼,實際上樹是一種虛擬出來的資料結構,底層都是基於陣列實現的。只是對於左右節點的訪問採用了不同的下標規則。

當我們使用for迴圈直接遍歷priorityqueue的時候,此時是直接將底層的陣列直接遍歷出來了,但問題是佇列是排序佇列,資料是排序資料,但陣列並非排序陣列,所以使用priorityqueue的時候需要使用add()、poll()等方法新增或者移除元素,這些方法在內部都會去維持二叉樹的有序性,所以通過迭代器的方式可以獲取到具體的排序數值。

堆排序

// 左孩子:2*i + 1

// 右孩子:2*i + 2

// 乙個節點的父節點: (i-1)/2

public

static

void

heapsort

(int

nums)

int size = nums.length;

// 由於是大根堆,最大的數肯定是在第乙個

// 交換第乙個數

swap

(nums,0,

--size)

;// 大根堆的環境被破壞了,此時需要調整

while

(size >0)

}private

static

void

heapify

(int

nums,

int index,

int size)

// 否則進行乙個調整,進行乙個交換

swap

(nums, largest, index)

; index = largest;

// 將index移動到這個最大值的地方,因為不能確保下面的值是否還有比自己大的

left =

2* index +1;

// 利用新的index重新計算左孩子的座標}}

private

static

void

heapinsert

(int

nums,

int index)

}public

static

void

swap

(int

nums,

int a,

int b)

這個for迴圈遍歷queue的問題就到這裡了,自己也花了點時間去看**的bug,有些小的問題自己可能很難發現,因為**寫出來確實是符合一切的邏輯。有些時候邏輯正確,**正確,但寫**的方式錯誤了,也會引發不小的問題。

keep thinking, keep coding! 2023年2月1日13:09:39寫於九江,加油!

pdfcrop不能使用

最近,用到了pdfcrop,用來去除pdf中空白的邊。但是使用pdfcrop margins 0 pdf 後,給出了錯誤 error pdfcrop cannot call ghostscript 但是我已經安裝了ctex,裡面已經包含ghostscript,所以就不知道什麼錯誤。在網上針對這個問題...

CGRect CGFloat 不能使用

筆者還在照著別人 敲東西的階段 汗顏哪 言歸正傳,今天敲 的時候發現只要是繼承nsobject的類 都不能使用cgrect cgfloat 會報 unknown type name cgrect did you mean rect or unknown type name cgfloat 糾結了一下...

oracle 不能使用for update

select from table name for update 造成oracle資料庫卡死 1 首先查詢出問題表的session id select session id from v locked object l join dba objects o on l.object id o.obj...