堆排序

主要思想(升序):

將待排序序列構造成一個大頂堆,此時,堆頂就是該序列的最大值。將堆頂與末尾元素交換,此時末尾元素就是最大值。然後

將剩餘 n-1 個元素重新構造一個大頂堆,這樣得到n個元素的次小值。如此反覆執行,得到一個有序序列。

步驟:

1、創建大鼎堆;

從最後一個非葉子節點從下到上、從右到左調整堆

2、將堆鼎與堆尾交換

3、調整堆結構

    比較堆頂與子節點,如堆頂小於子節點,交換;繼續比較交換後的節點與其子節點,重複執行,直到父節點大於子節點。

重複步驟2、3

package sortdemo;

import java.util.Arrays;

/**
* 堆排序demo
*/
public class HeapSort {
   public static void main(String []args){
       int []arr = {9,8,7,6,5,4,3,2,1};
       sort(arr);
       System.out.println(Arrays.toString(arr));
   }
   public static void sort(int []arr){
       //1.構建大頂堆
       for(int i=arr.length/2-1;i>=0;i--){
           //從第一個非葉子結點從下至上,從右至左調整結構
           adjustHeap(arr,i,arr.length);
       }
       //2.調整堆結構+交換堆頂元素與末尾元素
       for(int j=arr.length-1;j>0;j--){
           swap(arr,0,j);//將堆頂元素與末尾元素進行交換
           adjustHeap(arr,0,j);//重新對堆進行調整
       }

   }

   /**
    * 調整大頂堆(僅是調整過程,建立在大頂堆已構建的基礎上)
    * @param arr
    * @param i
    * @param length
    */
   public static void adjustHeap(int []arr,int i,int length){
       int temp = arr[i];//先取出當前元素i
       for(int k=i*2+1;k<length;k=k*2+1){
       //從i結點的左子結點開始,也就是2i+1處開始
           if(k+1<length && arr[k]<arr[k+1]){
           //如果左子結點小於右子結點,k指向右子結點
               k++;
           }
           if(arr[k] >temp){
           //如果子節點大於父節點,將子節點值賦給父節點(不用進行交換)
               arr[i] = arr[k];
               i = k;
           }else{
               break;
           }
       }
       arr[i] = temp;//將temp值放到最終的位置
   }

   /**
    * 交換元素
    * @param arr
    * @param a
    * @param b
    */
   public static void swap(int []arr,int a ,int b){
       int temp=arr[a];
       arr[a] = arr[b];
       arr[b] = temp;
   }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章