写一颗二叉树-适合初学者

(有任何问题欢迎留言或私聊

本文目的旨在给初学二叉树的朋友提供一个借鉴的模板:一个是指针版本,一个非指针版本。

在文末推荐几道经典例题、我的题解和经典博客,供大家学习。
已经了解二叉树的同学可以直接去看最下面的一些经典题目。点击左侧目录即可。

二叉树的很多相关定义在百度百科或者他人CSDN博客上都有,建议先看一下。

引入:

 一个二叉树如下:
这里写图片描述
前序遍历: ABDHIEJCFG
中序遍历: HDIBJEAFCG
后序遍历: HIDJEBFGCA
层序遍历: ABCDEFGHIJ
特点:
 1. 前序遍历中,根节点在第一位;后序遍历中,根节点在最后一位;
 2. 中序遍历中,根节点的左右子树分别在根节点位置两边;

非指针版本:

//DFS遍历二叉树
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1005;
const int INF = 0x3f3f3f3f;
const LL mod = 1000000007;
const double eps = 1e-8;
struct BinaryTree{
    int val;
    int l;
    int r;
    BinaryTree(){val=0;l=r=-1;}
}tree[N];
int ar[N],ans[N],n,tot,t;
int pre[N],jing[N];
//递归建树,k为当前建树已经跑到了输入序列数组的第几号元素
void build(int k){
    if(k>n)return;
    tree[++tot].val=ar[k];
    tree[tot].l=tree[tot].r=-1;
    int i=1;//从根节点往下分析此节点的位置情况
    while(1){
        if(ar[k]<tree[i].val){//比此节点的值小,就往左跑
            if(tree[i].l!=-1){
                i=tree[i].l;
            }else{//如果此节点没有左儿子,就让k号元素当它左儿子,break
                tree[i].l=tot;
                break;
            }
        }else {//反之往右跑
            if(tree[i].r!=-1){
                i=tree[i].r;
            }else{
                tree[i].r=tot;
                break;
            }
        }
    }
    build(k+1);
    return;
}
//二叉搜索树前序遍历的序列
void get_pre(int k){
    pre[++t]=tree[k].val;
    if(tree[k].l!=-1)get_pre(tree[k].l);
    if(tree[k].r!=-1)get_pre(tree[k].r);
    return;
}
//镜像二叉搜索树前序遍历的序列
void get_jing(int k){
    jing[++t]=tree[k].val;
    if(tree[k].r!=-1)get_jing(tree[k].r);
    if(tree[k].l!=-1)get_jing(tree[k].l);
    return;
}
//二叉搜索树中序遍历的结果
void get_mid(int k){
    if(tree[k].l!=-1)get_mid(tree[k].l);
    ans[++t]=tree[k].val;
    if(tree[k].r!=-1)get_mid(tree[k].r);
}
//镜像二叉搜索树中序遍历的结果
void get_mid2(int k){
    if(tree[k].r!=-1)get_mid2(tree[k].r);
    ans[++t]=tree[k].val;
    if(tree[k].l!=-1)get_mid2(tree[k].l);
}
//二叉搜索树后序遍历的结果
void get_la(int k){
    if(tree[k].l!=-1)get_la(tree[k].l);
    if(tree[k].r!=-1)get_la(tree[k].r);
    ans[++t]=tree[k].val;
}
//镜像二叉树后序遍历的结果
void get_la2(int k){
    if(tree[k].r!=-1)get_la2(tree[k].r);
    if(tree[k].l!=-1)get_la2(tree[k].l);
    ans[++t]=tree[k].val;
}
void output(){
    for(int i=1;i<=n;++i){
        if(i==n)printf("%d\n",ans[i]);
        else printf("%d ",ans[i]);
    }
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;++i){
        scanf("%d",&ar[i]);
    }
    tot=1;
    tree[1].val=ar[1];
    tree[1].l=tree[1].r=-1;
    build(2);
    t=0;
    get_pre(1);
    t=0;
    get_jing(1);
    return 0;
}


指针版本:


//由后序遍历和中序遍历获取层序遍历-BFS
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1005;
const int INF = 0x3f3f3f3f;
const LL mod = 1000000007;
const double eps = 1e-8;
typedef struct BinaryTree {
    int val;
    BinaryTree* left;
    BinaryTree* right;
    BinaryTree(){}
    BinaryTree(int data)
        : val(data), left(nullptr), right(nullptr) {}
}*tree;
int n;
int post[N],mid[N],pre[N];
tree build(int k,int *mid,int *post,int inl,int inr){
    int i,j;
    if(k<=0)return nullptr;
    if(inl>inr)return nullptr;
    tree p;
    p=new BinaryTree;
    p->left=p->right=nullptr;
    p->val=post[k-1];
    for(i=0;i<n;++i){
        if(mid[i]==post[k-1])break;
    }
    for(j=0;j<n;++j){
        //printf("j=%d\n",j);
        //j=0;
        if(*mid==mid[j])break;
    }
    int l=i-j;
    p->left=build(l,mid,post,inl,inl+l-1);
    p->right=build(k-l-1,mid+l+1,post+l,inl+l+1,inr);
    return p;
}
void bfs(tree head){
    queue<tree>Q;
    while(!Q.empty())Q.pop();
    Q.push(head);
    int s=0;
    while(!Q.empty()){
        tree u=Q.front();Q.pop();
        pre[s++]=u->val;
        if(u->left!=nullptr)Q.push(u->left);
        if(u->right!=nullptr)Q.push(u->right);
    }
    for(int i=0;i<s;++i){
        if(i==s-1)printf("%d\n",pre[i]);
        else printf("%d ",pre[i]);
    }
}
int main(){
    scanf("%d",&n);
    for(int i=0;i<n;++i){
        scanf("%d",&post[i]);
    }
    for(int i=0;i<n;++i){
        scanf("%d",&mid[i]);
    }
    tree root=new BinaryTree;
    root->left=root->right=nullptr;
    root=build(n,mid,post,0,n-1);
    bfs(root);
    return 0;
}

例题:

二叉树:PATL2-004. 这是二叉搜索树吗?
树的遍历:PATL2-006. 树的遍历
二叉树:PATL2-011. 玩转二叉树
完全二叉树:PATL3-010. 是否完全二叉搜索树
层序遍历例题:数据结构实验之二叉树五:层序遍历

我的题解

推荐博客:

二叉树前中后序遍历,DFS与BFS遍历二叉树
层序遍历讲解

猜你喜欢

转载自blog.csdn.net/qq_39599067/article/details/80167115