树:不包含回路的连通无向图
n个结点 n-1条边
根结点 父结点 子结点 叶结点
内部结点:父、子
深度:根结点到这个结点的层数 根为第一层

 

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

二叉树:每个结点最多有两个儿子 左、右儿子
满二叉树、完全二叉树...
满二叉树:二叉树中每个内部结点都有两个儿子  深度:h  结点:2^h-1
完全二叉树:除了最右边位置上有一个或者几个叶结点缺少 其他丰满
如果一个结点有右子结点,一定有左子结点

完全二叉树: 一个父结点:k 左儿子:2*k 右儿子:2*k+1;
左儿子:x 父结点:x/2
N个结点 高度为logn
经典应用:堆:神奇的优先队列:最小堆、最大堆

 最小堆:所有的父结点都比子结点小

向下调整

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(h[t],h[i]);
            i=t;
        }
        else flag=1;
    }
} 

向上调整

void siftup(int i) {
    int flag=0;
    if(i==1) return ;
    while(i!=1&&flag==0) {
        if(h[i]<h[i/2]) swap(h[i],h[i/2]);
        else flag=1;
        i/=2;
    }
}

最小堆从小到大排序

基础树 随笔 第1张
#include<iostream>
#include<algorithm>
using namespace std;
int h[101],n;//n为堆的大小
//最小堆 
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(h[t],h[i]);
            i=t;
        }
        else flag=1;
    }
}
void creat() {//建堆 
    for(int i=n/2;i>=1;i--) siftdown(i);
}

int deletemax() { //删除最大的元素 
    int t=h[1];
    h[1]=h[n--];
    siftdown(1);//向下调整 
    return t;
}

int main() {
    int num;
    cin>>num;
    for(int i=1;i<=num;i++) cin>>h[i];
    
    n=num; //堆的大小 
    
    creat();//建堆 
    
    for(int i=1;i<=num;i++) //删除顶部元素 把最尾的加到顶 
    cout<<deletemax()<<' ';
    return 0;
}
View Code

最大堆从大到小排序

基础树 随笔 第3张
#include<iostream>
#include<algorithm>
using namespace std;
int h[101],n;//n为堆的大小
//最小堆 
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(h[t],h[i]);
            i=t;
        }
        else flag=1;
    }
}
void creat() {//建堆 
    for(int i=n/2;i>=1;i--) siftdown(i);
}
void heapsort() {
    while(n>1) {
        swap(h[1],h[n]);
        n--;
        siftdown(1);
    }
}
int main() {
    int num;
    cin>>num;
    for(int i=1;i<=num;i++) cin>>h[i];
    
    n=num; //堆的大小 
    
    creat();//建堆 
    
    heapsort();
    
    for(int i=1;i<=num;i++) cout<<h[i]<<' ';
    return 0;
}
View Code

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