package com.victor.sort.algorithms; import java.util.ArrayList; import com.victor.sort.seeds.*; /** * 堆排序 * @author 黑妹妹牙膏 * */ public class Heap extends SortAlgorithms { /** * Algorithm # heapify for i = n/2:1, sink(a,i,n) → invariant: a[1,n] in heap order # sortdown for i = 1:n, swap a[1,n-i+1] sink(a,1,n-i) → invariant: a[n-i+1,n] in final position end # sink from i in a[1..n] function sink(a,i,n): # {lc,rc,mc} = {left,right,max} child index lc = 2*i if lc > n, return # no children rc = lc + 1 mc = (rc > n) ? lc : (a[lc] > a[rc]) ? lc : rc if a[i] >= a[mc], return # heap ordered swap a[i,mc] sink(a,mc,n) Properties ■Not stable ■O(1) extra space (see discussion) ■O(n·lg(n)) time ■Not really adaptive Discussion Heap sort is simple to implement, performs an O(n·lg(n)) in-place sort, but is not stable. The first loop, the Θ(n) "heapify" phase, puts the array into heap order. The second loop, the O(n·lg(n)) "sortdown" phase, repeatedly extracts the maximum and restores heap order. The sink function is written recursively for clarity. Thus, as shown, the code requires Θ(lg(n)) space for the recursive call stack. However, the tail recursion in sink() is easily converted to iteration, which yields the O(1) space bound. Both phases are slightly adaptive, though not in any particularly useful manner. In the nearly sorted case, the heapify phase destroys the original order. In the reversed case, the heapify phase is as fast as possible since the array starts in heap order, but then the sortdown phase is typical. In the few unique keys case, there is some speedup but not as much as in shell sort or 3-way quicksort. * (non-Javadoc) * @see com.victor.sort.algorithms.SortAlgorithms#_sort(java.util.ArrayList) */ @Override protected ArrayList<Integer> doSort(ArrayList<Integer> Alist) { ArrayList<Integer> a = Alist; int n = a.size(); //print(a); for(int i=(n-1)/2;i>=0;i--) { a = sink(a,i,n); } //print(a); for(int i=0;i<n;i++) { int temp = a.get(0); a.set(0, a.get(n-i-1)); a.set(n-i-1,temp); a = sink(a,0,n-i-1); moveMentIncrease(); //print(a); } return a; } private ArrayList<Integer> sink(ArrayList<Integer> a,int i,int n) { //get left child int lc = 2 * i + 1; if(lc >= n) return a; //get right child int rc = lc + 1; //get max of left and right child int mc = (rc >= n) ? lc : (a.get(lc) > a.get(rc) ? lc : rc); // if parent > max of child then return if(a.get(i) >= a.get(mc)) return a; //swap max and parent int temp = a.get(i); a.set(i, a.get(mc)); a.set(mc, temp); moveMentIncrease(); return sink(a,mc,n); } @Override public String getName() { return "Heap"; } public static void main(String[] args) { Seeds seed1 = new Random(); Seeds seed2 = new NearSorted(); Seeds seed3 = new Reversed(); Seeds seed4 = new FewUniqueKeys(); SortAlgorithms SA = new Heap(); SA.sort(seed1,100000); //SA.print(); SA.sort(seed2,100000); SA.sort(seed3,100000); SA.sort(seed4,100000); //SA.print(); } }