已知数组 79、52、48、51、49、34、21、3、26、23 ,请采用堆排序使数组有序。

什么是堆

是一颗完全二叉树,N层完全二叉树是一颗,除N-1层外其节点数都达到最大,且第N层子节点全部集中在树的最左侧的二叉树。

 

其次一般采用数组实现。

故其节点有如下关系:

根节点为ROOT:(X-1)/2;左节点LEFT为:2*X+1;右节点RIGHT为:2*X+2(LEFT+1);

堆分为:“最大堆”,以及“”最小堆”。最大堆是其根节点大于其子节点(每层子树同样是根节点大于其子节点)即   A[PARENT(i)]>=A[i].

最小堆与最大堆的情况相反即   A[PARENT(i)]<=A[i].

堆是一颗 “弱排序”的二叉树,与二叉搜索树不同,堆仅要求根节点大于或等于子节点。(二叉搜索树,左节点<根节点<=右节点)

根据以上性质我们便可以构建“堆”。

在构建堆时采用了两种思想:插入时,将“插入元素放在数组尾端”,根据性质向上搜索,插入合适的位置。即由树脚到树根方向。

                                               删除时,将根节点,弹出后,将数组尾端较小元素放置在根部,然后从树根根据性质向下搜索,插入合适的位置。 即从树根到树脚方向。

堆排序的思想就是利用堆这种数据结构,将待排序的数组插入堆,然后在按序弹出,数组即有序

即   for(){

          Heap.Insert(i)

       }

       for( ){

         Heap.popTop();

       }

经过以上操作,数组有序。

以下是采用java实现的  (最大堆),输出排序结果为从大到小。

public class HeapOrder {

private int[] Array;

private int currentIndex;

private int maxIndex;

public HeapOrder(int size) {
                         this.Array = new int[size];
                         this.currentIndex = 0;
                         this.maxIndex = size-1;
               }

public void insert(int value) {//插入元素,构建最大堆
                        if(this.maxIndex<this.currentIndex) {
                              System.out.println("堆已满");
                        }else {
                              this.Array[this.currentIndex++] = value;
                              this.moveUp(this.currentIndex-1);  //向上移动元素 从树脚到树根方向

                        }
               }

public int popTop() {//弹出树根,即最大元素
                        if(this.currentIndex!=0) {
                              int popValue = this.Array[0];
                             this.Array[0] = this.Array[--this.currentIndex];
                             this.moveDown(0);  //向下移动元素 从树根到树脚方向
                            return popValue;
                        }else {
                            return -1;
                       }
               }

private void moveUp(int index) {
                      int temp = this.Array[index];
                      int root = (index-1)/2;
                     while(index>0&&temp>this.Array[root]) {//判断元素所在位置,防止越界;同时检查插入元素和其相对树根元素的大小
                              this.Array[index] = this.Array[root];
                              index = root;
                             root = (index-1)/2;
                     }
                     this.Array[index] = temp;
             }

private void moveDown(int index) {
                    int temp = this.Array[index];
                    int largeValue;
                    while(this.currentIndex/2>index) {//每次循环的子树都必须要至少有一个子节点(左节点)
                          int left = 2*index+1;
                          int right = left+1;
                          if(right<this.currentIndex&&this.Array[left]<this.Array[right]) {//保证有右节点存在,并从左节点和右节点中选择较大的节点
                               largeValue = right;
                         }else{
                              largeValue = left;
                         }
                        if(temp>this.Array[largeValue]) {
                             break;
                        }else {
                             this.Array[index] = this.Array[largeValue]; 
                            index=largeValue;
                       }
                   }
                         this.Array[index] = temp;
              }

最终结果:79、52、51、49、48、34、26、26、21、3

堆排序是一个运行时间为O(N*lgN)的排序算法。

                                    

堆排序 思想 JAVA实现的更多相关文章

  1. 堆排序算法 java 实现

