昨天有個朋友問我一道演算法題,給出了他和答案的兩個版本,這道題我看過,並查集問題,左看右看就是沒發現它有問題,於是進行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...