数据结构和算法 堆排序

原理:

堆排序(英语:Heapsort)是指利用这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆的性质:即子节点的键值或索引总是小于(或者大于)它的父节点。

若以升序排序说明,把数组转换成最大堆(Max-Heap Heap),这是一种满足最大堆性质(Max-Heap Property)的二叉树:对于除了根之外的每个节点i, A[parent(i)] ≥ A[i]。

重复从最大堆取出数值最大的结点(把根结点和最后一个结点交换,把交换后的最后一个结点移出堆),并让残余的维持最大堆性质。

图解:

 

 

代码实现:

代码git地址

https://github.com/baochunhai/data-structure-algorithms.git

手写堆:

 /**
 * 手写大根堆
 * 特殊逻辑关系:
 * 1.寻找父节点(i-1)/2
 * 2.寻找左孩子2*i+1,寻找右孩子2*i+2
 * @author Administrator
 */
public class Heap {
    // 堆的大小
    private  int heapSize;
    // 模拟堆
    private  int[] heap;

    public int[] getHeap() {
        return heap;
    }

    // 数组大小
    private  int limit;

    public Heap(int limit) {
        heap = new int[limit];
        this.limit = limit;
        heapSize = 0;
    }


    public  boolean isEmpty(){
        return heapSize==0;
    }
    public  boolean isFull(){
        return heapSize==limit;
    }
    public int size(){
        return limit;
    }

    /**
     * 根据用户给的值,
     * @param value
     */
    public void push(int value){
        if (heapSize==limit){
            throw new RuntimeException("堆已经满了");
        }
        heap[heapSize] = value;
        heapInsert(heap,heapSize);
        heapSize++;
    }
    public int pop(){
        int ans = heap[0];
        SortUtil.swap(heap,0,--heapSize);
        heapify(heap, 0, heapSize);
        return ans;
    }
    /**
     * 依次向堆中添加元素,如果大于父,就和父交换
     * 使堆成为一个大根堆
     * @param arr
     * @param index
     */
    public void heapInsert(int[] arr,int index){
       while (arr[index]>arr[(index-1)/2]){
           SortUtil.swap(arr,index,(index-1)/2);
           index = (index-1)/2;
       }

    }

    /**
     * 当前arr[0]位置是前大根堆的arr.length-1位置,为了保证heap还是大根堆,
     * arr[0]的值需要不断下沉,直到他的孩子中没有比他大的
     * @param arr
     * @param index
     * @param size
     */
    public void heapify(int[] arr, int index, int size){
        // 左孩子
        int left = index * 2 + 1;
        while (left<heapSize){
            // 如果右孩子存在,找到左右2个孩子中较大的那个
            int largest = left+1<heapSize&&arr[left]<arr[left+1]?left+1:left;
            // 比较是否比2个孩子中较大的还要大
            largest = arr[largest]<arr[index]?index:largest;
            if(largest==index){break;}
            // 交换
            SortUtil.swap(arr,index,largest);
            index = largest;
            left = index * 2 + 1;
        }
    }

}

堆排序1.0:

 /**
 * 堆排序
 * @author Administrator
 */
public class HeapSort {
    public static void main(String[] args) {
        int[] arr = SortUtil.randomArr(10);
        SortUtil.printArr(arr);
        heapSort(arr);
//        SortUtil.printArr(arr);

    }
    public static void heapSort(int[] arr){
        Heap heap = new Heap(arr.length);
        for (int i = 0; i < heap.size(); i++) {
            heap.push(arr[i]);
        }
        System.out.println("push");
        SortUtil.printArr(heap.getHeap());
        for (int i = 0; i < heap.size(); i++) {
            heap.pop();
        }
        System.out.println("pop");
        SortUtil.printArr(heap.getHeap());
    }
}

堆排序2.0待添加。。。

时间复杂度分析:

 

稳定性:

       不稳定。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值