C語(yǔ)言 數(shù)據(jù)結(jié)構(gòu)堆排序順序存儲(chǔ)(升序)
堆排序順序存儲(chǔ)(升序)
一: 完全二叉樹(shù)的概念:前h-1層為滿二叉樹(shù),最后一層連續(xù)缺失右結(jié)點(diǎn)!
二:首先堆是一棵全完二叉樹(shù):
a:構(gòu)建一個(gè)堆分為兩步:⑴創(chuàng)建一棵完全二叉樹(shù) ⑵調(diào)整為一個(gè)堆
(標(biāo)注:大根堆為升序,小根堆為降序)
b:算法描述:①創(chuàng)建一棵完全二叉樹(shù)
②while(有雙親){
A:調(diào)整為大根堆;
B:交換根和葉子結(jié)點(diǎn);
C:砍掉葉子結(jié)點(diǎn);
}
c:時(shí)間復(fù)雜度為 O(nlogn) ,空間復(fù)雜度為 O(1), 是不穩(wěn)定排序!
代碼實(shí)現(xiàn):
/*堆排序思想:[完全二叉樹(shù)的定義:前 h-1 層為滿二叉樹(shù)一最后一層連續(xù)缺失右結(jié)點(diǎn)(即右子女)],(大根堆升序排序,小根堆降序排列) 首先堆是一個(gè)完全二叉樹(shù) ,根據(jù)數(shù)組下標(biāo)就可建成了一棵完全二叉樹(shù) 其次:while(有雙親){ A: 調(diào)整為一個(gè)大根堆 【Adjust()函數(shù)實(shí)現(xiàn)】 B: 交換最后一個(gè)葉子結(jié)點(diǎn)和根結(jié)點(diǎn) 【Swap()函數(shù)實(shí)現(xiàn)】 C: 砍掉最后一個(gè)葉子結(jié)點(diǎn) 【即元素個(gè)數(shù) n--】 } */ #include <iostream> #define N 100 using namespace std; int b[N]={0}; //存儲(chǔ)數(shù)據(jù)的數(shù)組 int n=0; //記錄數(shù)據(jù)的總個(gè)數(shù)【0單元不要,實(shí)際元素個(gè)數(shù)為(n-1)個(gè)】 void Swap(int *x,int *y){ int t; t=*x; *x=*y; *y=t; } void Adjust(){ int p; //記錄雙親結(jié)點(diǎn) int tag=1; //記錄是否已經(jīng)調(diào)整為大根堆(標(biāo)志性的變量) while(tag){ //判斷是否已經(jīng)調(diào)整好為大根堆 p=(n-1)/2; //最后一個(gè)雙親結(jié)點(diǎn)的下標(biāo) tag=0; //凡是交換后,tag=1,標(biāo)志著還沒(méi)有調(diào)整為大根堆,否則繼續(xù)調(diào)整 while(p>0){ //確保有雙親結(jié)點(diǎn) if(b[p]<b[2*p]){ //若根結(jié)點(diǎn)大于左子女結(jié)點(diǎn),就交換 Swap(&b[p],&b[2*p]); tag=1; } if(2*p+1<n && b[p]<b[2*p+1]){ //若存在右子女,并且根結(jié)點(diǎn)大于右子女結(jié)點(diǎn),就交換 Swap(&b[p],&b[2*p+1]); tag=1; } p--; //直到最后一個(gè)雙親結(jié)點(diǎn)調(diào)整完 } } } void HeapSort(){ while(n>2){ //保證有雙親結(jié)點(diǎn) Adjust(); //調(diào)整大根堆函數(shù) Swap(&b[1],&b[n-1]); //將最后一個(gè)葉子結(jié)點(diǎn)和根結(jié)點(diǎn)交換 n--; //裁剪最后的葉子結(jié)點(diǎn) } } int main(void){ int i,m; cout<<"請(qǐng)輸入數(shù)據(jù)的總數(shù)【0單元不要,實(shí)際元素個(gè)數(shù)為(n-1)個(gè)】:"<<endl; cin>>n; m=n; cout<<"請(qǐng)輸入各個(gè)數(shù)據(jù)【0單元不要,實(shí)際元素個(gè)數(shù)為(n-1)個(gè)】:"<<endl; b[0]=0; for(i=1;i<n;i++){ cin>>b[i]; } HeapSort(); //堆排序 cout<<"大根堆升序排列為:"<<endl; for(i=1;i<m;i++){ cout<<b[i]<<" "; } cout<<endl; return 0; }
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
相關(guān)文章
C++實(shí)現(xiàn)CreatThread函數(shù)主線程與工作線程交互的方法
這篇文章主要介紹了C++實(shí)現(xiàn)CreatThread函數(shù)主線程與工作線程交互的方法,是Windows應(yīng)用程序設(shè)計(jì)中非常實(shí)用的方法,需要的朋友可以參考下2014-10-10C/C++?單元自動(dòng)化測(cè)試解決方案總結(jié)
這篇文章主要介紹了C/C++?單元自動(dòng)化測(cè)試解決方案總結(jié),通過(guò)利用GCC插件來(lái)實(shí)現(xiàn)提升C/C++開(kāi)發(fā)者的單元效率工具解決方案,希望對(duì)大家在提升單元測(cè)試效率上有所啟發(fā)2022-06-06詳解C++ 動(dòng)態(tài)內(nèi)存分配與命名空間
這篇文章主要介紹了詳解C++ 動(dòng)態(tài)內(nèi)存分配與命名空間,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-08-08C++實(shí)現(xiàn)單例模式的自動(dòng)釋放
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)單例模式的自動(dòng)釋放,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06C語(yǔ)言詳解float類型在內(nèi)存中的存儲(chǔ)方式
在c語(yǔ)言中float函數(shù)是單精度的。它在內(nèi)存中以二進(jìn)制的形式存儲(chǔ)。分為符號(hào)位,階碼與尾數(shù)三部分,下面我們?cè)敿?xì)來(lái)了解一下2022-04-04深入了解C語(yǔ)言中的動(dòng)態(tài)內(nèi)存分配
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言中的動(dòng)態(tài)內(nèi)存分配,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C語(yǔ)言有一定的幫助,需要的可以參考一下2022-06-06C++實(shí)現(xiàn)簡(jiǎn)單的計(jì)算器小功能
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)簡(jiǎn)單的計(jì)算器小功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02C++稀疏矩陣的各種基本運(yùn)算并實(shí)現(xiàn)加法乘法
今天小編就為大家分享一篇關(guān)于C++稀疏矩陣的各種基本運(yùn)算并實(shí)現(xiàn)加法乘法,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-02-02