簡體   English   中英

使用std :: collections :: BinaryHeap進行就地堆排序

[英]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 為了以某種方式保護您免受恐慌,實際的實現可能會有些復雜。 我不知道。 如果沒有,那么您應該避免使用它。

編輯:我正在談論的板條箱是take_mut 甚至有一個RFC可以在std::mem添加類似的內容。

我在創建一個可以在參考上工作並且可以就地完成的工作時遇到了麻煩

BinaryHeap 建立在Vec之上 Vec創建新堆時,必須賦予它完全所有權。 然后,它將確保向量處於良好狀態以充當堆。

由於BinaryHeap並非基於&mut Vec (大多數情況下具有人體工程學),因此您不能這樣做。

目前尚不清楚為什么不對向量使用slice::sort

文檔指出“將向量轉換為二進制堆可以就地完成”

需要澄清的是,文檔是正確的- 不需要額外的內存分配 ,因此就位。 重要的方面是BinaryHeap 擁有其數據,並且不會向內部公開所有內部信息。

您要提供的功能是能夠在用戶提供的rebuild上調用rebuild 對我來說,這很有用,但是您始終可以提交RFC來公開它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM