码迷,mamicode.com
首页 > 编程语言 > 详细

堆排序算法剖析

时间:2017-10-02 20:21:32      阅读:292      评论:0      收藏:0      [点我收藏+]

标签:对象   http   .so   str   个数   tar   没有   param   logs   

1.将待排序列以一个完全二叉树存储,设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第h层所有的结点都连续集中在最左边,这就是完全二叉树。

技术分享  

2.第一趟排序,从二叉树的最后一个根节点(有步骤1可知是值为12的节点)开始,调整当前节点所在的堆,使当前节点大于所有子节点的值。

技术分享

技术分享

技术分享

技术分享

技术分享

3.第二趟排序,每趟排序后,待排序列中的最大值将被移动到根节点,将根节点元素与待排序列中最后一个元素交换位置,红色元素表示已经排好的序列,红色元素不参与下轮的排序过程

技术分享

技术分享

技术分享

技术分享

技术分享

技术分享

 技术分享

技术分享

技术分享

技术分享

技术分享

技术分享

技术分享

技术分享 

技术分享

技术分享

 

代码:

package com.zjl.sort;

/**
 * 堆排序
 * @author huanongying
 *
 */
public class HeapSort {

    /**
     * @param args
     */
    public static void main(String[] args) {
        int[] arr = {40,55,49,73,12,27,98,81,64,36};//待排序数组
        HeapSort(arr, arr.length - 1);//将arr按照降序排列
        //打印排序后的数组
        for(int value : arr) {
            System.out.print(value + " ");
        }
    }

    /**
     * 待排序列(R1,R2,...,Rk,...Rn)看作是完全二叉树,通过比较、交换,父节点和孩子节点的值,
     * 使得对于任意元素Rk(k<=n/2),满足Rk>=R(2k),Rk>=R(2k+1)
     * @param arr    数组对象
     * @param start    数组的开始下标
     * @param end    数组的结束下标
     */
    private static void HeapAdjust(int[] arr, int start, int end) {
        //当下标为start的元素有孩子元素时
        while(start <= end/2) {
            //left和right分别为左右孩子元素的下标,max为左右孩子中值较大的孩子的元素下标
            int left = 2 * start+1;
            int right = 2 * start+2;
            int max = 0;
            
            //如果既有左孩子,又有右孩子
            if(left < end&&right <= end) {
                //如果左孩子小于右孩子的值,max = right,否则为max = left
                if(arr[left] <= arr[right])
                    max = right;
                else
                    max = left;
            }
            //如果只有左孩子,没有右孩子,max值为left
            if(left <= end&&right > end) {
                max = left;
            }
            //如果没有孩子,则表明到了完全二叉树的叶子节点
            if(left > end) {
                break;
            }
            
            //如果当前节点值小于两孩子中的值较大者,那么将当前节点值与max交换
            if(arr[start] < arr[max]){
                int tmp = arr[start];
                arr[start] = arr[max];
                arr[max] = tmp;
            }
            //当前节点向孩子节点迭代
            start = max;
        }
    }

    /**
     * @param arr 数组
     * @param end    数组结束下标
     */
    private static void HeapSort(int[] arr, int end) {
        //由最后一个非叶子节点,向根节点迭代,创建最大堆,数组中的最大值将被移动到根节点
        for(int start = end/2;start >= 0;start--) {
            HeapAdjust(arr, start, end);
        }
        
        while(end > 0){
            //交换arr[0]和arr[end]的值
            int tmp = arr[0];
            arr[0] = arr[end];
            arr[end] = tmp;
            
            //排序范围变为(0,end-1)
            HeapAdjust(arr, 0, end - 1);
            end--;
        }
    }

}


 

堆排序算法剖析

标签:对象   http   .so   str   个数   tar   没有   param   logs   

原文地址:http://www.cnblogs.com/huanongying/p/7622168.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!