基础排序算法(4)

堆排序

  堆排序是一种原地排序算法,在任何时候,数组只有常数个元素存储在输入数组以外。

堆排需要用到堆,堆是一种数据结构,它可以被视为一棵完全二叉树,树中每个节点与数组中存放给节点的值对应。

由二叉树的性质,我们可以知道父节点下标为i/2,左子树节点为2i,右子树节点为2i+1.

  二叉堆有两种,分为最大堆和最小堆。最大堆是指除根节点外,所有父节点都大于或等于其子节点。最大堆的最大元素存放在根节点。

最小堆则与最大堆相反,最小堆的最小元素在根节点。

  在堆排序中,我们通常使用最大堆,最小堆通常在构造优先队列时使用。堆可以被看做是一棵树。具有n个元素的堆是基于一棵完全二叉树,

其高度为log2 n.

       在构建最大堆的过程中,我们要保持最大堆的性质,即父节点大于或等于其子节点,时间复杂度为O(log2 n).

java实现

    public class Heap_Sort{

      public int heapSize;

      public static void main(String[] args){

        int[] unsorted = new int[]{3,3,2,1,7,4,5,9};

        builtMaxHeap(unsorted);

        for(int i = unsorted.length-1; i >= 1;i--){

           int tmp = unsorted[i];

             unsorted[i] = unsorted[1];

             unsorted[1] = tmp;

           heapSize = heapSize-1;

           maxHeap(unsorted,1);

        }

      }

      private static builtMaxHeap(int[] unsorted){//建堆

        heapSize = unsorted.length;

        int len = unsorted.length;

        for(int i = len/2; i >= 0; i--){

          maxHeap(unsorted,i);

        }

    }

      private static maxHeap(int[] unsorted,int i){ //使堆保持根节点最大

        int l = 2*i;//左子树下标

        int r = 2*i+1;//右子树下标

        int largest = i;

        if(l <= heapSize&&unsorted[l] > unsorted[i]){    //如果左子节点大于其父节点,最大下标为l,否则为i

          largest = l;

        }else{  

          largest = i;

        }

        if(r <= heapSize&&unsorted[r] > unsorted[]largest){ //如果右子节点大于最大值,largest = r;

          largest = r;

        }

        if(largest != i){ //如果其父节点不是最大值,交换,使其保持最大堆的性质

          int tmp = unsorted[largest];

          unsorted[largest] = unsorted[i];

          unsorted[i] = tmp;

          maxHeap(unsorted,largest);//递归调用

         }

      }

  }

时间复杂度:O(nlog2 n)

猜你喜欢

转载自www.cnblogs.com/binhuang01/p/11426511.html
今日推荐