java实现 堆排序

在实现堆排序之前 我们先来介绍一下什么是最大堆与最小堆

最大堆 与最小堆 都是一个二叉树 也称为二叉堆

二叉堆的定义
每个节点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆)

最大堆 : 当父节点的键值总是大于或等于每一个子节点 时被称为最大堆

最小堆 : 当父节点的键值总是小于或等于每一个子节点 时被称为最小堆

最小堆 :

                   1

             2            3

       17        19     36    7 

    25   100        

最大堆:

                100

            98         97

         67    63

       45   23

一般的堆的存储都用数组来完成 ,所以一个节点的父节点就为 (节点下标-1)/2 他的左右子节点分别为2*i+1 和 2*i+2

例子 :

            10

       15        56

    23   75                                             array[]={10.15,56.23.75};      

15的父节点就为 (1-1)/2 =0 左右子节点为 array[2*1+1]=23 array[2*1+2]=75

我们已经理解了什么是最大堆 与最小堆了,现在我们来编写代码


/*
 * *功能  快速排序
 * *作者 blue
 * *data 4.5
 * 
 */
public class MaxHeapsortDemo {
    private static int[] sort = new int[]{1,0,10,10,3,5,6,4,9,8,12,17,34,11};

    public static void main(String[] args) {
        builddMaxHeapify(sort);
        heapSort(sort);
        Prtint(sort);
    }
    private static void Prtint(int[] sort2) {
        for (int i = 0; i < sort2.length; i++) {
            System.out.print(" "+sort2[i]);
        }

    }
    private static void builddMaxHeapify(int[] data) {
        int startIndex = (data.length-2)>>1;//得到数组最后一位的父节点
        for (int i = startIndex; i>=0; i--) {
            maxHeap(data, data.length, i);

        }
    }
    private static void maxHeap(int[] data ,int heapSize,int index) {
        int leftChildIndex = (index<<1)+1;//得到该节点的左子节点
        int rightChildIndex = (index<<1)+2;//得到该节点的右子节点
        int largest =index;
        /*
         * 找到当前节点与左右节点的的最大值
         */
        if (leftChildIndex<heapSize&&data[index]<data[leftChildIndex]) {
            largest = leftChildIndex;
        }
        if (rightChildIndex<heapSize&&data[largest]<data[rightChildIndex]) {
            largest = rightChildIndex;

        }
        /*
         * 如果当前的父节点不是最大点,就交换节点与最大节点的值,
         */
        if (largest!=index) {
            int temp = data[index];
            data[index] =data[largest];
            data[largest] =temp;
            maxHeap(data, heapSize, largest);

        }
    }
    /*
     * *从第一父节点开始交换,把第一父节点交换给最后一个节点,然后再调用MaxHeap 从新排最大堆
     */

    private static void heapSort(int[] data) {

        for (int i = data.length-1; i >=0; i--) {
            int temp = data[0];
            data[0]=data[i];
            data[i]=temp;
            maxHeap(data, i, 0);
        }

    }



}

我们首先 将一个乱序的数组 排成了一个最大堆 ,
首先 找到一个父节点 ,然后找到左右子节点,判断三个节点的键值的最大,如果父节点不是最大就要与最大的子节点交换,交换 之后的子节点已经不满足最大堆 ,所以这个时候我们就需要递归来继续重排最大堆

意思就是 刚开始是 56|67 23 发现 56不是最大节点 然后把 67 和 56 换掉 这个时候 原先67的左右子节点就不满足56 了 所以就要重新构成最大堆

在构成最大堆后 ,我们就开始排序了

首先这个最大堆得最大父节点 与最后一位交换,交换之后 就又不满足最大堆的特性,所以这时候我们又要重新调用maxHeap 函数 来重新构成最大堆了
这个时候我们发现,最大父节点已经是上一个父节点的左子节点
如图所示 :

END!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值