树——堆的运用
程序=算法+數據結構。今天所學的是“數據結構”中的“樹”。
一、樹的定義、特點、一些概念
(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值肯定是最小堆的堆頂,也就是數組的最小值。
?
總結
- 上一篇: linux中使用网易云音乐
- 下一篇: python分秒换算_度换算成度分秒的P