最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java實現堆排序(大根堆)的示例代碼

 更新時間:2019年10月24日 10:45:17   作者:sunshisonghit  
這篇文章主要介紹了Java實現堆排序(大根堆)的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

堆排序是一種樹形選擇排序方法,它的特點是:在排序的過程中,將array[0,...,n-1]看成是一顆完全二叉樹的順序存儲結構,利用完全二叉樹中雙親節(jié)點和孩子結點之間的內在關系,在當前無序區(qū)中選擇關鍵字最大(最?。┑脑亍?/p>

1. 若array[0,...,n-1]表示一顆完全二叉樹的順序存儲模式,則雙親節(jié)點指針和孩子結點指針之間的內在關系如下:

任意一節(jié)點指針 i:父節(jié)點:i==0 ? null : (i-1)/2

        左孩子:2*i + 1

        右孩子:2*i + 2

2. 堆的定義:n個關鍵字序列array[0,...,n-1],當且僅當滿足下列要求:(0 <= i <= (n-1)/2)

     ?、?array[i] <= array[2*i + 1] 且 array[i] <= array[2*i + 2]; 稱為小根堆;

     ?、?array[i] >= array[2*i + 1] 且 array[i] >= array[2*i + 2]; 稱為大根堆;

3. 建立大根堆:

n個節(jié)點的完全二叉樹array[0,...,n-1],最后一個節(jié)點n-1是第(n-1-1)/2個節(jié)點的孩子。對第(n-1-1)/2個節(jié)點為根的子樹調整,使該子樹稱為堆。

對于大根堆,調整方法為:若【根節(jié)點的關鍵字】小于【左右子女中關鍵字較大者】,則交換。

之后向前依次對各節(jié)點((n-2)/2 - 1)~ 0為根的子樹進行調整,看該節(jié)點值是否大于其左右子節(jié)點的值,若不是,將左右子節(jié)點中較大值與之交換,交換后可能會破壞下一級堆,于是繼續(xù)采用上述方法構建下一級的堆,直到以該節(jié)點為根的子樹構成堆為止。

反復利用上述調整堆的方法建堆,直到根節(jié)點。

4.堆排序:(大根堆)

 ?、賹⒋娣旁赼rray[0,...,n-1]中的n個元素建成初始堆;

 ?、趯⒍秧斣嘏c堆底元素進行交換,則序列的最大值即已放到正確的位置;

 ?、鄣藭r堆被破壞,將堆頂元素向下調整使其繼續(xù)保持大根堆的性質,再重復第②③步,直到堆中僅剩下一個元素為止。

堆排序算法的性能分析:

  空間復雜度:o(1);

  時間復雜度:建堆:o(n),每次調整o(log n),故最好、最壞、平均情況下:o(n*logn);

  穩(wěn)定性:不穩(wěn)定

建立大根堆的方法:

//構建大根堆:將array看成完全二叉樹的順序存儲結構
  private int[] buildMaxHeap(int[] array){
    //從最后一個節(jié)點array.length-1的父節(jié)點(array.length-1-1)/2開始,直到根節(jié)點0,反復調整堆
    for(int i=(array.length-2)/2;i>=0;i--){ 
      adjustDownToUp(array, i,array.length);
    }
    return array;
  }
  
  //將元素array[k]自下往上逐步調整樹形結構
  private void adjustDownToUp(int[] array,int k,int length){
    int temp = array[k];  
    for(int i=2*k+1; i<length-1; i=2*i+1){  //i為初始化為節(jié)點k的左孩子,沿節(jié)點較大的子節(jié)點向下調整
      if(i<length && array[i]<array[i+1]){ //取節(jié)點較大的子節(jié)點的下標
        i++;  //如果節(jié)點的右孩子>左孩子,則取右孩子節(jié)點的下標
      }
      if(temp>=array[i]){ //根節(jié)點 >=左右子女中關鍵字較大者,調整結束
        break;
      }else{  //根節(jié)點 <左右子女中關鍵字較大者
        array[k] = array[i]; //將左右子結點中較大值array[i]調整到雙親節(jié)點上
        k = i; //【關鍵】修改k值,以便繼續(xù)向下調整
      }
    }
    array[k] = temp; //被調整的結點的值放人最終位置
  }

堆排序:

//堆排序
  public int[] heapSort(int[] array){
    array = buildMaxHeap(array); //初始建堆,array[0]為第一趟值最大的元素
    for(int i=array.length-1;i>1;i--){ 
      int temp = array[0]; //將堆頂元素和堆低元素交換,即得到當前最大元素正確的排序位置
      array[0] = array[i];
      array[i] = temp;
      adjustDownToUp(array, 0,i); //整理,將剩余的元素整理成堆
    }
    return array;
  }

刪除堆頂元素(即序列中的最大值):先將堆的最后一個元素與堆頂元素交換,由于此時堆的性質被破壞,需對此時的根節(jié)點進行向下調整操作。

//刪除堆頂元素操作
  public int[] deleteMax(int[] array){
    //將堆的最后一個元素與堆頂元素交換,堆底元素值設為-99999
    array[0] = array[array.length-1];
    array[array.length-1] = -99999;
    //對此時的根節(jié)點進行向下調整
    adjustDownToUp(array, 0, array.length);
    return array;
  }

對堆的插入操作:先將新節(jié)點放在堆的末端,再對這個新節(jié)點執(zhí)行向上調整操作。

假設數組的最后一個元素array[array.length-1]為空,新插入的結點初始時放置在此處。

//插入操作:向大根堆array中插入數據data
  public int[] insertData(int[] array, int data){
    array[array.length-1] = data; //將新節(jié)點放在堆的末端
    int k = array.length-1; //需要調整的節(jié)點
    int parent = (k-1)/2;  //雙親節(jié)點
    while(parent >=0 && data>array[parent]){
      array[k] = array[parent]; //雙親節(jié)點下調
      k = parent;
      if(parent != 0){
        parent = (parent-1)/2; //繼續(xù)向上比較
      }else{ //根節(jié)點已調整完畢,跳出循環(huán)
        break;
      }
    }
    array[k] = data; //將插入的結點放到正確的位置
    return array;
  }

測試:

public void toString(int[] array){
    for(int i:array){
      System.out.print(i+" ");
    }
  }
  
  public static void main(String args[]){
    HeapSort hs = new HeapSort();
    int[] array = {87,45,78,32,17,65,53,9,122};
    System.out.print("構建大根堆:");
    hs.toString(hs.buildMaxHeap(array));
    System.out.print("\n"+"刪除堆頂元素:");
    hs.toString(hs.deleteMax(array));
    System.out.print("\n"+"插入元素63:");
    hs.toString(hs.insertData(array, 63));
    System.out.print("\n"+"大根堆排序:");
    hs.toString(hs.heapSort(array));  
  }

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • servlet創(chuàng)建web后端程序的示例代碼

    servlet創(chuàng)建web后端程序的示例代碼

    本文主要介紹了servlet創(chuàng)建web后端程序的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-06-06
  • Spring的懶加載機制原理和配置詳解

    Spring的懶加載機制原理和配置詳解

    這篇文章主要介紹了Spring的懶加載機制原理和配置詳解,Spring提供了懶加載機制,所謂的懶加載機制就是可以規(guī)定指定的bean不在啟動時立即創(chuàng)建,而是在后續(xù)第一次用到時才創(chuàng)建,從而減輕在啟動過程中對時間和內存的消耗,需要的朋友可以參考下
    2023-10-10
  • java排序高級之選擇排序實現方法

    java排序高級之選擇排序實現方法

    這篇文章主要介紹了java排序高級之選擇排序實現方法,較為全面的分析了選擇排序的原理與具體實現技巧,非常具有實用價值,需要的朋友可以參考下
    2015-02-02
  • SpringBoot參數校驗之@Valid與@Validated的用法與場景

    SpringBoot參數校驗之@Valid與@Validated的用法與場景

    這篇文章主要介紹了SpringBoot參數校驗的用法與場景,在實際開發(fā)中,參數校驗是保證接口安全性和數據完整性的重要手段,Spring Boot提供了@Valid和@Validated兩個核心注解來實現參數校驗,但許多開發(fā)者對它們的區(qū)別和使用場景存在疑惑,需要的朋友可以參考下
    2025-02-02
  • 如何獲取包下所有類中的注解的值(java工具類)

    如何獲取包下所有類中的注解的值(java工具類)

    這篇文章主要介紹了如何獲取包下所有類中的注解的值 (java工具類),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java實現聊天室界面

    Java實現聊天室界面

    這篇文章主要為大家詳細介紹了Java實現聊天室界面,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • 詳解Java是如何通過接口來創(chuàng)建代理并進行http請求

    詳解Java是如何通過接口來創(chuàng)建代理并進行http請求

    今天給大家?guī)淼闹R是關于Java的,文章圍繞Java是如何通過接口來創(chuàng)建代理并進行http請求展開,文中有非常詳細的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • JAVA二叉樹的幾種遍歷(遞歸,非遞歸)實現

    JAVA二叉樹的幾種遍歷(遞歸,非遞歸)實現

    這篇文章主要介紹了JAVA二叉樹的幾種遍歷(遞歸,非遞歸)實現,需要的朋友可以參考下
    2020-12-12
  • Spring MVC 404 Not Found無錯誤日志的解決方法

    Spring MVC 404 Not Found無錯誤日志的解決方法

    這篇文章主要為大家詳細介紹了Spring MVC 404 Not Found無錯誤日志的解決方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • Java進階知識之反射的概念與獲取方法

    Java進階知識之反射的概念與獲取方法

    這篇文章主要給大家介紹了關于Java進階知識之反射的概念與獲取方法的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-04-04

最新評論

赤城县| 吉首市| 武城县| 伊吾县| 正镶白旗| 西城区| 望都县| 外汇| 黄冈市| 柳江县| 乳山市| 成武县| 杭州市| 铜陵市| 青浦区| 古田县| 孝义市| 哈密市| 天祝| 应城市| 赞皇县| 突泉县| 互助| 谢通门县| 伊金霍洛旗| 根河市| 长顺县| 固始县| 喀什市| 冕宁县| 德庆县| 民丰县| 虎林市| 合肥市| 枝江市| 临洮县| 兴隆县| 临西县| 河曲县| 巨鹿县| 龙泉市|