    堆排序算法 java 实现 白话经典算法系列之七 堆与堆排序 Java排序算法(三):堆排序 算法概念 堆排序(HeapSort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,可以利用数组的特 ...

  2. 程序员必知的8大排序(二)-------简单选择排序,堆排序(java实现)

    程序员必知的8大排序(一)-------直接插入排序,希尔排序(java实现) 程序员必知的8大排序(二)-------简单选择排序,堆排序(java实现) 程序员必知的8大排序(三)-------冒 ...

  3. 堆排序之Java实现

    堆排序之Java实现 代码: package cn.com.zfc.lesson21.sort; /** * * @title HeapSort * @describe 堆排序 * @author 张 ...

  4. 基本算法思想Java实现的详细代码

    基本算法思想Java实现的详细代码 算法是一个程序的灵魂,一个好的算法往往可以化繁为简,高效的求解问题.在程序设计中算法是独立于语言的,无论使用哪一种语言都可以使用这些算法,本文笔者将以Java语言为 ...

  5. 33.JAVA编程思想——JAVA IO File类

    33.JAVA编程思想--JAVA IO File类 RandomAccessFile用于包括了已知长度记录的文件.以便我们能用 seek()从一条记录移至还有一条:然后读取或改动那些记录. 各记录的 ...

  6. 排序系列 之 堆排序算法 —— Java实现

       基本概念: 二叉堆是完全二叉树或者是近似完全二叉树. 当父结点的键值总是大于或等于任何一个子节点的键值时为最大堆. 当父结点的键值总是小于或等于任何一个子节点的键值时为最小堆. 一般将二叉堆简称 ...

  7. 排序算法入门之堆排序(Java实现)

    堆排序 在学习了二叉堆(优先队列)以后,我们来看看堆排序.堆排序总的运行时间为O(NlonN). 堆的概念 堆是以数组作为存储结构. 可以看出,它们满足以下规律: 设当前元素在数组中以R[i]表示,那 ...

  8. 插入排序 思想 JAVA实现

    已知一个数组 60.28.41.39.6 .18 .14.28.49.31 利用插入排序算法进行排序 插入排序是一个运行时间为O(N²)的排序算法. 算法思想  60.28.41.39.6 .18 . ...

  9. 二叉搜索树 思想 JAVA实现

    二叉搜索树:一棵二叉搜索树是以一棵二叉树来组织的,这样一棵树可以使用链表的数据结构来表示(也可以采用数组来实现).除了key和可能带有的其他数据外,每个节点还包含Left,Right,Parent,它 ...

随机推荐

  1. leetcode592

    public class Solution { private int GCD(int a, int b) { ? GCD(b, a % b) : a; } private int LCM(int a ...

  2. Hadoop Serialization -- hadoop序列化详解 (3)【ObjectWritable,集合Writable以及自定义的Writable】

    前瞻:本文介绍ObjectWritable,集合Writable以及自定义的Writable TextPair 回顾: 前面了解到hadoop本身支持java的基本类型的序列化,并且提供相应的包装实现 ...

  3. 继承ServletContextListener可以完成的事情

    1.定时任务: 定时任务是从某个固定的时间开始执行特定的程序,继承这个方法,可以实现刚启动项目的时候执行某特定的程序,完成给客户部署的时即可以看到某个页面的效果. 2.初始化系统常量等: 这样来完成系 ...

  4. oracle语言基础

    一.语言分类 1.DML(Data Manipulation Language,数据操作语言):用于对数据的操作. DML包括:(1)SELECT:查询数据 select * from temp;   ...

  5. s=1+2*3+4*5*6+7*8*9*10+.... C语言求解

    #include <stdio.h> /*类似斐波那契数列的计算方式 项 1 2 3 4 1 2*3 4*5*6 7*8*9*10 生成项的起始数字 1 2 4 7 和后一项的差值 1 2 ...

  6. Nginx Rewrite研究笔记

    原文出自:http://blog.cafeneko.info/2010/10/nginx_rewrite_note/ 在新主机的迁移过程中,最大的困难就是WP permalink rewrite的设置 ...

  7. SSH连接Linux

    转载自百度经验 https://jingyan.baidu.com/article/bea41d439d16d7b4c51be619.html 连接Linux的工具有Putty.SSH Secure ...

  8. 卡尔曼滤波总结——KF、EFK、UKF

    1.用途 现实是我们的处理和测量模型都是非线性的,结果就是一个不规则分布,KF能够使用的前提就是所处理的状态是满足高斯分布的,为了解决这个问题,EKF是寻找一个线性函数来近似这个非线性函数,而UKF就 ...

  9. Tensorflow学习(练习)—下载骨骼图像识别网络inception数据集

    import tensorflow as tfimport osimport tarfileimport requests #inception模型下载地址inception_pretrain_mod ...

  10. php_imagick超强的PHP图片处理扩展

      php_imagick是一个可以供PHP调用ImageMagick功能的PHP扩展,使用这个扩展可以使PHP具备和ImageMagick相同的功能. ImageMagick是一套功能强大.稳定而且 ...