欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

堆排序算法(選擇排序改進)

 更新時間:2014年01月09日 15:08:44   作者:  
這篇文章主要介紹了堆排序算法(選擇排序改進),有需要的朋友可以參考一下

首先要理解堆的含義:要么所有節(jié)點都不大于其子孩子節(jié)點數(shù)據(jù),要么都不小于其子孩子節(jié)點數(shù)據(jù)

堆排序的核心思想:就是要滿足所有節(jié)點都滿足上面兩點,如何完成,看下面

堆排序的步驟:

1.首先要建成一個大頂堆或者小頂堆,在建的過程中其實就是調整節(jié)點的位置,首先要從最后最后一個節(jié)點的母親節(jié)點開始,按照堆的含義調整。為什么不是最后一個或者其他?因為要保證完整性和不必要性,所以只需從最后一個的母親節(jié)點開始即可(下面的堆默認存在順序結構,從索引0開始的,所以有些二叉樹的特性請查閱二叉樹),直至索引節(jié)點為0的節(jié)點。調整完成后即成為一個堆,但是這里的數(shù)據(jù)并沒有排序好,所以下一部調整順序。

2.從最后一個數(shù)據(jù)開始,與第一個數(shù)據(jù)進行交換,然后按照堆的含義調整第一個數(shù)據(jù)。為什么先選擇最后一個數(shù)據(jù)?因為默認情況下,最后一個或者是較大或者是較小,可以滿足調整要求。這時就考慮當前所有數(shù)據(jù)減去最后一個,因為這個已是最大或者是最小,不必再考慮.。直至調整沒有任何數(shù)據(jù),此時已完成排序。

具體圖例不再標識,有此愛好可以參考其他書籍或者網上的介紹,下面看堆排序代碼:

復制代碼 代碼如下:

int HeapSort(MergeType* L)
{
 int i = 0;
 if (!L->elem)
 {
  return -1;
 }

 //創(chuàng)建堆
 for (int i = L->len/2-1; i >= 0; i--)
 {
  HeapAdjust(L, i, L->len-1);
 }

 //堆排序
 for (i = L->len-1; i >= 0; i-- )
 {
  swap(L->elem[i], L->elem[0]);
  HeapAdjust(L, 0, i-1);
 }
 return 0; 
}

注意:
1)由于父子節(jié)點的關系,for循環(huán)第一個數(shù)據(jù)索引其實是L,len-1,但是其父母節(jié)點(i)與 當前節(jié)點(p)的關系:p = 2i+1 或者2i+2; 如果存儲數(shù)據(jù)的節(jié)點第一個索引不是0而是1,這里p=2i或者p=2i+1,請參看有關書籍的證明,所以當前父母節(jié)點:i =(p-1)/ 2 = (L.len-1-1)/2 = L.len/2-1

2)由于再次調整數(shù)據(jù)的時候是從最后一個數(shù)據(jù),所以需要交換數(shù)據(jù)swap,再進行當前頂點數(shù)據(jù)也就是第一個數(shù)據(jù)的堆調整,但是此時調整的對象只是(0~i)這些數(shù)據(jù),其他已經排序好,所以不再需要調整

下面看一下調整代碼,如下:

復制代碼 代碼如下:

int HeapAdjust(MergeType* L, int nPos, int nEnd)
{
 for (int i = nPos*2+1; i < nEnd ; i = 2*i+1)
 {
  if (L->elem[i] <= L->elem[i+1])
  {
   i++;
  }
  if (L->elem[nPos] >= L->elem[i])
  {
   break;
  }
  swap(L->elem[nPos], L->elem[i]);
  nPos = i;
 }
 return 0;
}

這里使用的是在一個層次上是數(shù)據(jù)直接交換,其實這不是必須的,因為最后才把數(shù)據(jù)放到最后的位置,所以也可以使用下面的代碼,減少復制的次數(shù)

復制代碼 代碼如下:

