堆排序实现-java

堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。
下面的算法以小顶堆为例

堆的储存及其表示

可以用一维数组表示一个堆
在这里插入图片描述
可表示为{50,45,40,20,25,35,30,10,15}
所以可得出parent节点和左右节点的公式:
当前节点为index,
parent: (index-1)/2
left: index2+1
right: index
2+2

构造堆

堆调整方法heapify()

找出以当前节点为父亲节点的树的最大节点交换其和父亲节点的位置,然后再对被换的那个节点进行递归堆调整操作

  /**
     * 堆调整函数
     * @param array 堆
     * @param parent 父亲节点
     * @param len 长度
     */
    public void heapify(int[] array,int parent,int len){
        if(parent>=len){//最后一个节点结束
            return;
        }

        int left = parent*2+1;
        int right = parent*2+2;
        int max = parent;
        if(left<len && array[left]>array[max]){

            max = left;
        }
        if(right<len && array[right]>array[max]){

            max = right;
        }
        if(max != parent){//max节点发生变化后,递归调整max节点为parent节点的树
            swap(array,max,parent);
            heapify(array,max,len);
        }

    }

构造堆方法

从最后一个非叶子节点开始,即倒数第二层进行调用堆调整算法

 /**
     * 构造堆函数
     * 从下往上,最后一一个非子节点开始,即倒数第二层
     * @param array
     * @param len
     */
    public void getHeap(int[] array,int len){
        int index = (len-1)/2;//获取最后一个非子节点
        for(int i = index;i>=0;i--){
            heapify(array,i,len);
        }
    }

堆排序

    /**
     * 堆排序算法
     * 将堆顶节点与堆尾节点交换,然后隐式去除最后一个节点(通过len),并调整堆顶,heapify
     * @param array
     * @param len
     */
    public void heapSort(int[] array,int len){
        getHeap(array,len);
        for(int i = len-1;i>=0;i--){
            swap(array,0,i);//交换堆顶和在最后一个节点值,然后将最后一个元素从堆中去除
            heapify(array,0,i);//此处len用i代替,因为len每次减一值和i等
        }
    }

完整代码

package sort;

public class HeapSortTest {
    public void swap(int[] array,int a, int b){
        int temp = array[a];
        array[a] = array[b];
        array[b] = temp;
    }

    /**
     * 堆调整函数
     * @param array 堆
     * @param parent 父亲节点
     * @param len 长度
     */
    public void heapify(int[] array,int parent,int len){
        if(parent>=len){//最后一个节点结束
            return;
        }

        int left = parent*2+1;
        int right = parent*2+2;
        int max = parent;
        if(left<len && array[left]>array[max]){

            max = left;
        }
        if(right<len && array[right]>array[max]){

            max = right;
        }
        if(max != parent){//max节点发生变化后,递归调整max节点为parent节点的树
            swap(array,max,parent);
            heapify(array,max,len);
        }

    }

    /**
     * 构造堆函数
     * 从下往上,最后一一个非子节点开始,即倒数第二层
     * @param array
     * @param len
     */
    public void getHeap(int[] array,int len){
        int index = (len-1)/2;//获取最后一个非子节点
        for(int i = index;i>=0;i--){
            heapify(array,i,len);
        }
    }

    /**
     * 堆排序算法
     * 将堆顶节点与堆尾节点交换,然后隐式去除最后一个节点(通过len),并调整堆顶,heapify
     * @param array
     * @param len
     */
    public void heapSort(int[] array,int len){
        getHeap(array,len);
        for(int i = len-1;i>=0;i--){
            swap(array,0,i);//交换堆顶和最后一个节点的值
            heapify(array,0,i);//此处len用i代替,因为len每次减一值和i等
        }
    }



    public static void main(String[] args) {

        int[] array ={2,5,3,1,10,4};
        int len =array.length;
        HeapSortTest heapSortTest = new HeapSortTest();
        heapSortTest.heapSort(array,len);
        System.out.println("hhh");
        for (int i:array){
            System.out.println(i+" ");
        }


    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值