文档章节

HeapSort -- 堆排序

gackey
 gackey
发布于 2017/09/07 21:08
字数 745
阅读 4
收藏 0

精选30+云产品,助力企业轻松上云!>>>

堆是一个顺序存储的完全二叉树。

对于n个元素的序列{R1, R2, , Rn}。当前元素为的话,

它的左子节点是 ;

它的右子节点是 ;

它的父节点是 。

其中每个结点的关键字都不大于其孩子结点的关键字,这样的堆称为小根堆。()

其中每个结点的关键字都不小于其孩子结点的关键字,这样的堆称为大根堆。()

/*
 * 堆排序利用了大根堆(或小根堆)堆顶记录的关键字最大(或最小)这一特征, 使得在当前无序区中选取最大(或最小)关键字的记录变得简单。
 * (1)用大根堆排序的基本思想 ① 先将初始文件R[1..n]建成一个大根堆,此堆为初始的无序区 ②
 * 再将关键字最大的记录R[1](即堆顶)和无序区的最后一个 记录R[n]交换,由此得到新的无序区R[1..n-1]和有序区R[n],
 * 且满足R[1..n-1].keys≤R[n].key ③由于交换后新的根R[1]可能违反堆性质,故应将当前无序区R[1..n-1]调整为堆。
 * 然后再次将R[1..n-1]中关键字最大的记录R[1]和该区间的最后一个记录R[n-1]交换,
 * 由此得到新的无序区R[1..n-2]和有序区R[n-1..n],
 * 且仍满足关系R[1..n-2].keys≤R[n-1..n].keys,同样要将R[1..n-2]调整为堆。 直到无序区只有一个元素为止。
 * (2)大根堆排序算法的基本操作: ① 初始化操作:将R[1..n]构造为初始堆; ②
 * 每一趟排序的基本操作:将当前无序区的堆顶记录R[1]和该区间的最后一个记录交换, 然后将新的无序区调整为堆(亦称重建堆)。
 */

public class HeapSort {

    public static void sort(int[] data) {
        MaxHeap h = new MaxHeap();
        h.init(data);
        for (int i = 0; i < data.length; i++)
            h.remove();
        System.arraycopy(h.queue, 1, data, 0, data.length);
    }

    private static class MaxHeap {

        private int size = 0;

        private int[] queue;

        // 构造初始大根堆
        void init(int[] data) {
            this.queue = new int[data.length + 1];
            for (int i = 0; i < data.length; i++) {
                queue[++size] = data[i];
                fixUp(size);
            }
        }

        public int get() {
            return queue[1];

        }

        public void remove() {
            MaxHeap.swap(queue, 1, size--);
            fixDown(1);
        }

        // 重构大根堆
        private void fixDown(int k) {
            int j;
            while ((j = k << 1) <= size) {
                if (j < size && queue[j] < queue[j + 1])
                    j++;
                if (queue[k] > queue[j]) // 不用交换

                    break;
                MaxHeap.swap(queue, j, k);
                k = j;
            }
        }

        // 找出最大值
        private void fixUp(int k) {
            while (k > 1) {
                int j = k >> 1;
                if (queue[j] > queue[k])
                    break;
                MaxHeap.swap(queue, j, k);

                k = j;
            }
        }

        public static void swap(int[] data, int i, int j) {
            int temp = data[i];
            data[i] = data[j];
            data[j] = temp;
        }
    }
}

 

gackey

gackey

粉丝 4
博文 78
码字总数 35022
作品 0
昌平
程序员
私信 提问
加载中
请先登录后再评论。
图解堆排序

一、引言二、图解堆排序(heapsort)三、java代码实现及时间复杂度分析四、总结 一、引言 优先队列可以用于以O(NlogN)时间排序,正如上一篇的求解topK问题中用到的思想一样,这种思想就是堆排...

9龙
2019/04/27
0
0
堆排序 求高手解答

堆排序求解,为什么结果不是1,2,3,。。。顺序的 代码如下: /* 堆排序(大顶堆) */ #include #include using namespace std; void HeapAdjust(int *a,int i,int size) //调整堆 { int lchild...

hjhomw
2015/07/16
503
2
java语言实现堆排序

1.堆 堆,其实是一个完全二叉树,分为大顶堆和小顶堆。 大顶堆:每个节点的值都大于或者等于其左右子节点的值 小顶堆:每个节点的值都小于或者等于其左右子节点的值 注意:堆中某个节点的左右...

osc_xs6whvw7
03/24
2
0
10-9-堆排序-内部排序-第10章-《数据结构》课本源码-严蔚敏吴伟民版

课本源码部分 第10章 内部排序 - 堆排序 ——《数据结构》-严蔚敏.吴伟民版 源码使用说明 链接☛☛☛ 《数据结构-C语言版》(严蔚敏,吴伟民版)课本源码+习题集解析使用说明 课本源码合辑 链...

康建伟
2016/06/22
0
0
堆排序

堆排序 相关代码(选自 程序员小灰 的《漫画算法》):

Funcy1122
2019/08/13
0
0

没有更多内容

加载失败,请刷新页面

加载更多

App Builder 2020中文版

教程: 1、断开网络连接,下载解压,运行对应操作系统App Builder 2020安装包; 2、在弹出的窗口中勾选同意条款协议,点击【Next】; 3、创建桌面快捷方式,点击【Next】; 4、一切准备就绪,...

osc_62a7f5bj
18分钟前
19
0
蚂蚁金服轻量级类隔离框架 Maven 打包插件解析 | SOFAArk 源码解析

SOFAStack(Scalable Open Financial Architecture Stack)是蚂蚁金服自主研发的金融级云原生架构,包含了构建金融级云原生架构所需的各个组件,是在金融场景里锤炼出来的最佳实践。 本文为《...

SOFAStack
03/19
11
0
Java 高级 面试题 及 参考答案

一、面试题基础总结 1、 JVM结构原理、GC工作机制详解 答:具体参照:JVM结构、GC工作机制详解 ,说到GC,记住两点:1、GC是负责回收所有无任何引用对象的内存空间。 注意:垃圾回收回收的是无...

osc_np3y0rbq
19分钟前
10
0
面试准备季——MyBatis 面试专题(含答案)

写在前面:2020年面试必备的Java后端进阶面试题总结了一份复习指南在Github上,内容详细,图文并茂,有需要学习的朋友可以Star一下! GitHub地址:https://github.com/abel-max/Java-Study-...

osc_1ipdqsf2
20分钟前
8
0
Redis 高频面试题:10w+QPS 的 Redis 真的只是因为单线程和基于内存?

你以为 Redis 这么快仅仅因为单线程和基于内存? 那么你想得太少了,我个人认为 Redis 的快是基于多方面的:不但是单线程和内存,还有底层的数据结构设计,网络通信的设计,主从、哨兵和集群...

osc_qgfjs4a5
21分钟前
18
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部