堆排序

堆排序

  堆排序是利用这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。首先简单了解下堆结构。

'''堆'''是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆

  堆排序的基本思想是:将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了

堆排序首先进行建堆

建堆完成后进行排序

大致步骤

a.将无需序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆;

b.将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;

c.重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。

    public static void heapSort( int []arr){
        //将数据整理成大顶堆
        for (int i=arr.length/2-1;i>=0;i--){
            buildHeapSort(arr,i,arr.length);
        }

        for (int j=arr.length-1;j>0;j--){
            //把堆顶元素放到数组最后
            swap(arr,0,j);
            //堆顶放入数组结尾后 自上而下重新调整数组 建立新的大顶堆
            buildHeapSort(arr,0,j);
        }
    }

    /**
     * 整个堆排序最关键的地方
     *
     * @param arr    待组堆
     * @param start  起始结点
     * @param length 堆的长度
     */
    public static void buildHeapSort(int[] arr, int start, int length) {
        int temp = arr[start];
        //从上到下 将小数下沉到堆底
        for (int i = 2 * start + 1; i < length; i = 2 * i + 1) {
            //判断左右孩子节点的大小
            if (i + 1 < length && arr[i] < arr[i + 1]) {
                i++;
            }
            //父节点与大于父节点的孩子节点进行交换
            if (temp < arr[i]) {
                swap(arr, start, i);
                start = i;
            } else {
                break; //父节点大于它的左节点和右节点
            }
        }


    }
//用于交换  
public static void swap(int[] arr, int x, int y) {
        int tem = arr[x];
        arr[x] = arr[y];
        arr[y] = tem;
    }
原文地址:https://www.cnblogs.com/huangshen/p/13367388.html