堆排序

堆排序可归纳为两个操作:

(1)根据初始数组去构造初始堆(构建一个完全二叉树,保证所有的父结点都比它的孩子结点数值大)。

(2)每次交换第一个和最后一个元素,输出最后一个元素(最大值),然后把剩下元素重新调整为大根堆。 

当输出完最后一个元素后,这个数组已经是按照从小到大的顺序排列了。

先通过详细的实例图来看一下,如何构建初始堆。

设有一个无序序列 { 1, 3, 4, 5, 2, 6, 9, 7, 8, 0 }。

 

构造了初始堆后,我们来看一下完整的堆排序处理:

还是针对前面提到的无序序列 { 1, 3, 4, 5, 2, 6, 9, 7, 8, 0 } 来加以说明。

 

 

下面给出代码实现

/**
 * Created by 亮大王 on 2017/9/21.
 */

import java.util.Arrays;

/**
 * 堆实质是一个二叉树,存储是用数组来实现的,节点i的两个孩子节点(如果存在)分别是2*i+1和2*i+2,它的父节点是(i-1)/2,
 * 大顶堆 i>=2i+1&&i>=2i+2  小顶堆  i<=2i+1&&i<=2i+2,本程序是基于大顶堆来实现的
 */
public class maxHeap {

    /**
     * 此方法是一个大顶堆调整算法指从第i个元素开始,使它的子树满足大顶堆的要求
     *
     * @param i 从第i个元素开始
     * @param a 存储数组
     * @param n 当前堆元素的总个数
     * @return
     */
    public void maxHeapDown(int i, int a[], int n) {
        /**左孩子节点*/
        int j = 2 * i + 1;
        int temp = a[i];
        while (j < n) {
            if (j + 1 < n && a[j + 1] > a[j]) {
                j++;
            }
            if (a[j] <= temp) {
                break;
            }
            a[i] = a[j];
            i = j;
            j = 2 * i + 1;
        }
        a[i] = temp;
    }

    /**
     * 此方法是一个大顶堆排序算法,生成一个大顶堆数组
     *
     * @param a 存储数组
     * @param n 数组元素的总个数
     * @return
     */
    public void heapSort(int a[], int n) {
        /**排序从最后一个非叶子节点开始,为(n/2)-1*/
        for (int i = (n / 2) - 1; i >= 0; i--) {
            maxHeapDown(i, a, n);
        }
    }

    /**
     * 此方法是一个大顶堆输出函数
     *
     * @param a 大顶堆存储数组
     * @param n 数组元素的总个数
     * @return
     */
    public void printMaxHeap(int a[], int n) {
        /**数组的首元素即为最大元素,将堆尾元素与其交换位置,堆尾输出后,重新调整位置*/
//        for(int i=n-1;i>=0;i--)
//        {
//            swap(a,0,i);
//            System.out.println(a[i]);
//            maxHeapDown(0,a,i);
//        }
        for (int i = 0; i < n; i++) {
            swap(a, 0, n - i - 1);
           // System.out.println(a[n - 1 - i]);
            maxHeapDown(0, a, n - i - 1);
        }
    }

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

    public static void main(String[] args) {
        int[] a = new int[]{9, 6, 12, 32, 23, 11, 2, 100, 85};
        maxHeap mh = new maxHeap();
        System.out.println(Arrays.toString(a));
        mh.heapSort(a, a.length);
        System.out.println(Arrays.toString(a));
        mh.printMaxHeap(a, a.length);
        System.out.println(Arrays.toString(a));
    }


}

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值