int HeapAdjustEx(MergeType* L, int nPos, int nEnd)
{
 int nTempkey = L->elem[nPos];

 for (int i = nPos*2+1; i < nEnd ; i = 2*i+1)
 {
  if (L->elem[i] <= L->elem[i+1])//選出最大的子孩子
  {
   i++;
  }
  if (nTempkey >= L->elem[i]) //如果當前節(jié)點大于最大子孩子退出
  {
   break;
  }
  L->elem[nPos] = L->elem[i]; //否則進行數(shù)據(jù)交換
  nPos = i;
 }
 L->elem[nPos] = nTempkey;
 return 0;
}

這里就可以減少較多的復制操作,也就是俗稱的移動操作次數(shù);這里for循環(huán)的起始節(jié)點按照上面的推論,子節(jié)點應該為p=2i+1,所以第一個應該為2*nPos+1,對應當前要比較節(jié)點的做孩子,右孩子為2*nPos+2,也就是左孩子+1,其他請看注釋。
時間復雜度:O(nlogn),分析過程暫略

相關文章

  • 基于C語言實現(xiàn)簡單的走迷宮游戲

    基于C語言實現(xiàn)簡單的走迷宮游戲

    這篇文章主要介紹了基于C語言實現(xiàn)簡單的走迷宮游戲,用到雙向隊列,方便在運行完畢后輸出經過的點,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-04-04
  • C++求最大公約數(shù)四種方法解析

    C++求最大公約數(shù)四種方法解析

    這篇文章主要為大家詳細介紹了C++求最大公約數(shù)四種方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-09-09
  • C語言實現(xiàn)BF算法案例詳解

    C語言實現(xiàn)BF算法案例詳解

    這篇文章主要介紹了C語言實現(xiàn)BF算法案例詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下
    2021-08-08
  • C++11中條件標量和互斥鎖應用出現(xiàn)死鎖問題

    C++11中條件標量和互斥鎖應用出現(xiàn)死鎖問題

    這篇文章主要介紹了C++11中條件標量和互斥鎖應用出現(xiàn)死鎖思考,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-06-06
  • OPENMP?SECTIONS?CONSTRUCT原理示例解析

    OPENMP?SECTIONS?CONSTRUCT原理示例解析

    這篇文章主要為大家介紹了OPENMP?SECTIONS?CONSTRUCT原理示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-03-03
  • 帶你粗略了解C++中的深淺拷貝

    帶你粗略了解C++中的深淺拷貝

    這篇文章主要給大家介紹了關于c++中深淺拷貝以及寫時拷貝實現(xiàn)的相關資料,文中通過示例代碼介紹的非常詳細,對大家具有一定的參考學習價值,需要的朋友們下面跟著小編來一起學習學習吧
    2021-08-08
  • 使用C++繪制GDI位圖的基本編寫實例

    使用C++繪制GDI位圖的基本編寫實例

    這篇文章主要介紹了使用C++繪制GDI位圖的基本編寫實例,一般來說適用于Windwos下的C++的GUI編程,需要的朋友可以參考下
    2015-12-12
  • C語言不使用strcpy函數(shù)如何實現(xiàn)字符串復制功能

    C語言不使用strcpy函數(shù)如何實現(xiàn)字符串復制功能

    這篇文章主要給大家介紹了關于C語言不使用strcpy函數(shù)如何實現(xiàn)字符串復制功能的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-02-02
  • C++中的幾種排序算法

    C++中的幾種排序算法

    這篇文章主要介紹了C++中的幾種排序算法,需要的朋友可以參考下
    2014-02-02
  • 基于C/C++將派生類賦值給基類的超詳細講解

    基于C/C++將派生類賦值給基類的超詳細講解

    類其實也是一種數(shù)據(jù)類型,也可以發(fā)生數(shù)據(jù)類型轉換,下面這篇文章主要給大家介紹了關于基于C/C++將派生類賦值給基類的超詳細講解,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-06-06

最新評論