树与二叉树

树的性质

1.树可以没有结点,称为空树;
2.根结点为第一层;
3.结点的子树棵数称为结点的度,而树中结点的最大的度称为树的度;
4.有n个结点的树,边数一定是n-1,且满足连通、边数等于顶点数减1的结构一定是一棵树;
5.叶子结点被定义为度为0的结点,当树只有一个结点(根结点)时,根结点也算是叶子结点;

二叉树

1.满二叉树:每一层的结点个数都达到了当层能达到的最大结点数
2.完全二叉树:除了最下面一层之外,其余层的结点个数都达到了当层能达到的最大结点数,且最下面一层只从左至右连续存在若干结点,而这些连续结点右边的结点全部不存在。

二叉树的遍历

1.先序遍历:根结点->左子树->右子树
2.中序遍历:左子树->根结点->右子树
3.后序遍历:左子树->右子树->根结点
4.层次遍历:从根结点开始从上往下逐层遍历,对同一层进行从左到右的遍历

给定后序遍历和中序遍历,构建二叉树

#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;
 } 
 
 //当前二叉树后序序列区间为[postL,postR],中序序列区间[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;//左子树结点个数 
     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);
         }
     }
 }
 

给定一棵树及所有结点的权值,求出所有从根节点到叶子结点的路径,使得每条路径上权值之和等于给定常数s,依次输出路径上的权值。

#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:结点数 m:有孩子树的结点数 s:要求的权值 
int main()
{
    scanf("%d%d%d",&n,&m,&s);
    for(int i=0;i<n;++i){
        scanf("%d",&node[i].weight);//设置结点的权值 
    }
    int id,k;//id:编号 k:孩子数 
    int child;//孩子编号 
    //每个有孩子的结点
    for(int i=0;i<m;++i){
        scanf("%d%d",&id,&k);//设置该编号id的结点有k个孩子 
        for(int i=0;i<k;++i){
            scanf("%d",&child);//设置孩子编号
            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){
        //当前结点是否为叶子结点
        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);
        }
    }
}

二叉查找树

二叉查找树满足其左子树上所有结点的数据域均小于或等于根节点的数据域,右子树上所有结点的数据域均大于根节点的数据域。

给出N个正整数来作为一棵二叉排序树的结点插入顺序,问:这串序列是否是该二叉排序树的先序序列或是该二叉排序树的镜像树的先序序列,如果是镜像树,输出yes,并输出对应的树的后序序列,否则输出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;//结点个数 
    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);
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 四、树与二叉树 1. 二叉树的顺序存储结构 二叉树的顺序存储就是用数组存储二叉树。二叉树的每个结点在顺序存储中都有...
    MinoyJet阅读 1,759评论 0 7
  • 二叉树的遍历 二叉树的操作有很多种,其中最常用的是二叉树的遍历。二叉树的遍历是指按照某种顺序访问二叉树中的每个结点...
    Richie_ll阅读 491评论 0 4
  • 数据结构和算法--二叉树的实现 几种二叉树 1、二叉树 和普通的树相比,二叉树有如下特点: 每个结点最多只有两棵子...
    sunhaiyu阅读 6,712评论 0 14
  • 树和二叉树 1、树的定义 树(Tree)是由一个 或 多个结点 组成的有限集合T,且满足: ①有且仅有一个称为根的...
    利伊奥克儿阅读 1,587评论 0 1
  • 用异或
    JoviChan阅读 338评论 0 0

友情链接更多精彩内容