Java基础算法之堆排序(Heap Sort)

1、堆介绍

大顶堆: 非叶子结点的数据要大于或等于其左,右子节点的数据

小顶堆: 非叶子结点的数据要小于或等于其左,右子节点的数据

2、算法介绍

  1. 先从后面的非叶子结点从后向前将结点构建成一个大顶堆(小顶堆)。
  2. 此时根节点就是最大的数据(最小的数据),然后将根节点与数组最后一位进行交换。
  3. 交换后再从根节点开始构建堆(此时树的长度应该减一,因为最大的数已经确定了)。
  4. 重复执行2-3步骤,直到数据有序。

3、图解

堆排序图解

4、代码实现

package sort;

import java.util.Arrays;

/**
 * <p>
 *
 * </p>
 *
 * @author: D
 * @since: 2020/9/11
 * @version: 1
 */
public class HeapSortDemo {
    
    
    public static void main(String[] args) {
    
    
        int[] arr = {
    
    117, 101, 106, 100, 112, 60, 90, 110};
        heapSort(arr);
        Arrays.sort(arr);
        System.out.println(Arrays.toString(arr));

    }

    private static void heapSort(int[] arr) {
    
    
        int temp;
        System.out.println("从后向前构建堆");
        //从后面的非叶子结点进行调整数组为大顶堆
        for (int i = arr.length / 2 - 1; i >= 0; i--) {
    
    
            System.out.println("非叶子结点:" + i);
            bigTopPile(arr, i, arr.length);
        }
        System.out.println("从根节点开始构建堆");
        for (int j = arr.length - 1; j > 0; j--) {
    
    
            temp = arr[j];
            arr[j] = arr[0];
            arr[0] = temp;
            System.out.println("确认下标为" + j + ":" + Arrays.toString(arr));
            // 从根节点开始调整数据为大顶堆
            bigTopPile(arr, 0, j);
        }
    }

    /**
     * 将数组变为一个大顶堆
     *
     * @param arr         数组
     * @param nonLeafNode 非叶子结点在数组中的下标
     * @param length      调整的数组长度
     */
    private static void bigTopPile(int[] arr, int nonLeafNode, int length) {
    
    
        System.out.println("构建前数组:" + Arrays.toString(arr));
        //保存非叶子结点
        int temp = arr[nonLeafNode];
        System.out.println("非叶子结点数据:" + temp);

        // index = nonLeafNode * 2 + 1 index为非叶子结点的左子结点
        for (int index = nonLeafNode * 2 + 1; index < length; index = index * 2 + 1) {
    
    
            System.out.println("左子节点:" + index);
            //左子节点小于右子节点  右子节点就是左子节点加1
            if (index + 1 < length && arr[index] < arr[index + 1]) {
    
    
                System.out.println("左子节点小于右子节点,指针指向右子节点");
                //左子节点小于右子节点 那么将index此时指向右子节点
                index++;
            }
            //如果子节点大于父节点  则进行交换
            if (arr[index] > temp) {
    
    
                System.out.println("子节点大于父节点,进行交换");
                arr[nonLeafNode] = arr[index];
                nonLeafNode = index;
            } else {
    
    
                break;
            }
        }
        arr[nonLeafNode] = temp;
        System.out.println("构建后数组:" + Arrays.toString(arr));
        System.out.println();
    }
}

5、执行结果

image-20200911104430539

image-20200911104458365

image-20200911104513701

6、其他算法

选择排序(Selection Sort)
插入排序(Insertion Sort)
希尔排序(Shell Sort)
冒泡排序(Bubble Sort)
快速排序(Quick Sort)

猜你喜欢

转载自blog.csdn.net/d875708765/article/details/108531476