• 数据结构-二叉树的遍历


    一、先序遍历

    • 第一个一定是根结点
    1. 递归式:就是先序递归的定义
    2. 递归边界:二叉树中递归边界是二叉树为一棵空树
    void preorder(node* root){
        if(root == NULL){
            return;
        }
        //访问根结点root, 例如将其数据域输出
        printf("%d
    ", root->data);
        //访问左子树
        preorder(root->lchild);
        //访问右子树
        preorder(root->rchild);
    }
    

    二、中序遍历

    • 只要知道根结点就可以通过根结点在中序遍历的序列中位置分出为左子树和右子树
    1. 递归式:就是中序递归的定义
    2. 递归边界:二叉树中递归边界是二叉树为一棵空树
    void inorder(node* root){
        if(root == NULL){
            return;
        }
        inorder(root->lchild);
        printf("%d
    ", root->data);
        inorder(root->rchild);
    }
    

    三、后序遍历

    • 最优一个结点一定是根结点
    void postorder(node* root){
        if(root == NULL){
            return;
        }
        postorder(root->lchild);
        postorder(root->rchild);
        printf("%d
    ", root->data);
    }
    
    • 总的来说无论是先序遍历还是后序遍历,都必须知道中序遍历才能唯一确定一棵树

    四、层序遍历

    void  LayerOrder(node* root){
        queue<node*> q;
        q.push(root);
        while(!q.empty()){
            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);
        }
    }
    
    • 有时候需要记录每个结点的层次
    struct node{
        int data;
        int layer;
        node* lchild;
        node* rchild;
    }
    void  LayerOrder(node* root){
        queue<node*> q;
        root->layer = 1;
        q.push(root);
        while(!q.empty()){
            node* now = q.front();
            q.pop();
            printf("%d
    ", now->data);
            if(now->lchild != NULL){
                now->lchild->layer = now->layer+1;
                q.push(now->lchild);
            }
            if(now->rchild != NULL){
                now->rchild->layer = now->layer+1;
                q.push(now->rchild);
            }
        }
    }
    

    五、由先序遍历和中序遍历构建二叉树/后序遍历和中序遍历构建二叉树

    node* create(int preL, int preR, int inL, int inR){
        if(preL > preR){
            return NULL;//先序序列长度小于等于0时,直接返回
        }
        node* root = new node;//新建一个结点,用于存放二叉树的根结点
        //如果是先序和中序那么这里就是从左边第一个结点就是根结点所以为preL,而后序和中序是从后面第一个是根结点所以为postR
        root->data = pre[preL]/post[postR];//新结点的数据域为根结点的值
        int k;
        for(k = inL; k <= inR; k++){
            if(in[k] == pre[preL]){
                break;
            }
        }
        int numLeft = k - inL;//左子树的结点个数
        //左子树的先序区间为[preL+1, preL+numLeft], 中序区间[inL, k-1]
        //返回左子树的根结点地址,赋值给root的左指针
        root->lchild = create(preL+1/postL, preL+numLeft/postL+numLeft-1, inL, k-1);
        //右子树的先序区间[preL+numLeft+1, preR], 中序区间为[k+1, inR];
        //返回右子树的根结点地址,赋值给root的右指针
        root->rchild = create(preL+numLeft+1/postL+numLeft, preR/postR-1, k+1, inR);
        
        return root;//返回根结点地址
    }
    
    作者:睿晞
    身处这个阶段的时候,一定要好好珍惜,这是我们唯一能做的,求学,钻研,为人,处事,交友……无一不是如此。
    劝君莫惜金缕衣,劝君惜取少年时。花开堪折直须折,莫待无花空折枝。
    曾有一个业界大牛说过这样一段话,送给大家:   “华人在计算机视觉领域的研究水平越来越高,这是非常振奋人心的事。我们中国错过了工业革命,错过了电气革命,信息革命也只是跟随状态。但人工智能的革命,我们跟世界上的领先国家是并肩往前跑的。能身处这个时代浪潮之中,做一番伟大的事业,经常激动的夜不能寐。”
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
  • 相关阅读:
    自己定义Actionbar
    创建自己的Repo Server
    AI案例
    贝叶斯定理,从白袜到飞机失事再到人工智能
    jupyter notebook 安装代码提示功能
    Jupyter notebook 自动补全
    27 个Jupyter Notebook的小提示与技巧
    Windows下的Jupyter Notebook 安装与自定义启动
    以太坊联盟链 parity 节点搭建
    ubuntu上面Parity 安装
  • 原文地址:https://www.cnblogs.com/tsruixi/p/12309690.html
Copyright © 2020-2023  润新知