/**
  *堆排序思路:O(nlogn)
  *    用最大堆,传入一个数组,先用数组建堆,维护堆的性质
  *    再把第一个数与堆最后一个数调换,因为第一个数是最大的
  *    把堆的大小减小一
  *    再  在堆的大小上维护堆的性质
  *    重复操作..
  *
  *
  */
 public  class  HeapSort
 {
     /**
      *静态变量存放堆的大小
      */
     private  static  int  heapsize = 0 ;    

     /**
      *堆排序主方法
      *    构建最大堆,然后进行堆排序
      *    堆排序是把最上面的最大的元素放在最下面,然后再维护上面最大堆的性质
      */
     public  static  void  heapSort(int[] resouceArr)
     {
         //堆的大小
         heapsize = resouceArr.length - 1 ;

         _buildMaxHeap(resouceArr);

         for( int i = resouceArr.length - 1 ; i >= 0 ; i--)
         {
             int temp = resouceArr[0] ;
             resouceArr[0] = resouceArr[i] ;
             resouceArr[i] = temp ; 

             heapsize = heapsize - 1 ;
             _maxHeapify( resouceArr, 0 );
         }
     }

     /**
      *构建最大堆
      *    构建之后还不是有序的,但符合最大堆性质,上面的数一定大于下面的数
      */
     private  static  void  _buildMaxHeap(int[] arr)
     {
         int length = arr.length - 1 ; 

         //从倒数第二排开始维护最大堆性质
         //    当heapsize为偶数时,heapsize要减一
         //    当heapsize为奇数时,不变
         if(length % 2 == 0)
         {
             length--;
         }
         for( int i = length / 2 ; i >= 0  ; i--)
         {
             _maxHeapify(arr , i );
         }
     }

     /**
      *用于维护堆的性质
      *    树形堆在postion的位置向下维护堆的性质,自postion向下满足最大堆的性质
      */
     private  static  void  _maxHeapify(int[] arr,int postion)
     {
         //计算postion的左孩子和右孩子
         postion = postion + 1 ;

         int  l = postion * 2 - 1;
         int  r = postion * 2 ;
         postion = postion - 1 ;

         int largest = maxNumInThreeNum(arr , postion , l , r);

         //如果不满足最大堆性质,则交换值,然后检查树形下方是否满足最大堆性质
         if(largest <= heapsize)
         {
             if( largest != postion)
             {
                 //交换最大值与父节点值
                 int  temp = arr[postion] ;
                 arr[postion] = arr[largest] ;
                 arr[largest] = temp ;
                 //如果子节点变动了,则重新构建已子节点为根的最大堆
                 _maxHeapify(arr , largest);                

             }
         }
     }    

     /**
      *比较数组中的三个数找出最大值
      */
     private  static  int  maxNumInThreeNum(int[] arr ,int a, int b , int c)
     {
         int max = a ;
         //数组长度小于左孩子,最大值为本身
         if(heapsize < b)
         {
             max = a ;
         }
         else if(heapsize >=b && heapsize < c)
         {
             if(arr[a] < arr[b])
             {
                 max = b ;
             }
         }
         else
         {
             if(arr[a] > arr[b])
             {
                 max = a ;
             }
             else
             {
                 max = b ;
             }
             if(arr[max] < arr[c])
             {
                 max = c ;
             }
         }
         return max ;
     }
 }

