树的建立和遍历

Posted zjsaipplp

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树的建立和遍历相关的知识,希望对你有一定的参考价值。

二叉树的建立

typedef struct node{
    int data;
    struct node *L, *R;
}*BiTree;

前中建树

//给出当前先序序列PreL, PreL+1, ..., Pre(L+numLeft), Pre(L+numLeft+1), ..., PreR
//给出当前中序序列InL, InL+1, ..., In(K-1), InK, In(k+1), ..., InR
BiTree PreInCreate(int preL, int preR, int inL, int inR){
    if(preL > preR)
        return NULL;    //先序序列长度小于0
    BiTree root = new node;
    root->data = pre[preL];
    int k = inL;
    while(k <= inR && in[k] != pre[preL]) k++;//在中序序列中找到根节点
    int numLeft = k - inL;      //由中序序列得到左子树结点的个数 
    //左子树的先序区间为[preL+1, preL+numLeft], 左子树的中序区间为[inL, k-1];
    root->L = PreInCreate(preL+1, preL+numLeft, inL, k-1);
    //右子树的先序区间为[preL+numLeft+1, preR], 右子树的中序区间为[k+1, inR];
    root->R = PreInCreate(preL+numLeft+1, preR, k+1, inR);
    //printf("%d ", in[k]);
    return root;
}

后中建树

//给出当前后序序列PostL, PostL+1, ..., Post(L+numLeft-1), Post(L+numLeft), ..., Pre(R-1), PreR
//给出当前中序序列InL, InL+1, ..., In(k-1), Ink, In(k+1), ..., InR
BiTree PostInCreate(int postL, int postR, int inL, int inR){
    if(postL > postR)
        return NULL;
    BiTree root = new node;
    root->data = post[postR];
    int k = inL;
    while(k <= inR && in[k] != post[postR]) k++;
    int numLeft = k - inL;
    //printf("%d ", in[k]);
    root->L = PostInCreate(postL, postL+numLeft-1, inL, k-1);
    root->R = PostInCreate(postL+numLeft, postR-1, k+1, inR);
    return root;
}

层中建树

//给出当前中序序列InL, ..., In(k-1), Ink, In(k+1), ..., InR
//给出当前层次序列layerL, ..., layerR
BiTree LayerInCreate(int layerL, int layerR, int inL, int inR){
    if(inL > inR)    return NULL;
    int i, j;
    for(i = layerL; i <= layerR; i++){
        bool flag = true;
        for(j = inL; j <= inR; j++){
            if(layer[i] == in[j]){
                flag = false;
                break;
            }
        }
        if(!flag)   break;
    }
    BiTree root = new node;
    root->data = in[j];
    root->L = LayerInCreate(layerL, layerR, inL, j-1);
    root->R = LayerInCreate(layerL, layerR, j+1, inR);
    return root;
}

二叉树的遍历

int n, m = 0;

递归算法

void Order(BiTree root){
    if(root == NULL)
        return;
    //printf("%d%s", root->data, ++m == n ? "
" : " "); //visit(T);
    Order(root->L);
    //printf("%d%s", root->data, ++m == n ? "
" : " "); //visit(T);
    Order(root->R);
    //printf("%d%s", root->data, ++m == n ? "
" : " "); //visit(T);
}

先序非递归

void PreOrder(BiTree T){
    stack<BiTree> s;
    BiTree p = T;
    while(p || !s.empty()){
        if(p){
            //printf("%d ", p->data);//visit(p);
            s.push(p);
            p = p->L;
        }else{
            p = s.top();
            s.pop();
            p = p->R;
        }
    }
}

中序非递归

void InOrder(BiTree T){
    stack<BiTree> s;
    BiTree p = T;
    while(p || !s.empty()){
        if(p){
            s.push(p);
            p = p->L;
        }else{
            p = s.top();
            //printf("%d ", p->data);//visit(p);
            s.pop();
            p = p->R;
        }
    }
}

后序非递归

void PostOrder(BiTree T){
    stack<BiTree> s;
    BiTree p = T, r = NULL;
    while(p || !s.empty()){
        if(p){//走到最左边
            s.push(p);
            p = p->L;
        }else{
            p = s.top();
            if(p->R && p->R != r){//右子树存在,未被访问
                p = p->R;
                s.push(p);
                p = p->L;
            }else{   //p出栈时,栈内为根节点到p的路径,以此可以求解公共结点等
                printf("%d ", p->data);//visit(p);
                s.pop();
                r = p;//记录最近访问过的节点
                p = NULL;//节点访问完后,重置p指针
            }
        }
    }
}

层次遍历

void LevelOrder(BiTree T){
    queue<BiTree> q;      //队列中存放BiTnode变量的地址,这样就可以通过访问地址去修改原元素
    T->Level = 1;           //记录结点深度
    q.push(T);
    while(!q.empty()){
        BiTree p = q.front();
        q.pop();
        //printf("%d ", p->data);//visit(p);
        if(p->L){
            p->L->Level = p->Level + 1;       //计算各结点深度
            q.push(p->L);
        }
        if(p->R){
            p->R->Level = p->Level + 1;
            q.push(p->R);
        }
    }
}

多叉树的静态表示

//存储结构:孩子表示法
#include <bits/stdc++.h>
using namespace std;
const int M = 1e3;
struct node{
    int layer;  //结点深度
    int data;
    vector<int> children;
}tree[M];

//若结点不涉及数据域,可以简化结点结构
vector<int> child[M];

//插入结点
int index=0;
int NewNode(int x){
    tree[index].data = x;
    tree[index].children.clear();
    return index++;
}

//遍历
void PreOrder(int root){
    printf("%d ", tree[root].data);     //先根遍历
    for(int i=0; i<tree[root].children.size(); i++)
        PreOrder(tree[root].children[i]);
    Printf("%d ", tree[root].data);     //后根遍历
}

//层序遍历
#include <bits/stdc++.h>
using namespace std;
void LayerOrder(int root){
    queue<int> q;
    tree[root].layer = 0;
    q.push(root);
    while(!q.empty()){
        root = q.front();
        q.pop();
        printf("%d ", tree[root].data);
        for(int i=0; i<tree[root].children.size(); i++){
            int child = tree[root].children[i];
            tree[child].layer = tree[root].layer+1;
            q.push(child);
        }
    }
}

以上是关于树的建立和遍历的主要内容,如果未能解决你的问题,请参考以下文章

二叉树的遍历方法之层序-先序-中序-后序遍历的简单讲解和代码示例

二叉树的前中后序递归和非递归遍历操作代码

建立二叉树的二叉链表表示,实现二叉树的先序、中序、后序和按层次遍历,统计并输出结点个数。

二叉树的模板 先序建立 二叉树的遍历 深度

c++如何用非递归的算法去创建二叉树,有没有分层建立二叉树的方法

算法——二叉排序树的建立中序遍历