[英]In-place heapsort using std::collections::BinaryHeap
我想在Rust中創建一個就地堆排序函數。 在標准庫中,我發現std::collections::BinaryHeap
看起來很有希望。 我可以使用它來創建一個使用其參數的函數:
use std::collections::BinaryHeap;
fn heapsort<T: Ord>(list: Vec<T>) -> Vec<T> {
let heap = BinaryHeap::from(list);
heap.into_sorted_vec()
}
文檔指出,“可以將向量轉換為二進制堆可以就地完成”,但是我在創建一個可以在引用上工作並且可以就地進行處理的堆時遇到了麻煩( heapsort<T: Ord>(list: &mut Vec<T>)
)。 我可以僅使用std::collections::BinaryHeap
來實現它嗎?
您可以使用mem::replace
從&mut
引用后面“移動”某些內容:
use std::collections::BinaryHeap;
use std::mem;
fn heapsort<T: Ord>(list: &mut Vec<T>) {
let tmp = mem::replace(list, Vec::new());
let heap = BinaryHeap::from(tmp);
*list = heap.into_sorted_vec();
}
因此,在短時間內*list
等於一個空向量。 在這種情況下可以,因為創建和刪除空Vec
非常便宜。
IIRC甚至有一個板條箱,可以按值借用一些*mutref
,而無需在借用時就地使用虛擬值。 但是我現在找不到。 它看起來像這樣:
fn heapsort<T: Ord>(list: &mut Vec<T>) {
borrow_by_value(list, |tmp| {
BinaryHeap::from(tmp).into_sorted_vec()
});
}
其中borrow_by_value
使用一些不安全的代碼(可能是ptr::read
)為您提供按值分配的Vec
,並將帶有一些更不安全的代碼(可能是ptr::write
)的Vec
返回到*list
。 為了以某種方式保護您免受恐慌,實際的實現可能會有些復雜。 我不知道。 如果沒有,那么您應該避免使用它。
我在創建一個可以在參考上工作並且可以就地完成的工作時遇到了麻煩
BinaryHeap
建立在Vec
之上 。 從Vec
創建新堆時,必須賦予它完全所有權。 然后,它將確保向量處於良好狀態以充當堆。
由於BinaryHeap
並非基於&mut Vec
(大多數情況下具有人體工程學),因此您不能這樣做。
目前尚不清楚為什么不對向量使用slice::sort
。
文檔指出“將向量轉換為二進制堆可以就地完成”
需要澄清的是,文檔是正確的- 不需要額外的內存分配 ,因此就位。 重要的方面是BinaryHeap
擁有其數據,並且不會向內部公開所有內部信息。
您要提供的功能是能夠在用戶提供的rebuild
上調用rebuild
。 對我來說,這很有用,但是您始終可以提交RFC來公開它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.