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

堆排序算法(選擇排序改進(jìn))

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

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

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

堆排序的步驟:

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

2.從最后一個(gè)數(shù)據(jù)開(kāi)始,與第一個(gè)數(shù)據(jù)進(jìn)行交換,然后按照堆的含義調(diào)整第一個(gè)數(shù)據(jù)。為什么先選擇最后一個(gè)數(shù)據(jù)?因?yàn)槟J(rèn)情況下,最后一個(gè)或者是較大或者是較小,可以滿足調(diào)整要求。這時(shí)就考慮當(dāng)前所有數(shù)據(jù)減去最后一個(gè),因?yàn)檫@個(gè)已是最大或者是最小,不必再考慮.。直至調(diào)整沒(méi)有任何數(shù)據(jù),此時(shí)已完成排序。

具體圖例不再標(biāo)識(shí),有此愛(ài)好可以參考其他書(shū)籍或者網(wǎng)上的介紹,下面看堆排序代碼:

復(fù)制代碼 代碼如下:

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é)點(diǎn)的關(guān)系,for循環(huán)第一個(gè)數(shù)據(jù)索引其實(shí)是L,len-1,但是其父母節(jié)點(diǎn)(i)與 當(dāng)前節(jié)點(diǎn)(p)的關(guān)系:p = 2i+1 或者2i+2; 如果存儲(chǔ)數(shù)據(jù)的節(jié)點(diǎn)第一個(gè)索引不是0而是1,這里p=2i或者p=2i+1,請(qǐng)參看有關(guān)書(shū)籍的證明,所以當(dāng)前父母節(jié)點(diǎn):i =(p-1)/ 2 = (L.len-1-1)/2 = L.len/2-1

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

下面看一下調(diào)整代碼,如下:

復(fù)制代碼 代碼如下:

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;
}

這里使用的是在一個(gè)層次上是數(shù)據(jù)直接交換,其實(shí)這不是必須的,因?yàn)樽詈蟛虐褦?shù)據(jù)放到最后的位置,所以也可以使用下面的代碼,減少?gòu)?fù)制的次數(shù)

復(fù)制代碼 代碼如下:

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]) //如果當(dāng)前節(jié)點(diǎn)大于最大子孩子退出
  {
   break;
  }
  L->elem[nPos] = L->elem[i]; //否則進(jìn)行數(shù)據(jù)交換
  nPos = i;
 }
 L->elem[nPos] = nTempkey;
 return 0;
}

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

相關(guān)文章

  • C語(yǔ)言Static?關(guān)鍵字解析

    C語(yǔ)言Static?關(guān)鍵字解析

    這篇文章主要介紹了C語(yǔ)言Static?關(guān)鍵字解析,C語(yǔ)言中staic關(guān)鍵字很簡(jiǎn)單,簡(jiǎn)單到你的任何一個(gè)項(xiàng)目中可以不寫(xiě)一個(gè)staic關(guān)鍵字也是沒(méi)有問(wèn)題的。寫(xiě)這篇章主要是一下自己的staic的理解和應(yīng)用,當(dāng)然在章開(kāi)頭依舊要照本宣科簡(jiǎn)述一下static關(guān)鍵字,需要的朋友可以參考一下
    2022-02-02
  • C++中的覆蓋和隱藏詳解

    C++中的覆蓋和隱藏詳解

    這篇文章主要介紹了C++中重載、重寫(xiě)(覆蓋)和隱藏的區(qū)別,是C++面向?qū)ο蟪绦蛟O(shè)計(jì)非常重要的概念,需要的朋友可以參考下,希望能夠給你帶來(lái)幫助
    2021-08-08
  • C++面試題之結(jié)構(gòu)體內(nèi)存對(duì)齊計(jì)算問(wèn)題總結(jié)大全

    C++面試題之結(jié)構(gòu)體內(nèi)存對(duì)齊計(jì)算問(wèn)題總結(jié)大全

    這篇文章主要給大家總結(jié)了關(guān)于C++面試題中結(jié)構(gòu)體內(nèi)存對(duì)齊計(jì)算問(wèn)題的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),通過(guò)這些介紹的內(nèi)容對(duì)大家在面試C++工作的時(shí)候,會(huì)有一定的參考幫助,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-08-08
  • C語(yǔ)言與JAVA的區(qū)別是什么(推薦)

    C語(yǔ)言與JAVA的區(qū)別是什么(推薦)

    本文是小編給大家收集整理的關(guān)于C語(yǔ)言與Java的區(qū)別介紹,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧
    2017-04-04
  • C++編程使用findfirst和findnext查找及遍歷文件實(shí)現(xiàn)示例

    C++編程使用findfirst和findnext查找及遍歷文件實(shí)現(xiàn)示例

    這篇文章主要為大家介紹了C++編程如何使用findfirst和findnext查找及遍歷文件實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2021-10-10
  • C++中的pair使用詳解

    C++中的pair使用詳解

    pair是定義在<utility>中的生成特定類型的模板,它的作用是把一組數(shù)據(jù)合并為一體,實(shí)際上是一個(gè)擁有兩個(gè)成員變量的struct,這篇文章主要介紹了c++的pair使用,需要的朋友可以參考下
    2022-09-09
  • VC枚舉串口端口應(yīng)用

    VC枚舉串口端口應(yīng)用

    這篇文章主要介紹了VC枚舉串口端口應(yīng)用,羅列了常見(jiàn)的一些串口端口的應(yīng)用實(shí)例,需要的朋友可以參考下
    2014-10-10
  • 帶你了解如何用C++合并兩個(gè)有序鏈表

    帶你了解如何用C++合并兩個(gè)有序鏈表

    這篇文章主要介紹了c++ 如何合并兩個(gè)有序鏈表,小編感覺(jué)這篇文章還不錯(cuò),希望能幫助大家更好的理解和學(xué)習(xí)C++,感興趣的朋友可以了解下
    2021-08-08
  • C語(yǔ)言詳細(xì)講解二分查找用法

    C語(yǔ)言詳細(xì)講解二分查找用法

    二分查找法,又叫做折半查找法,它是一種效率較高的查找方法。但是,折半查找要求線性表必須采用順序存儲(chǔ)結(jié)構(gòu),而且表中元素按關(guān)鍵字有序排列
    2022-04-04
  • C語(yǔ)言實(shí)現(xiàn)無(wú)頭單向鏈表的示例代碼

    C語(yǔ)言實(shí)現(xiàn)無(wú)頭單向鏈表的示例代碼

    本文主要介紹了C語(yǔ)言實(shí)現(xiàn)無(wú)頭單向鏈表的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09

最新評(píng)論

皮山县| 木兰县| 宝丰县| 三台县| 兴国县| 盱眙县| 晋中市| 德令哈市| 临颍县| 资阳市| 康马县| 阿克苏市| 汝城县| 兰溪市| 横山县| 繁昌县| 乌拉特后旗| 吴江市| 乌拉特前旗| 文化| 高邑县| 陵水| 石楼县| 呈贡县| 祁阳县| 大厂| 中卫市| 定边县| 十堰市| 承德市| 河津市| 长岛县| 永清县| 石屏县| 瓮安县| 会东县| 兴海县| 澄迈县| 正阳县| 浮梁县| 东平县|