堆排序算法

    堆排序是对数组进行排序的一个方法,其用到的思想是能够经过构建一个树直观的来看,但它自己的存储结构与树确实是一毛钱关系都没有。java

    堆排序是仿照树的作法,把整个数组抽象成一棵彻底二叉树。数组第一个元素就是这个彻底二叉树的根结点。彻底二叉树的概念能够在百度上自行普及下。数组

    堆排序的步骤

    堆排序从大的层面,有三个步骤:ui

    (1)找出一个备用的数组spa

    (2)把备用的数组调整成一个堆(最大堆或最小堆)code

    (3)每次把第一个元素与最后一个元素互换,而后把最后一个元素踢出数组,再把剩下元素组成的数组调整成一个堆排序

    代码实现

    

/**
 * @date 2017/11/16 上午10:22
 */
public class HeapSort {
    public static void main(String args[]) {
        int[] a = {
                1, 3, 9, 2, 5, 29, 2, 4, 8
        };
        print(a);
        buildHeap(a);
        print(a);
        heapSort(a);
        print(a);
    }

    /**
     * 堆排序的具体实现
     */
    private static void heapSort(int[] a) {
        int size = a.length;
        for (int i = size - 1; i >= 0; i--) {
            swap(a, 0, i);
            heapAdjust(a, 0, i);
        }
    }

    //从下向上进行堆的构建
    private static void buildHeap(int[] a) {
        int size = a.length;
        for (int i = size / 2 - 1; i >= 0; i--) {
            heapAdjust(a, i, size);
        }
    }

    //从一个节点从上向下进行堆的调整
    private static void heapAdjust(int[] a, int index, int size) {
        int lchild = index * 2 + 1;
        int rchild = index * 2 + 2;
        int maxIndex = index;
        if ((lchild < size) && (a[lchild] > a[index])) {
            maxIndex = lchild;
        }
        if ((rchild < size) && (a[rchild] > a[maxIndex])) {
            maxIndex = rchild;
        }
        if (maxIndex != index) {
            swap(a, maxIndex, index);
            heapAdjust(a, maxIndex, size);
        }
    }

    //交换数组中两个下标元素的值
    private static void swap(int[] a, int x, int y) {
        int temp = a[x];
        a[x] = a[y];
        a[y] = temp;
    }

    //对数组进行打印
    private static void print(int[] a) {
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i] + ",");
        }
        System.out.println();
    }

}

    代码分析

    代码的核心其实就是heapAdjust()方法,这个方法的做用是:get

    在当前结点为根结点的树是一个堆的状况下,改变根结点的值,这个方法会把以这个结点为根结点的二叉树调整成一个堆。class

    在进行堆构建的时候,其实也是进行了一个简单的迭代。先从下向上一个结点一个结点的保证堆的性质,直至根结点。百度

    而在排序的时候,每次把根结点取出放到最后,那最后一个元素放的就必定是这个二叉树中的最大或最小元素。交换元素值以后再进行堆的调整,调整到最后,排序就完成了。date

相关文章
相关标签/搜索