繁体   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