排序算法FOUR:堆排序HeapSort的更多相关文章

  1. Java常见排序算法之堆排序

    在学习算法的过程中,我们难免会接触很多和排序相关的算法.总而言之,对于任何编程人员来说,基本的排序算法是必须要掌握的. 从今天开始,我们将要进行基本的排序算法的讲解.Are you ready?Let ...

  2. 排序算法之堆排序(Heapsort)解析

    一.堆排序的优缺点(pros and cons) (还是简单的说说这个,毕竟没有必要浪费时间去理解一个糟糕的的算法) 优点: 堆排序的效率与快排.归并相同,都达到了基于比较的排序算法效率的峰值(时间复 ...

  3. Java排序算法之堆排序

    堆的概念: 堆是一种完全二叉树,非叶子结点 i 要满足key[i]>key[i+1]&&key[i]>key[i+2](最大堆) 或者 key[i]<key[i+1] ...

  4. 《排序算法》——堆排序(大顶堆,小顶堆,Java)

    十大算法之堆排序: 堆的定义例如以下: n个元素的序列{k0,k1,...,ki,-,k(n-1)}当且仅当满足下关系时,称之为堆. " ki<=k2i,ki<=k2i+1;或k ...

  5. C++编程练习(13)----“排序算法 之 堆排序“

    堆排序 堆是具有下列性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆(也叫最大堆):或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆(也叫最小堆). 最小堆和最大堆如 ...

  6. 数据结构与算法之PHP排序算法(堆排序)

    一.堆的定义 堆通常是一个可以被看做一棵树的数组对象,其任一非叶节点满足以下性质: 1)堆中某个节点的值总是不大于或不小于其父节点的值: 每个节点的值都大于或等于其左右子节点的值,称为大顶堆.即:ar ...

  7. 八大排序算法之七—堆排序(Heap Sort)

    堆排序是一种树形选择排序,是对直接选择排序的有效改进. 基本思想: 堆的定义如下:具有n个元素的序列(k1,k2,...,kn),当且仅当满足 时称之为堆.由堆的定义可以看出,堆顶元素(即第一个元素) ...

  8. 排序算法(2) 堆排序 C++实现

    堆 1 数组对象 2 可以视为一棵完全二叉树 3 一个堆可以被看作一棵二叉树和一个数组,如下图所示: 4 下标计算(通常使用内联函数或者宏来定义下标操作): 已知某个结点的下标为i 其父节点下标:i/ ...

  9. Python 一网打尽<排序算法>之堆排序算法中的树

    本文从树数据结构说到二叉堆数据结构,再使用二叉堆的有序性对无序数列排序. 1. 树 树是最基本的数据结构,可以用树映射现实世界中一对多的群体关系.如公司的组织结构.网页中标签之间的关系.操作系统中文件 ...

随机推荐

  1. 60款开源云应用【Part 2】(60 Open Source Apps You Can Use in the Cloud)

    60款开源云应用[Part 2](60 Open Source Apps You Can Use in the Cloud) 本篇翻译自http://www.datamation.com/open-s ...

  2. SQL索引详解

    转自:http://www.cnblogs.com/AK2012/archive/2013/01/04/2844283.html SQL索引在数据库优化中占有一个非常大的比例, 一个好的索引的设计,可 ...

  3. 使用百度地图结合GPS进行定位

    本文在上文基础上加入GPS定位功能,实现实时定位,代码如下: Activity: package com.home; import android.app.Activity; import andro ...

  4. 文件I/O(不带缓冲)概述

    一.引言 UNIX系统中大多数文件I/O只需用到5个函数:open.read.write.lseek以及close.这些函数经常被称为不带缓冲的I/O(unbuffered I/O).术语不带缓冲指的 ...

  5. NPOI导出多表头Execl(通过html表格遍历表头)

    关于NPOI的相关信息,我想博客园已经有很多了,而且NPOI导出Execl的文章和例子也很多,但导出多表头缺蛮少的:今天要讲的通过自己画html表格:通过html表格来导出自定义的多表头: 先来看要实 ...

  6. linux文件夹操作(及模糊搜索)

    mkdir   文件夹名称    :创建文件夹 touch  文件名称       : 创建文件 给文件夹或文件授权 chmod -R 777 文件夹名称   : 递归给文件夹授读写执行权限 chmo ...

  7. PHP端验证代码、后端验证

    /** * 验证url是否存在 * @param string $url url路径 * @return boolean true:存在,false:不存在 */ public function va ...

  8. java_jdbc_batch处理_主键id获取

    //create1 速度较慢,create2较快,但是要根据数据库不同来决定 //ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_ ...

  9. Encryption

    Encryption Configuration Basic Usage Encrypting a value Decrypting a value Configuration Before usin ...

  10. JS 笔记

    如何定义一个函数呢?基本语法如下: function 函数名() {      函数代码; } 说明: 1. function定义函数的关键字. 2. "函数名"你为函数取的名字. ...