樹(shù)與二叉樹(shù)

樹(shù)的性質(zhì)

1.樹(shù)可以沒(méi)有結(jié)點(diǎn),稱為空樹(shù);
2.根結(jié)點(diǎn)為第一層;
3.結(jié)點(diǎn)的子樹(shù)棵數(shù)稱為結(jié)點(diǎn)的度,而樹(shù)中結(jié)點(diǎn)的最大的度稱為樹(shù)的度;
4.有n個(gè)結(jié)點(diǎn)的樹(shù),邊數(shù)一定是n-1,且滿足連通、邊數(shù)等于頂點(diǎn)數(shù)減1的結(jié)構(gòu)一定是一棵樹(shù);
5.葉子結(jié)點(diǎn)被定義為度為0的結(jié)點(diǎn),當(dāng)樹(shù)只有一個(gè)結(jié)點(diǎn)(根結(jié)點(diǎn))時(shí),根結(jié)點(diǎn)也算是葉子結(jié)點(diǎn);

二叉樹(shù)

1.滿二叉樹(shù):每一層的結(jié)點(diǎn)個(gè)數(shù)都達(dá)到了當(dāng)層能達(dá)到的最大結(jié)點(diǎn)數(shù)
2.完全二叉樹(shù):除了最下面一層之外,其余層的結(jié)點(diǎn)個(gè)數(shù)都達(dá)到了當(dāng)層能達(dá)到的最大結(jié)點(diǎn)數(shù),且最下面一層只從左至右連續(xù)存在若干結(jié)點(diǎn),而這些連續(xù)結(jié)點(diǎn)右邊的結(jié)點(diǎn)全部不存在。

二叉樹(shù)的遍歷

1.先序遍歷:根結(jié)點(diǎn)->左子樹(shù)->右子樹(shù)
2.中序遍歷:左子樹(shù)->根結(jié)點(diǎn)->右子樹(shù)
3.后序遍歷:左子樹(shù)->右子樹(shù)->根結(jié)點(diǎn)
4.層次遍歷:從根結(jié)點(diǎn)開(kāi)始從上往下逐層遍歷,對(duì)同一層進(jìn)行從左到右的遍歷

給定后序遍歷和中序遍歷,構(gòu)建二叉樹(shù)

#include<stdio.h>
#include<stdlib.h>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
 
using namespace std;
struct node{
    int data;
    struct node* lchild;
    struct node* rchild; 
};
struct node* create(int postL,int postR,int inL,int inR);
void bfs(struct node* root);
int post[100],in[100];
int main()
{
    int n;
    scanf("%d\n",&n);
    for(int i=0;i<n;++i){
        scanf("%d",&post[i]);
    } 
    for(int j=0;j<n;++j){
        scanf("%d",&in[j]);
    } 
    struct node* root=create(0,n-1,0,n-1);
    bfs(root);//層序遍歷 
    
    
    return 0;
 } 
 
 //當(dāng)前二叉樹(shù)后序序列區(qū)間為[postL,postR],中序序列區(qū)間[inL,inR] 
 struct node* create(int postL,int postR,int inL,int inR){
    if(postL>postR){
        return NULL;
     }
     struct node* root=new node;
     root->data=post[postR];
     int k;
     for( k=inL;k<=inR;++k){
        if(post[postR]==in[k])
        break;
     }
     
     int numleft=k-inL;//左子樹(shù)結(jié)點(diǎn)個(gè)數(shù) 
     root->lchild=create(postL,postL+numleft-1,inL,k-1);
     root->rchild=create(postL+numleft,postR-1,k+1,inR); 
    return root;
 }
 
 void bfs(struct node* root){
    queue<node*> q;
    q.push(root);
    while(!(q.empty())){
        struct node* now=q.front();
        q.pop();
        printf("%d",now->data);
        if(now->lchild!=NULL){
            q.push(now->lchild);
         }
         if(now->rchild!=NULL){
            q.push(now->rchild);
         }
     }
 }
 

給定一棵樹(shù)及所有結(jié)點(diǎn)的權(quán)值,求出所有從根節(jié)點(diǎn)到葉子結(jié)點(diǎn)的路徑,使得每條路徑上權(quán)值之和等于給定常數(shù)s,依次輸出路徑上的權(quán)值。

#include<cstdio>
#include<algorithm> 
#include<vector>
using namespace std;
struct Node{
    int weight;
    vector<int> child;
}node[110];

void dfs(int index,int numNode,int sum); 
bool cmp(int a,int b){
    return node[a].weight>node[b].weight;
}

