Java——数据结构——堆排序

来源:互联网 发布:sql server raiserror 编辑:程序博客网 时间:2024/06/05 03:30


package algorithms; 
import java.util.Random; 
public class MaxHeapify { 
private static int heapSize; 
public static void main(String[] args) { 
       Random rand = new Random(); 
       int[] a = new int[rand.nextInt(10)]; 
       for (int i = 0; i < a.length; i++) 
           a[i] = rand.nextInt(100); 
        heapSort(a); 
       for (int i : a) 
            System.out.print(i + " "); 
   } 
 
   private static void heapSort(int[] a) { 
        heapSize = a.length; 
        buildMaxHeap(a); 
       for (int i = a.length - 1; i >= 1; i--) { 
            swap(a, i, 0); 
            heapSize = heapSize - 1; 
            maxHeapify(a, 0); 
       } 
   } 
 
   private static void swap(int[] a, int i, int j) { 
        int temp = a[i]; 
        a[i] = a[j]; 
        a[j] = temp; 
   } 
 
   private static void buildMaxHeap(int[] a) { 
       for (int i = a.length / 2; i >= 0; i--) { 
           maxHeapify(a, i); 
        } 
    } 
 
    private static void maxHeapify(int[] a, int i) { 
        int l = left(i); 
        int r = right(i); 
        int largest = i; 
        if (l < heapSize && a[l] > a[i]) 
            largest = l; 
       else 
           largest = i; 
        if (r < heapSize && a[r] > a[largest]) 
            largest = r; 
        if (largest != i) { 
            swap(a, i, largest); 
            maxHeapify(a, largest); 
       } 
   } 
 
   private static int left(int i) { 
        return 2 * i; 
   } 
 
   private static int right(int i) { 
       return 2 * i + 1; 
    } 
 



堆排序和合并排序一样,是一种时间复杂度为O(nlgn)的算法,同时和插入排序一样,是一种就地排序算法(不需要额外的存储空间)。堆排序需要用到一种被称为最大堆的数据结构,与java或者lisp的gc不一样,这里的堆是一种数据结构,他可以被视为一种完全二叉树,即树里面除了最后一层其他层都是填满的。


我们现在有一个数组A,大小是n,假设其中元素按照完全二叉树的方式排列。如何将其构造成一个最大堆?首先我们知道最大堆的每个子树都符合最大堆的性质(根节点值大于所有子节点)。同时我们知道序号为(n/2+1)~n的元素都是叶子节点(因为其子女节点的序号都大于n,即说明没有子女节点),因此我们构建最大堆的操作就在序号为1~n/2的元素内进行(其他元素已满足最大堆性质)。我们定义如下操作maxify(i):将以i位置节点为根的子树改造成最大堆。其操作内容如下:对于每个节点i,我们考察他与子女节点的大小,如果他比某个子女节点小,则将他与子女节点中最大的那个互换位置,然后在相应的子女节点位置重复操作,直到到达堆的叶子节点或者考察的位置比子女节点的值都要大为止。由此可知我们构造最大堆buildmaxheap的过程就是在每个内部节点上调用maxify过程,依次到树的根部,此时其左右子树都是最大堆,现在在根节点调用maxify即完成了最大堆的构造。



0 0
原创粉丝点击