Small (big) top of the heap with a variety of operating scenarios (based on Java)

package algroithm;

import java.util.Arrays;
import java.util.Scanner;

/**
 * @Author Snail
 * @Describe 用于堆算法的测试
 * @CreateTime 2019/7/25
 * <p>
 * <p>
 * 堆中父子节点索引的关系:
 * childIndex=parentIndex*2+1(左节点在数组中的索引)
 * childIndex=parentIndex*2+2(右节点在数组中的索引)
 */
public class TestHeap {

    public static void main(String[] args) {
        //1. 将任意一个数组构建为小顶堆
        int[] arr = new int[]{7, 1, 3, 10, 5, 2, 8, 9, 6};
        buildHeap(arr);
        System.out.println(Arrays.toString(arr));        //[1, 5, 2, 6, 7, 3, 8, 9, 10]
        //2. 交换堆顶元素与末尾元素 + 调整堆结构:得到堆排序后的有序数组
        for (int i = arr.length - 1; i > 0; i--) {
            swap(arr, 0, i);
            downAdjust(arr, 0, i);
        }
        System.out.println(Arrays.toString(arr));//[10, 9, 8, 7, 6, 5, 3, 2, 1]
/**
 *1中堆构建的时间复杂度为O(n),2中堆调整的时间复杂度为nlog(n),所以认为堆排序的时间复杂度为O(nlog(n))
 */

        //加入一个元素到小顶堆中(加入元素到堆中,自能将新元素加在数组最后)
        Scanner scanner = new Scanner(System.in);
        int childNode = Integer.parseInt(scanner.nextLine());//0
        int[] arrHeap = new int[]{1, 5, 2, 6, 7, 3, 8, 9, 10};
        arrHeap = upAdjust(arrHeap, childNode);
        System.out.println(Arrays.toString(arrHeap));//[0, 1, 2, 6, 5, 3, 8, 9, 10, 7]

        //删除堆顶元素,堆中每次都只能删除第0个数据,并将最后一个元素放到数组的0位置
        arrHeap = delNode(arrHeap);
        System.out.println(Arrays.toString(arrHeap));//[1, 5, 2, 6, 7, 3, 8, 9, 10]
    }

    private static void swap(int[] arr, int i, int i1) {
        int temp = arr[i];
        arr[i] = arr[i1];
        arr[i1] = temp;
    }

    /**
     * 构建一个小顶堆(任何一个父节点的值,都小于等于它左右孩子节点的值)
     *
     * @param arr 待调整的堆
     */
    public static void buildHeap(int[] arr) {
        // 从最后一个非叶子节点开始到根节点,依次下沉调整
        for (int i = arr.length / 2; i >= 0; i--) {
            downAdjust(arr, i, arr.length);
        }
    }

    /**
     * 堆中某个元素的下沉调整
     *
     * @param arrHeap     待调整的堆
     * @param parentIndex 下沉的节点
     * @param length      堆数组的长度
     */
    public static void downAdjust(int[] arrHeap, int parentIndex, int length) {
        //保存父节点值,避免元素交换,并用于最后的赋值
        int temp = arrHeap[parentIndex];
        int childIndex = parentIndex * 2 + 1;
        while (childIndex < length) {//表示节点还没下沉到数组的最后位置
            //判断是否存在右节点,并找到两个孩子节点的最小值
            if (childIndex + 1 < length && arrHeap[childIndex] > arrHeap[childIndex + 1]) {
                childIndex++;
            }
            //如果父节点小于孩子节点的最小值,则证明他不需要下沉了
            if (temp <= arrHeap[childIndex]) {
                break;
            }
            //将孩子节点上浮到父节点位置
            arrHeap[parentIndex] = arrHeap[childIndex];
            parentIndex = childIndex;
            childIndex = parentIndex * 2 + 1;
        }
        arrHeap[parentIndex] = temp;
    }

    /**
     * 堆中元素的上浮调整,上浮最后一个元素
     *
     * @param arrHeap   待调整的堆
     * @param childNode
     */
    public static int[] upAdjust(int[] arrHeap, int childNode) {
        //复制数组到新的空间
        int childIndex = arrHeap.length;
        int[] newHeap = new int[childIndex + 1];
        System.arraycopy(arrHeap, 0, newHeap, 0, childIndex);
        //上浮元素
        newHeap[childIndex] = childNode;
        int parentIndex = (childIndex - 1) / 2;
        while (childIndex > 0 && childNode < newHeap[parentIndex]) {
            //将parent节点替换到child节点
            newHeap[childIndex] = newHeap[parentIndex];
            childIndex = parentIndex;
            //获取父节点的父节点
            parentIndex = (parentIndex - 1) / 2;
        }
        newHeap[childIndex] = childNode;
        return newHeap;
    }

    /**
     * 删除小顶堆中堆顶
     *
     * @param arrHeap
     * @return
     */
    private static int[] delNode(int[] arrHeap) {
        //构建新数组地址空间
        int[] newHeap = new int[arrHeap.length - 1];
        System.arraycopy(arrHeap, 0, newHeap, 0, arrHeap.length - 1);
        newHeap[0] = arrHeap[arrHeap.length - 1];

        downAdjust(newHeap, 0, newHeap.length);
        return newHeap;
    }

}

Heap sort algorithm can be considered time complexity O (nlog (n))

Algorithm can refer to: https://mp.weixin.qq.com/s/cq2EhVtOTzTVpNpLDXfeJg

Published 91 original articles · won praise 54 · views 10000 +

Guess you like

Origin blog.csdn.net/BigBug_500/article/details/97656888