日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

树——堆的运用

發布時間:2023/12/20 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 树——堆的运用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

程序=算法+數據結構。今天所學的是“數據結構”中的“樹”。

一、樹的定義、特點、一些概念

(1)定義:任意兩個節點間有且只有一條路徑的無向圖。

(2)特點:任意兩個節點間有且只有一條路徑連接;n個節點有n-1條邊;在樹中增加一條邊會構成回路。

(3)一些概念:根(沒有父節點的節點)、父節點、子節點、葉節點(沒有子節點的節點)、內部節點、深度(從根到節點的層數)。

二、二叉樹

(1)定義:每個節點最多有兩個子節點的樹。

(2)特殊二叉樹:滿二叉樹(每個內部節點都有兩個子節點,即有2^h-1個節點,h為深度);完全二叉樹(即最后一層從右向左連續缺少若干個節點,其余各層都是滿的)。

(3)應用:堆\并查集。

(4)Tip:可以只用一維數組存儲完全二叉樹(此時S型穿插,記圖)。

三、

堆是一種特殊的完全二叉樹,分為最小堆和最大堆。最小堆是所有父節點都比子節點要小的完全二叉樹,最大堆是所有父節點都比子節點要大的完全二叉樹。

1、建立堆

(1)建立最小堆

首先,創建用來存放堆的數組,假如為h[101],堆的大小為n;

接著,讀入n個數據到數組h[ ]中;

最后,對這n個數據進行建堆;

代碼如下:

#include

int h[101];

int n;

void swap(int x,int y)

{

????? int t;

??????t=h[x];

????? h[x]=h[y];

????? h[y]=t;

????? return;

}

void siftdown(int i)

{

????? int t,flag=0;

???? while(i*2<=n&&flag==0)

???? {

???????????? if (h[i]>h[i*2])

??????????????????t=i*2;

???????????? else

??????????????????t=i;//已經用t作為標記,因而t=i或者t=i*2,也就是t編號可能為父節點編號,又可能為左兒子編號

?????????????

???????????? if (i*2+1<=n)

??? ???????????? if(h[t]>=h[i*2+1])//此時可能是父節點編號和右兒子比,也可能是左節點和右節點對比

????????????????????? ?t=i*2+1;

?

?????????????if(t!=i)//因為t表示的是三者(兩者)中最小的編號,而i表示的肯定是父節點的編號,

????????????????????//因此如果兩者不相等,說明有比它更小的

??????????? {

???????????????? ?swap(t,i);

???????????????? ?i=t;//把最小的和它交換

???????????? }

??????????? else

??????????????????flag=1; ??????

?????}

????? return;

}

?

void creat()

{

????? int i;

????? for(i=n/2;i>=1;i--)

?????????? siftdown(i);

??????return;

}

?

int main()

{

???? int i,num;

???? scanf("%d",&num);

? ???for(i=1;i<=num;i++)

????????? scanf("%d",&h[i]);

?????n=num;

??? creat();

???? ……

}

?

(2)建立最大堆

????? 最大堆的建立和最小堆的建立一樣,只是將siftdown( )函數相應的修改,即用t記錄值較大的節點編號。

???????

2、堆的運用——堆排序

(1)利用最大堆排序

????? void heapsort()
????? {
??????????while(n>1)
????????? {
?????????????? swap(1,n);
?????????????? n--;
?????????????? siftdown(1);
???????????}
??????????return;
??????}

??????其中,siftdown( )函數是建立最大堆的函數。經heapsort()函數后,數組h[n]已經從小到大排好順序。

?

(2)利用最小堆排序

??????? int deletemax()
??????? {
????????????? int t;
???????????? ?t=h[1];
???????????? ?h[1]=h[n];
????????????? n--;
????????????? siftdown(1);
??????????????return t;
????????? }

?????????此時的siftdown( )函數是建立最小堆的函數,保證了t值肯定是最小堆的堆頂,也就是數組的最小值。

?

總結

以上是生活随笔為你收集整理的树——堆的运用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。