1.树是指任意两个结点之间有且只有一条路径的无向图,只要没有回路的联通无向图就是树。
2.没有父结点的的结点称为根结点,无子结点的称为叶结点。
3.二叉树。
a,满二叉树:树中每个内部结点都有左右结点,即所有的叶结点都具有相同的深度。
b,完全二叉树:如果树内部的结点有右子结点的话就一定有左子结点,则称为完全二叉树,左子结点的编号为2k,右子结点的编号为2k+1.
4.堆:一种特殊的完全二叉树:所有父结点都比子结点大或者小。、
a,将一个数放到最小堆堆顶,重新得出最小堆。
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;
if(i*2+1<=n){//判断是否有右结点
if(h[t]>h[i*2+1])
t=i*2+1;
}
if(t!=i){//判断最小结点是不是自己,是的话说明子结点有比父结点更小的
swap(t,i);
i=t;
}
else
flag=1;
}
return;
}
b,将一个数插入到堆得最末端,求最小堆
void siftdown(int i){
int flag=0;
if(i==1) return;//判断是否已经到达堆顶
while(i!=1&&rflag==0){
if(h[i]<h(i/2))
swap(i,i/2);
else
flag=1;
i=i/2;//更新编号i为它父结点的编号
}
return;
}
c,如何建立一个堆。
从空的堆开始,然后依次往堆中插入每一个元素,直到所有的元素被插入。
for(n=1;n<=m;n++){
scanf("%d",&h[n]);//其中h[n]为全局变量
siftup(n);//通过这个函数建立一个最小栈
}
d,建堆及堆排序
#include<stdio.h>
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;
if(i*2+1<=n){
if(h[t]>h[i*2+1]){
t=i*2+1;
}
}
if(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 deletemax(){
int t;
t=h[1];
h[1]=h[n];
n--;
siftdown(1);
return t;
}
int main(void){
int i,num;
scanf("%d",&num);
for(i=1;i<=num;i++)
scanf("%d",&h[i]);
n=num;
creat();
for(i=1;i<=num;i++)
printf("%d ",deletemax());
}