面试--算法排序(5)(堆排序)

堆排序也是选择排序的一种
堆的定义
如果有一个关键码K={k1,k2,k3…..}把他的所有元素按照完全二叉树的顺序存储方式放在一个一维数组中。并且满足
ki<=k2i且ki<=k2i+1//小根堆
ki>=k2i且Ki>=K2i+1//大根堆
小根堆效果图:
这里写图片描述

大根堆效果图
这里写图片描述

堆排序:
若在输出堆栈的最大值之后,使得剩余n-1个元素的序列又建成一个堆,则得到n个元素中的次大值,如此反复执行,便能得到一个有序序列,这个过程称为堆排序
*堆排序解决的两个问题:
①如何建堆
②输出堆顶元素之后,如何调整新堆*

代码展示:



import java.util.*;
public class HeapSort {
    public int[] heapSort(int[] A, int n) {
        int lastIndex = n - 1;
        buildMaxHeap(A, lastIndex);//建立最大堆
        while(lastIndex > 0){
            swap(A, 0, lastIndex);
            if(--lastIndex == 0)//只剩一个元素,就不用调整堆了,排序结束
                break;
            adjustHeap(A,0,lastIndex);    
        }
        return A;
    }
    public void buildMaxHeap(int[] arr, int lastIndex) {
        // 从最后一个元素的父节点开始进行调整,一直调整到根节点结束
        int j = (lastIndex - 1) / 2;
        while (j >= 0) {
            int rootIndex = j;
            adjustHeap(arr, rootIndex, lastIndex);
            j--;
        }

    }
    public void adjustHeap(int[] arr, int rootIndex, int lastIndex) {//从根节点开始往下调整
        int biggerIndex = rootIndex;
        int leftChildIndex = rootIndex * 2 + 1; 
        int rightChildIndex = rootIndex * 2 + 2;
        if(rightChildIndex <= lastIndex){//如果右孩子存在,则左孩子一定存在
            if(arr[rightChildIndex] > arr[rootIndex] || arr[leftChildIndex] > arr[rootIndex]){
                //将子节点更大的元素下标赋值给biggerIndex
                biggerIndex = arr[rightChildIndex] > arr[leftChildIndex]?rightChildIndex:leftChildIndex;
            }
        }
        else if(leftChildIndex <= lastIndex){//保证左孩子存在,且不能越界
            if(arr[leftChildIndex] > arr[rootIndex]){
                biggerIndex = leftChildIndex;
            }
        }
        if(biggerIndex != rootIndex){
            swap(arr, biggerIndex, rootIndex);
            adjustHeap(arr, biggerIndex, lastIndex);
        }
    }
    public void swap(int[] arr, int biggerIndex, int rootIndex) {
        int temp = arr[rootIndex];
        arr[rootIndex] = arr[biggerIndex];
        arr[biggerIndex] = temp;
    }
}

算法分析:
平均时间复杂度:O(N*logN)
空间复杂度:O(1)
稳定性:不稳定

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值