文档章节

HeapSort -- 堆排序

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

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

对于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;
        }
    }
}

 

© 著作权归作者所有

共有 人打赏支持
ninjaFrog
粉丝 3
博文 66
码字总数 17262
作品 0
昌平
程序员
私信 提问
堆排序 求高手解答

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

hjhomw
2015/07/16
486
2
堆排序算法及其Java实现(以大根堆为例)

(二叉)堆数据结构是一种数组对象,如图所示(下标从0开始),它完全可以被视为一棵完全二叉树。 接下来要出现的几个词语,这里介绍一下: length[A]: 数组A中元素的个数 heap-size[A]: 存放在数...

qq_35178267
2017/10/22
0
0
Heapsort 和 priority queue

一、二叉堆含义及属性: 堆(heap)亦被称为:优先队列(priority queue),是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵完全二叉树的数组对象。在队列中,调度程序反...

famince
2014/07/30
0
0
算法--堆排序学习以及模板

堆排序学习以及模板 堆排序(Heapsort)是指利用堆这样的数据结构所设计的一种排序算法。 堆积是一个近似全然二叉树的结构。并同一时候满足堆积的性质:即子结点的键值或索引总是小于(或者大...

技术mix呢
2017/10/19
0
0
HeapSort堆排序详解

本文我们来学习下堆排序的实现原理,堆排序顾名思义就是利用了堆的特点来实现排序,首先了解堆是什么? 堆相关的一些概念 二叉树 二叉树是每个节点最多有两个子树的树结构。也就是一个节点只...

激情的狼王丶21
2018/01/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

百度黄埔学院将培养一批首席AI架构师,为“国之重器”赋能

深度学习高端人才不仅是AI发展的重要养分,也是企业转型AI巨大推动力。2019年1月19日,百度黄埔学院——深度学习架构师培养计划在百度科技园举行开学典礼,深度学习技术及应用国家工程实验室...

深度学习之桨
44分钟前
2
0
扒站wget仿站

wget -c -r -p -np -k http://xxx.com/xxx 其中: -c, --continue (断点续传) 接着下载没下载完的文件 -r, --recursive(递归) specify recursive download.(指定递归下载) -p, --page...

临江仙卜算子
47分钟前
2
0
Nextjs+React非页面组件SSR渲染

@随风溜达的向日葵 Nextjs Nextjs是React生态中非常受欢迎的SSR(server side render——服务端渲染)框架,只需要几个步骤就可以搭建一个支持SSR的工程(_Nextjs_的快速搭建见Next.js入门)...

随风溜达的向日葵
今天
3
0
如何在 Linux 系统查询机器最近重启时间

在你的 Linux 或类 UNIX 系统中,你是如何查询系统上次重新启动的日期和时间?怎样显示系统关机的日期和时间? last 命令不仅可以按照时间从近到远的顺序列出该会话的特定用户、终端和主机名...

来来来来来
今天
4
0
Redis协议是什么样的

前言 我们用过很多redis的客户端,有没有相过自己撸一个redis客户端? 其实很简单,基于socket,监听6379端口,解析数据就可以了。 redis协议 解析数据的过程主要依赖于redis的协议了。 我们...

春哥大魔王的博客
今天
11
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部