堆排序,删除堆中任意单一元素

本文深入探讨了堆排序算法,特别是关注如何在排序过程中有效地从堆中删除任意单一元素。通过学习,读者将掌握堆的性质、构建过程以及删除操作的实现细节,进一步提升对排序算法的理解。
package headSort;
import java.util.Arrays;
public class MyHeap {
    public int[] arr;
    public int size;
    public MyHeap(int[] arr) {
        this.arr = arr;
        this.size=arr.length;
    }
    /**
     * 删除下标为i的元素
     * 思路->将最大元素删除->让删除元素的值增加到原先的最大元素->替换思想
     */
    public void delete(int i){
        int deleteValue = arr[i];
        int pop = pop();
        if (i!=0)        increaseValue(arr,deleteValue,pop);
    }
    public int pop(){
        int popValue = arr[0];
        swap(arr,0,arr.length-1);
        size--;
        arr=Arrays.copyOf(arr,size);
        headify(0, size);
        return popValue;
    }
    private void increaseValue(int[] a,int deleteValue,int k){
        // 一定是变大
        int i = 0 ;
        while (arr[i]!=deleteValue) i++;
        arr[i]=k;
        // 上浮
        int parentIndex;
        while ((parentIndex=parent(i)) >= 0 && a[i]>a[parentIndex]){
            swap(a,parentIndex,i);
            i=parentIndex;
        }
    }
    public void headSort() {
        for (int i = (size - 1) / 2 ; i >= 0; i--)
            headify(i,size);//为什么这个时候length不用-1 ->因为这个时候需要全部节点都要考虑

        for (int i = size - 1; i >= 0; i--) {
            swap(arr, i, 0);//将第一元素移动到最后->堆顶元素是最大元素->这样一来就不用管最后的元素了,排序从后往前排
            //为什么这个时候不用考虑最后一个节点->因为这个时候最后一个节点已经有序了不用管了
            headify(0,i);
        }
    }
    private void headify (int i,int length) {
        int largest = i;
        int leftson = 2 * i + 1;
        int rightson = 2 * i + 2;
        if (leftson < length) largest = (arr[largest] > arr[leftson]) ? largest : leftson;
        if (rightson < length) largest = (arr[largest] > arr[rightson]) ? largest : rightson;
        if (largest != i) { //largest是更最大值交换的位置
            swap(arr,largest,i);
            headify(largest,length);
        }
    }
    private void swap(int[] a, int i, int j) {
        int temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }
    public void print_ln(){
        for (int i = 0 ; i < size ; i ++){
            if (i==0) {System.out.print(" [ " + arr[i] + "  ");continue;}
            if (i == size - 1){
                System.out.println( arr[i]  + " ] ");
                break;
            }
            System.out.print( arr[i] + "  ");
        }
    }
    private int parent(int i){
        return (i%2==0)?i/2-1:i/2;
    }
    public static void main(String[] args) {
        MyHeap myHeap = new MyHeap(new int[]{10, 9, 3, 8, 5, 1, 2, 7, 6});
        myHeap.delete(2);
        myHeap.print_ln();
        myHeap.headSort();
        myHeap.print_ln();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值