【八大排序之选择排序---堆排序】

选择排序---堆排序


堆排序:

时间复杂度为O(nlogn)
堆排序算法首先将所有元素(从未排序的数组)插入堆中,然后从堆的根节点依次删除,直到堆空为止。主要利用现有数组进行就地排序,具体做法是,当删除一个元素时,只是将数组中的第一个元素与最后一个元素交换位置而不是移除,同时减小堆的大小,即数组大小,然后再对第一个元素进行堆化。持续这个过程直到剩余元素为1.

在数组中直接进行堆排序,需要知道几个参数,即最后一个元素的位置是i=count-1,count为数组大小,则最后一个元素的双亲位置为(count-1)/2。任意一个节点j的左子节点位置l=2j+1,右子节点位置r=2j+2.

##代码如下:

public static void heap(int[] arr)
    {    //堆排序  1、先创建堆
        for(int i=(arr.length-1) / 2; i>=0; i--)  //从数组中间的值开始,先作为顶点,然后从右边到左边,从上到下调整堆结构
        {
            adjust(arr,i,arr.length);      //结束后形成了大顶堆
        }
 
        for(int i=arr.length-1 ; i>0 ; i--)   //交换堆顶元素与末尾元素后 再调整堆结构,构成大顶堆
        {
            int temp=arr[i];
            arr[i]=arr[0];
            arr[0]=temp;
 
            adjust(arr,0,i);   //将最大的那个放在末尾,不进行调整
        }
    }
    public static void adjust(int[] arr,int parent,int length)
    {      //2、调整堆结构(大顶堆)
        int father=arr[parent];  //把temp作为父节点
        int lChild=2*parent+1;  //父节点的左孩子
        while (lChild<length)   //如果左孩子小于数组长度,说明存在右孩子
        {
            int rChild=lChild+1; //右孩子比左孩子大一
            if(rChild<length && arr[lChild] < arr[rChild]) //如果右孩子依然存在,且右孩子值大于左孩子,则选右孩子节点
            {
                lChild++;   //左孩子结点始终指向大的节点
            }
            if(father >= arr[lChild])    //如果父节点大于孩子节点中较大的那个,则结束循环
            {
                break;
            }
            arr[parent]=arr[lChild];  //否则把孩子的值赋给父亲
            parent=lChild; //然后孩子当爹,往下筛选
            lChild=2*lChild+1;   //然后把左孩子换成新爹的左孩子
            arr[parent]=father;   //最后将值交换
        }
 
 
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值