Java排序八堆排序

8 篇文章 0 订阅

基本思想:
堆排序是一种树形选择排序方法,这种排序利用了堆的数据结构,是一种简单排序的改进版,将待排序的数组构造成一个大顶堆,将堆顶元素R1与最后一个元素R[n]交换,此时得到新的无序区和新的有序区,由于交换后的新的堆顶可能违反堆的性质,因此需要当前无序区调整为新堆,然后再将R1
与无序区的最后一个元素进行交换,得到新的无序区和新的有序区,重复此过程知道有序区的长度为初始数组的长度减一为止。
时间复杂度:O(nlogn),根据二叉树的特性得知
空间复杂度:O(1)

代码实现:

public class heapSort {
    static int length;//用于记录数组的长度
    public static int[] heap(int[] nums){
        length = nums.length;
        if (length ==0) return nums;
        //构建一个大根堆
        buildMaxHeap(nums);
        //循环将堆顶(最大值)与堆尾(最小值)进行交换,删除堆尾元素,然后重新调整大根堆
        while (length >0){
            swap(nums,0,length-1);
            length--;//原来的堆尾进入有序区,删除堆尾元素
            adjustHeap(nums,0);//重新调整大根堆
        }
        return nums;
    }
    /**
     * 自顶向下调整以i为根的堆为大根堆
     * @param nums
     * @param i
     */
    public static void adjustHeap(int[] nums, int i){
        //maxIndex表示最大指针
        int maxIndex = i;
        //如果有左子树,且左子树大于父结点,则将最大指针指向左子树
        if (2 *i+1<length && nums[2*i+1]>nums[maxIndex]){
            maxIndex = 2*i+1;
        }
        //如果有右子树,且右子树大于父结点,则将最大指针指向右子树
        if (2 *i+2<length && nums[2*i+2]>nums[maxIndex]){
            maxIndex = 2*i+2;
        }
        //如果父结点不是最大值,则将父结点与最大值交换,并且递归调整与父节点交换的位置
        if (maxIndex != i){
            swap(nums,maxIndex,i);
            adjustHeap(nums,maxIndex);
        }
    }
    /**
     * 交换两个元素
     * @param arr
     * @param index1
     * @param index2
     */
    private static void swap(int[] arr,int index1,int index2) {
        int temp = arr[index1];
        arr[index1]=arr[index2];
        arr[index2] = temp;
    }
    /**
     * 自底向上构建初始大根堆
     * @param arr
     */
    public static void buildMaxHeap(int[] arr){
        //从最后一个非叶子节点开始自底向上构造大根堆
        for (int i = (length-2)/2;i>=0;i--){
            adjustHeap(arr,i);
        }
    }
    public static void main(String[] args) {
      int[] arr = {70, 20, 60, 80, 30, 40, 50, 32, 64 };
        System.out.println(Arrays.toString(heap(arr)));
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值