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

C++堆排序算法的實(shí)現(xiàn)方法

 更新時(shí)間:2014年08月14日 09:18:52   投稿:shichen2014  
這篇文章主要介紹了C++堆排序算法的實(shí)現(xiàn)方法,很經(jīng)典的算法,需要的朋友可以參考下

 本文實(shí)例講述了C++實(shí)現(xiàn)堆排序算法的方法,相信對(duì)于大家學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)與算法會(huì)起到一定的幫助作用。具體內(nèi)容如下:

 首先,由于堆排序算法說(shuō)起來(lái)比較長(zhǎng),所以在這里單獨(dú)講一下。堆排序是一種樹(shù)形選擇排序方法,它的特點(diǎn)是:在排序過(guò)程中,將L[n]看成是一棵完全二叉樹(shù)的順序存儲(chǔ)結(jié)構(gòu),利用完全二叉樹(shù)中雙親節(jié)點(diǎn)和孩子節(jié)點(diǎn)之間的內(nèi)在關(guān)系,在當(dāng)前無(wú)序區(qū)中選擇關(guān)鍵字最大(或最?。┑脑?。

一、堆的定義

堆的定義如下:n個(gè)關(guān)鍵字序列L[n]成為堆,當(dāng)且僅當(dāng)該序列滿(mǎn)足:
①L(i) <= L(2i)且L(i) <= L(2i+1)  或者  ②L(i) >= L(2i)且L(i) >= L(2i+1)   其中i屬于[1, n/2]。

滿(mǎn)足第①種情況的堆稱(chēng)為小根堆(小頂堆),滿(mǎn)足第②種情況的堆稱(chēng)為大根堆(大頂堆)。在大根堆中,最大元素存放在根結(jié)點(diǎn)中,且對(duì)任一非根結(jié)點(diǎn),它的值小于或等于其雙親結(jié)點(diǎn)值。小根堆則恰恰相反,小根堆的根結(jié)點(diǎn)存放的是最小元素。例如{16, 14, 10, 8, 7, 9, 3, 2}表示的大根堆:

                                 

二、構(gòu)造初始堆

堆排序的關(guān)鍵就是構(gòu)造初始堆。n個(gè)結(jié)點(diǎn)的完全二叉樹(shù)中,最后一個(gè)結(jié)點(diǎn)是第n/2(向下取整)個(gè)結(jié)點(diǎn)的孩子。所以構(gòu)造初始堆的流程是:對(duì)第n/2(向下取整)個(gè)結(jié)點(diǎn)為根的子樹(shù)進(jìn)行篩選(以大根堆為例,若根結(jié)點(diǎn)的關(guān)鍵字小于左右子女中關(guān)鍵字的較大者,則交換),使該子樹(shù)成為堆。之后向前依次對(duì)從n/2-1到1的各結(jié)點(diǎn)為根的子樹(shù)進(jìn)行篩選,看該結(jié)點(diǎn)值是否大于其左右子結(jié)點(diǎn)的值,若不是,將左右子結(jié)點(diǎn)中較大值與之交換,交換后可能會(huì)破壞下一級(jí)的堆,于是繼續(xù)采用上述方法構(gòu)造下一級(jí)的堆,直到以該結(jié)點(diǎn)為根的子樹(shù)構(gòu)成堆為止。反復(fù)利用上述調(diào)整堆的方法建堆,直到根結(jié)點(diǎn)。

由于在數(shù)組中下標(biāo)從0開(kāi)始,所以在堆中i的左子結(jié)點(diǎn)為2*i+1,右子結(jié)點(diǎn)為2*i+2。下面是將某個(gè)結(jié)點(diǎn)i向下調(diào)整建堆的算法實(shí)現(xiàn):

void AdjustDown(ElementType A[], int i, int len) 
{ 
  ElementType temp = A[i]; // 暫存A[i] 
   
  for(int largest=2*i+1; largest<len; largest=2*largest+1) 
  { 
    if(largest!=len-1 && A[largest+1]>A[largest]) 
      ++largest;     // 如果右子結(jié)點(diǎn)大 
    if(temp < A[largest]) 
    { 
      A[i] = A[largest]; 
      i = largest;     // 記錄交換后的位置 
    } 
    else 
      break; 
  } 
  A[i] = temp;  // 被篩選結(jié)點(diǎn)的值放入最終位置 
} 
 

建堆,從n/2(向下取整)到1依次對(duì)各結(jié)點(diǎn)向下調(diào)整,當(dāng)然由于數(shù)組下標(biāo)從0開(kāi)始,所以:

void BuildMaxHeap(ElementType A[], int len) 
{ 
  for(int i=len/2-1; i>=0; --i) // 從i=n/2-1到0,反復(fù)調(diào)整堆 
    AdjustDown(A, i, len); 
} 

三、堆排序

構(gòu)造初始堆成功以后,堆排序的思路就很簡(jiǎn)單了:首先將存放在L[n]中的n個(gè)元素建成初始堆,由于堆本身的特點(diǎn)(以大根堆為例),堆頂元素就是最大值。輸出堆頂元素后,通常將堆底元素送入堆頂,此時(shí)根結(jié)點(diǎn)已不滿(mǎn)足大根堆的性質(zhì),堆被破壞。這時(shí)將堆頂元素向下調(diào)整使其繼續(xù)保持大根堆的性質(zhì),再輸出堆頂元素。如此重復(fù),直到堆中僅剩下一個(gè)元素為止。算法實(shí)現(xiàn)如下:

void HeapSort(ElementType A[], int n) 
{ 
  BuildMaxHeap(A, n);    // 初始建堆 
  for(int i=n-1; i>0; --i) // n-1趟的交換和建堆過(guò)程  
  { 
    // 輸出最大的堆頂元素(和堆底元素交換) 
    A[0] = A[0]^A[i]; 
    A[i] = A[0]^A[i]; 
    A[0] = A[0]^A[i]; 
    // 調(diào)整,把剩余的n-1個(gè)元素整理成堆 
    AdjustDown(A, 0, i);   
  } 
} 

四、性能分析

時(shí)間復(fù)雜度:向下調(diào)整的時(shí)間與樹(shù)高有關(guān),為O(h)??梢宰C明在元素個(gè)數(shù)為n的序列上建堆,其時(shí)間復(fù)雜度為O(n)。之后還有n-1次向下調(diào)整操作,每次調(diào)整的時(shí)間為O(h),故在最好,最壞和平均情況下,堆排序的時(shí)間復(fù)雜度為O(nlogn)。

空間復(fù)雜度:僅使用了常數(shù)個(gè)輔助單元,空間復(fù)雜度為O(1)。

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

相關(guān)文章

  • C++ 實(shí)現(xiàn)哈希表的實(shí)例

    C++ 實(shí)現(xiàn)哈希表的實(shí)例

    這篇文章主要介紹了C++ 實(shí)現(xiàn)哈希表的實(shí)例的相關(guān)資料,這里使用C++實(shí)現(xiàn)哈希表的實(shí)例幫助大家徹底理解哈希表的原理,需要的朋友可以參考下
    2017-08-08
  • QT線(xiàn)程QThread的使用介紹

    QT線(xiàn)程QThread的使用介紹

    在進(jìn)行桌面應(yīng)用程序開(kāi)發(fā)的時(shí)候,假設(shè)程序在某些情況要處理復(fù)雜邏輯, 如果一個(gè)線(xiàn)程去處理,就會(huì)導(dǎo)致窗口卡頓,無(wú)法處理用戶(hù)操作。這就需要使用多線(xiàn)程,其中一個(gè)線(xiàn)程處理窗口事件,其他線(xiàn)程進(jìn)行邏輯運(yùn)算,多個(gè)線(xiàn)程各司其職,不僅可以提高用戶(hù)體驗(yàn)還可以提升程序的執(zhí)行效率
    2022-09-09
  • 淺析C++內(nèi)存布局

    淺析C++內(nèi)存布局

    本文給大家介紹了C++內(nèi)存布局的相關(guān)知識(shí),通過(guò)進(jìn)程間通信比線(xiàn)程間通信難也是因?yàn)檫M(jìn)程間的用戶(hù)空間是相互隔離的,無(wú)法相互訪(fǎng)問(wèn),需要通過(guò)進(jìn)程間通信方式通信,通過(guò)內(nèi)核地址空間
    2021-10-10
  • C++繼承介紹

    C++繼承介紹

    C++繼承可以是單一繼承或多重繼承,每一個(gè)繼承連接可以是public,protected,private也可以是virtual或non-virtual
    2013-01-01
  • 虛函數(shù)被類(lèi)的構(gòu)造析構(gòu)函數(shù)和成員函數(shù)調(diào)用虛函數(shù)的執(zhí)行過(guò)程

    虛函數(shù)被類(lèi)的構(gòu)造析構(gòu)函數(shù)和成員函數(shù)調(diào)用虛函數(shù)的執(zhí)行過(guò)程

    虛函數(shù)被類(lèi)的構(gòu)造析構(gòu)函數(shù)和成員函數(shù)調(diào)用虛函數(shù)的執(zhí)行過(guò)程,需要的朋友可以參考下
    2013-02-02
  • 深入理解C語(yǔ)言中使用頻率較高的指針與數(shù)組

    深入理解C語(yǔ)言中使用頻率較高的指針與數(shù)組

    在C語(yǔ)言中要說(shuō)到哪一部分最難搞,首當(dāng)其沖就是指針,指針永遠(yuǎn)是個(gè)讓人又愛(ài)又恨的東西,用好了可以事半功倍,用不好就會(huì)有改不完的bug和通不完的宵,下面這篇文章主要給大家介紹了關(guān)于C語(yǔ)言中使用頻率較高的指針與數(shù)組的相關(guān)資料,需要的朋友可以參考下
    2022-03-03
  • c++ 深入理解歸并排序的用法

    c++ 深入理解歸并排序的用法

    歸并排序是典型分治思想的代表——首先把原問(wèn)題分解為兩個(gè)或多個(gè)子問(wèn)題,然后求解子問(wèn)題的解,最后使用子問(wèn)題的解來(lái)構(gòu)造出原問(wèn)題的解
    2022-03-03
  • 華為機(jī)試題之統(tǒng)計(jì)單詞個(gè)數(shù)實(shí)例代碼

    華為機(jī)試題之統(tǒng)計(jì)單詞個(gè)數(shù)實(shí)例代碼

    這篇文章主要介紹了華為機(jī)試題之統(tǒng)計(jì)單詞個(gè)數(shù)實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • C++?Boost?CircularBuffer算法超詳細(xì)精講

    C++?Boost?CircularBuffer算法超詳細(xì)精講

    Boost是為C++語(yǔ)言標(biāo)準(zhǔn)庫(kù)提供擴(kuò)展的一些C++程序庫(kù)的總稱(chēng)。Boost庫(kù)是一個(gè)可移植、提供源代碼的C++庫(kù),作為標(biāo)準(zhǔn)庫(kù)的后備,是C++標(biāo)準(zhǔn)化進(jìn)程的開(kāi)發(fā)引擎之一,是為C++語(yǔ)言標(biāo)準(zhǔn)庫(kù)提供擴(kuò)展的一些C++程序庫(kù)的總稱(chēng)
    2022-11-11
  • Sersync+Rsync實(shí)現(xiàn)觸發(fā)式文件同步實(shí)戰(zhàn)過(guò)程

    Sersync+Rsync實(shí)現(xiàn)觸發(fā)式文件同步實(shí)戰(zhàn)過(guò)程

    sersync是使用c++編寫(xiě),而且對(duì)linux系統(tǒng)文 件系統(tǒng)產(chǎn)生的臨時(shí)文件和重復(fù)的文件操作進(jìn)行過(guò)濾。下面通過(guò)本文給大家分享Sersync+Rsync實(shí)現(xiàn)觸發(fā)式文件同步實(shí)戰(zhàn)過(guò)程,需要的朋友參考下吧
    2017-09-09

最新評(píng)論

定日县| 舞钢市| 颍上县| 福州市| 南木林县| 夏河县| 崇仁县| 科尔| 鸡泽县| 太仓市| 准格尔旗| 六盘水市| 曲沃县| 日喀则市| 余江县| 故城县| 阳城县| 鲁山县| 潼南县| 鹰潭市| 天长市| 化德县| 桃源县| 和硕县| 如皋市| 乌兰浩特市| 湖州市| 华坪县| 安国市| 涞源县| 曲松县| 河西区| 色达县| 铅山县| 龙江县| 东辽县| 昌图县| 鲜城| 大兴区| 贺州市| 元阳县|