堆排序
堆排序的时间复杂度是:o(nlogn);
第一种思路:在所有的循环中,循环的第一次是建堆,剩余的是调整堆。
public class lianxi { public static void main(String[] args){ int[] array = {1,2,3,4,5,6,7,8}; int[] result = new lianxi().heapSort(array); System.out.println(Arrays.toString(array)); } public int[] heapSort(int[] array){ int length = array.length; for(int i=0;i<length;i++){ buildHeap(array,length-1-i); //System.out.println(Arrays.toString(array)); swap(array,0,length-1-i); //System.out.println(Arrays.toString(array)); } return array; } public void buildHeap(int[] array,int n){ int i=0; // 保证后面的几次循环只是调整堆,调整一次堆的时间复杂度是O(logn),需要调整n次,所以需要的时间复杂度是O(nlogn); if(n==array.length-1) i = (n-1)/2; //保证当第一次循环时,只是建堆,建堆需要的时间复杂度是O(nlogn); for(;i>=0;i--){ //由以上两个注释,可以得到最后的时间复杂度是o(nlogn)。 int m = i; while(2*m+1<=n){ int p = 2*m+1; if(p<n){ if(array[p]<array[p+1]){ p = p+1; } } if(array[m]<array[p]){ swap(array,m,p); m = p; }else{ break; } } } } public void swap(int[] array,int p,int q){ int temp = array[q]; array[q] = array[p]; array[p] = temp; } }
第二种思路是:先建堆,然后再调整堆。(建立一个调整堆函数
public int[] heapSort(int[] array){ int length = array.length; for(int i=(length-2/2);i>=0;i--){ adjustHeap(array,i,length-1); } for(int i=0;i<array.length;i++){ swap(array,0,length-1-i); adjustHeap(array,0,length-2-i); } return array; } public void adjustHeap(int[] array,int m,int n){ //m:代表开始的调整堆的节点,n:代表需要调整的堆的大小。 while(2*m+1<=n){ int p = 2*m+1; if(p<n){ if(array[p]<array[p+1]){ p=p+1; } } if(array[m]<array[p]){ swap(array,m,p); m = p; }else{ break; } } } public void swap(int[] array,int p,int q){ int temp = array[q]; array[q] = array[p]; array[p] = temp; } }
)