zoukankan      html  css  js  c++  java
  • 堆排序 Rust实现

    堆排序

    堆是一个数组,可以看成一颗二叉树

    struct Heap(Vec<i32>);
    
    impl Heap {
        //父节点索引
        fn parent(i: usize) -> usize {
            i / 2
        }
        //左子节点索引
        fn left(i: usize) -> usize {
            2 * i
        }
        //右子节点索引
        fn right(i: usize) -> usize {
            2 * i + 1
        }
    }
    

    首先要能维护最大堆(排序通常用最大堆)

    思路就是找出该节点和两个子节点的最大节点
    如果该节点为最大,则结束,否则,先交换,然后继续判断子节点
    递归实现起来更简单
    具体实现如下

    impl Heap {
        fn heap_size(&self) -> usize {
            self.0.len()
        }
        fn max_heapify(&mut self, mut i: usize) {
            loop {
                let l = Heap::left(i);
                let r = Heap::right(i);
                let mut largest;
                if l <= self.heap_size() && self.0[l - 1] > self.0[i - 1] {
                    largest = l;
                } else {
                    largest = i;
                }
                if r <= self.heap_size() && self.0[r - 1] > self.0[largest - 1] {
                    largest = r;
                }
    
                if largest == i {
                    break;
                } else {
                    let tmp = self.0[i - 1];
                    self.0[i - 1] = self.0[largest - 1];
                    self.0[largest - 1] = tmp;
                }
                i = largest;
            }
        }
    }
    

    构建最大堆

    依次对每个节点都进行维护即可构建最大堆

    impl Heap {
        fn build_max_heap(&mut self) {
            for i in (1..self.heap_size() + 1).rev() {
                self.max_heapify(i);
            }
        }
    }
    

    堆排序

    1. 先构建一个最大堆
    2. 交换第一个和最后一个元素的值
    3. 缩小堆空间
    4. 对第一个节点进行堆维护
    impl Heap {
        fn heap_sort(&mut self) {
            let len = self.heap_size();
            self.build_max_heap();
            let mut v = Vec::with_capacity(self.heap_size());
            for i in (2..len + 1).rev() {
                let tmp = self.0[0];
                self.0[0] = self.0[i - 1];
                v.insert(0, tmp);
                let len = self.heap_size();
                self.0.truncate(len - 1);
                self.max_heapify(1);
            }
            self.0.append(&mut v);
        }
    }
    
    • 整个堆排序时间复杂度为O(nlgn)
    • 构建堆时间复杂度为O(n)
    • 每次维护堆为O(lgn), 总共调用n-1次
  • 相关阅读:
    在网页中实现flash全屏的几种方法
    flashdevelop生成的swf如何支持能打开本地文件
    getPreferredSize()、setPreferredSize()、getSize()、setSize()、revalidate()、pack()
    Flash字体嵌入方法
    NOPI 基本读写
    调整图片的透明度,以及把透明背景改为其他颜色的方法
    查看表空间大小
    浅谈电子商务b2c商城中的用户体验
    使用方法的返回值进行注入
    有关nginx upstream的五种分配方式
  • 原文地址:https://www.cnblogs.com/kwebi/p/9615805.html
Copyright © 2011-2022 走看看