算法导论堆排序Java实现

时间:2021-03-19 11:03:30

            堆排序的时间复杂度为O(nlogn),相对于插入排序的O(n^2),它有很大的优势;对归并排序来讲,时间复杂度上两者一致,但是堆排序具有空间原址性,不用像归并那样还要有数组的复制操作。因此,堆排序的优点多多,

    下面给出算法导论里堆排序的java实现。

     

 /**
* 堆排序
*
*/
public void heapSort(int[] A){
//先创建数组对应的最大堆
buildMaxHeap(A,A.length);
for(int i = A.length -1;i> 0;i--){
//将根结点与最后一个结点交换数据
int temp = A[i];
A[i] = A[0];
A[0] = temp;
//将根结点从最大堆中拿出,
//通过将堆大小减1并重新维护最大堆性质来实现
maxHeapify(A,1,i);
}
}
/**创建最大堆
* @param A
* @param heapSize 堆大小,
*/
private void buildMaxHeap(int[] A,int heapSize){

for(int i = heapSize/2;i> 0;i--){
maxHeapify(A, i, heapSize);
}
}
/**维护最大堆属性的过程,
* 最大堆属性即是每个结点的值至多与其根结点一样大
* @param A
* @param i 根结点
* @param heapSize 堆大小
*/
private void maxHeapify(int[] A,int i,int heapSize){
int largest = i;//用来记录父结点以及儿子结点中最大值的index
int left = 2*i;//左儿子结点
int right = left+1;//右儿子结点
if(left <= heapSize && A[left-1] > A[i-1]){
largest = left;
}else{
largest = i;
}
if(right <= heapSize && A[right-1] > A[largest-1]){
largest = right;
}
if(largest != i){
int temp = A[i-1];
A[i-1] = A[largest-1];
A[largest-1] = temp;
//交换之后再重新维护下以largest为根结点的堆,
//使其保持最大堆属性
maxHeapify(A,largest,heapSize);
}

}