经典排序算法——堆排序(逆序)

经典排序算法——堆排序(逆序)

基本步骤

  1. 构建小顶堆
  2. 将堆顶元素与最后一个元素交换并减小数组范围
  3. 对交换完的数组进行向下调整

算法复杂度

整体时间复杂度O(nlog n)

  • 构建小顶堆 O(nlog n)
  • 交换与向下调整 O(nlog n)
public class HeapSort(){
	//堆排序
	public static void sort(int[] a){
		int n = a.length; 
		//1.构建小顶堆
		minHeap(a);
		//2.将堆顶元素与最后一个元素交换并减小数组范围
		for(int i = n-1; i > 0; i--){
			swap(a,0,i);
			//3.对交换完的数组进行向下调整
			//注意i的变化,每次进行调整后会减小数组范围
			minHeapFixDown(a,0,i);
		}
	}
	//构建小顶堆
	public static void minHeap(int[] a, int n){
		//从堆的倒数第二层开始向下调整
		for(int i = n/2-1; i >= 0; i--){
			minHeapFixDown(a,i,n);
		}
	}
	//小顶堆的向下调整
	public static void minHeapFixDown(int[] a, int i, int n){
   		int left = 2*i+1;//左子节点
   		int right = 2*i+2;//右子节点
   		int min = left;//左右节点中最小值,初始化为左节点
   		if(left >= n) return;//如果左子节点越界,则无需调整
   		if(right >= n) min = left;//右子节点越界,则最小值为左节点值
   		else{//若都无越界,min为左右子节点中小的那个
   			if(a[right] < left) min = right;
   		}
   		
   		//若子节点都比节点i大,则无需调整
   		if(a[min] >= a[i]) return;
   		//否则对i和min进行调整,并且继续向下调整
   		swap(a,min,i);
   		minHeapFixDown(a,min,n);
   		
   }
}

你可能感兴趣的:(算法)