int path[110];//保存路徑
int n,m,s;//n:結(jié)點(diǎn)數(shù) m:有孩子樹(shù)的結(jié)點(diǎn)數(shù) s:要求的權(quán)值 
int main()
{
    scanf("%d%d%d",&n,&m,&s);
    for(int i=0;i<n;++i){
        scanf("%d",&node[i].weight);//設(shè)置結(jié)點(diǎn)的權(quán)值 
    }
    int id,k;//id:編號(hào) k:孩子數(shù) 
    int child;//孩子編號(hào) 
    //每個(gè)有孩子的結(jié)點(diǎn)
    for(int i=0;i<m;++i){
        scanf("%d%d",&id,&k);//設(shè)置該編號(hào)id的結(jié)點(diǎn)有k個(gè)孩子 
        for(int i=0;i<k;++i){
            scanf("%d",&child);//設(shè)置孩子編號(hào)
            node[id].child.push_back(child); 
        } 
        sort(node[id].child.begin(),node[id].child.end(),cmp);
    } 
    path[0]=0;
    dfs(0,1,node[0].weight);
    
    return 0;
}

void dfs(int index,int numNode,int sum)
{
    if(sum>s){
        return;
    }
    if(sum==s){
        //當(dāng)前結(jié)點(diǎn)是否為葉子結(jié)點(diǎn)
        if(node[index].child.size()!=0){
            return ;
        } 
        for(int i=0;i<numNode;++i){
            printf("%d",node[path[i]].weight);
            if(i<numNode-1){
                printf(" ");
            }
            else{
                printf("\n");
            }
        }
        return ;
    }
    if(sum<s){
        for(int i=0;i<node[index].child.size();++i){
            int child=node[index].child[i];
            path[numNode]=child;
            dfs(child,numNode+1,sum+node[child].weight);
        }
    }
}

二叉查找樹(shù)

二叉查找樹(shù)滿足其左子樹(shù)上所有結(jié)點(diǎn)的數(shù)據(jù)域均小于或等于根節(jié)點(diǎn)的數(shù)據(jù)域,右子樹(shù)上所有結(jié)點(diǎn)的數(shù)據(jù)域均大于根節(jié)點(diǎn)的數(shù)據(jù)域。

給出N個(gè)正整數(shù)來(lái)作為一棵二叉排序樹(shù)的結(jié)點(diǎn)插入順序,問(wèn):這串序列是否是該二叉排序樹(shù)的先序序列或是該二叉排序樹(shù)的鏡像樹(shù)的先序序列,如果是鏡像樹(shù),輸出yes,并輸出對(duì)應(yīng)的樹(shù)的后序序列,否則輸出no

#include<cstdio>
#include<vector>
using namespace std; 
struct node{
    int data;
    struct node* lchild;
    struct node* rchild;
};
void insert(struct node*& root,int data);
void preOrder(struct node* root,vector<int>& vi);
void postOrder(struct node* root,vector<int>& vi);
void preMorder(struct node* root,vector<int>& vi);
void postMorder(struct node* root,vector<int>& vi);
vector<int> origin,pre,post,preM,postM;
int main(){
    int n,data;//結(jié)點(diǎn)個(gè)數(shù) 
    scanf("%d\n",&n);
    struct node* root=NULL;
    for(int i=0;i<n;++i){
        scanf("%d",&data);
        origin.push_back(data);
        insert(root,data);
    }
    preOrder(root,pre);
    preMorder(root,preM);
    postOrder(root,post);
    postMorder(root,postM);
    if(origin==pre){
        printf("yes\n");
        for(int i=0;i<post.size();++i){
            printf("%d ",post[i]);
        }
    }else if(origin==preM){
        printf("yes\n");
        for(int i=0;i<postM.size();++i){
            printf("%d ",postM[i]);
        }
    }
    else{
        printf("no");
    }
    return 0;
} 

void insert(struct node*& root,int data){
    if(root==NULL){
        root=new node;
        root->data=data;
        root->lchild=NULL;
        root->rchild=NULL;
        return ;
    } 
    if(data<root->data){
        insert(root->lchild,data);
    }
    else{
        insert(root->rchild,data);
    }
}
void preOrder(struct node* root,vector<int>& vi){
    if(root==NULL){
        return ;
    }
    vi.push_back(root->data);
    preOrder(root->lchild,vi);
    preOrder(root->rchild,vi);
}

void postOrder(struct node* root,vector<int>& vi){
    if(root==NULL){
        return ;
    }
    postOrder(root->lchild,vi);
    postOrder(root->rchild,vi);
    vi.push_back(root->data);
}

void preMorder(struct node* root,vector<int>& vi){
    if(root==NULL){
        return ;
    }
    vi.push_back(root->data);
    preMorder(root->rchild,vi);
    preMorder(root->lchild,vi);
    
}

void postMorder(struct node* root,vector<int>& vi){
    if(root==NULL){
        return ;
    }
    postMorder(root->rchild,vi);
    postMorder(root->lchild,vi);
    vi.push_back(root->data);
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容