其他分享
首页 > 其他分享> > 堆

作者:互联网

size
i 左节点:2 * i + 1
右节点:2 * i + 2
父节点:(i-1)/ 2

维护heapsize(堆大小)
当插入一个元素,初始位置就是 当前heaspsize的位置,然后和自己的父节点比较。如果比自己的父节点大,就交换,直到根节点。如果不大,就停止。这个操作就是heapInsert

public static void heapInsert(int[] arr, int index) {
        //当前值小于其父节点就停止
        // 当index为0. index-1/2 也为0.也停止了。
        while (arr[index] > arr[(index - 1) / 2]) {
            swap(arr, index, ((index -1 ) /2));
            //交换之后,更新index
            index = (index - 1) /2;
        }
    }

当取走0位置上的数之后(获取最大值), 调整堆的结构保持 是大根堆。
最后一个数和0 交换,然后调整。调整之后,最后一个数就不在堆里了。断掉
自己的左孩子 和 右孩子 PK,挑一个最大的。 和 自己再pk.
停的条件:左右孩子都没自己大,没有左右孩子了。

public static void heapify(int[] arr, int index, int size) {
    int left = 2 * index + 1; // 左孩子下标
    while (left < size) { // 有左孩子,
        // 获取 左孩子和右孩子 值大 的 index
        int largest = left + 1 < size && arr[left + 1] > arr[left] ? left + 1 : left;
        // 孩子最大 和 自己比。
        largest = arr[largest] > arr[index] ? largest : index;

        if (largest == index) {
            // 如果自己就是最大的,退出
            break;
        }
        // 孩子比自己大,交换
        swap(arr, largest, index);
        // 更新index,继续往下
        index = largest;
        // 更新 左孩子 下标
        left = 2 * index + 1;
    }
}

排序

public void userSort(int[] arr) {
    if (arr == null || arr.length < 2) {
        return;
    }

    int heapSize = arr.length;
    // 插入堆,只是个大根堆,还未排序
    for (int i = 0; i < arr.length; i++) {
        heapInsert(arr, i);
    }
    // 开始调整,当前最大值在0,依次和最后的位置交换,就依次排好了。
    swap(arr, 0, --heapSize);
    while (heapSize > 0) {
        heapify(arr, 0, heapSize);
        
        swap(arr, 0, --heapSize);
    }

}

标签:,index,arr,int,largest,节点,left
来源: https://www.cnblogs.com/clllll/p/16212639.html