堆排序数组代码实现

堆的概念:
一颗完全树
堆排序就是:就是依次添加的,中间不缺节点,除了最后叶节点不满,别的节点哦都是两个子节点
分为大根堆小根堆
小根堆,每个节点都比它的左右子树的节点要小
大根堆,每个节点都比它的左右子树的节点要大
堆排序的实现:

  • 先是读数组中的值构建小顶堆(小顶堆升序,大顶堆降序序列,其实也看怎末写),就是新添的先放最后,跟父节点比较,比父节点小就继续比较,直到根节点。
  • 再依次拿堆顶元素,因为堆顶就是最小的,拿完就要调整
  • 调整:树最后的元素取代丢掉的堆顶元素,遍历重新整合成小丁堆

堆排序两种实现

  • 1.树的实现,依靠先序队列,建堆,要和父节点比较,交换value值,还有指针的指向,依次拿,每次都要
  • 2.数组的实现,不用指针,找到下标就可以直接交换值
    树和数组之间默认转换就是从左到右,从上到下读取树
    数组体现:左孩子2n+1,有孩子2n+2,父亲是(n-1)/2
    时间复杂度
    构建堆:
    1.从数组中取, O(N)
    2.建一个堆,每次都和父节点比较,树的深度O(logN)
    取堆顶元素:
    1.从堆中取根节点取n次 O(N)
    2.调整为堆 O(logN)
    代码:
package BadaSort.duiPai;

import java.util.Arrays;

/**
 * @author Mzh
 * @date 2020-06-03 12:52
 * @description:
 * @version:
 */

public class DuipaiArray {
    public static void main(String[] args) {
        int[] arr={9,8,7,6,5,4,3,2,1};
        sort(arr);
        System.out.println(Arrays.toString(arr));
    }
    public static void sort(int[] arr){
        //构建大顶堆
        for(int i=arr.length/2-1;i>=0;--i){
            //从第一个非叶子节点从下往上,从右向左调整结构
            adjustHeap(arr,i,arr.length);
        }

        //调整结构+交换堆顶和莫为元素
        for (int j=arr.length-1;j>0;j--){
            swap(arr,0,j);
            adjustHeap(arr,0,j);
        }
    }

    /**
     * 调整大顶堆(仅是调整过程,建立在大顶堆已构建的基础上)
     * @param arr
     * @param i
     * @param length
     */
    public static void adjustHeap(int []arr,int i,int length){
        int temp = arr[i];//先取出当前元素i
        for(int k=i*2+1;k<length;k=k*2+1){//从i结点的左子结点开始,也就是2i+1处开始
            if(k+1<length && arr[k]<arr[k+1]){//如果左子结点小于右子结点,k指向右子结点
                k++;
            }
            if(arr[k] >temp){//如果子节点大于父节点,将子节点值赋给父节点(不用进行交换)
                arr[i] = arr[k];
                i = k;
            }else{
                break;
            }
        }
        arr[i] = temp;//将temp值放到最终的位置
    }


    //交换
    public static void swap(int []arr,int a ,int b){
        int temp=arr[a];
        arr[a] = arr[b];
        arr[b] = temp;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值