zoukankan      html  css  js  c++  java
  • 二叉树的遍历

    对于一棵二叉树一般有三种遍历方式,先序遍历(preOrder)、中序遍历(inOrder)、后序遍历(postOrder)。

    同时这里还介绍了二叉树的 层次遍历(levelOrder)

    每种遍历都有递归的实现和非递归的实现。

    1、preOrder

    对每个节点进行遍历,并将right节点push到一个stack中

    //递归实现
    void preOrder1(BinTree *root)     //递归前序遍历 
    {
        if(root!=NULL)
        {
            cout<<root->data<<" ";
            preOrder1(root->lchild);
            preOrder1(root->rchild);
        }
    }
    
    //非递归
    void preOrder2(BinTree *root)     //非递归前序遍历 
    {
        stack<BinTree*> s;
        BinTree *p=root;
        while(p!=NULL||!s.empty())
        {
            while(p!=NULL)
            {
                cout<<p->data<<" ";
                s.push(p);
                p=p->lchild;
            }
            if(!s.empty())
            {
                p=s.top();
                s.pop();
                p=p->rchild;
            }
        }
    }
    

    2、inOrder

    通过一个stack存储遍历的中心节点,知道最左边的节点,然后对stack进行pop操作。

    //递归实现
    void inOrder1(BinTree *root)      //递归中序遍历
    {
        if(root!=NULL)
        {
            inOrder1(root->lchild);
            cout<<root->data<<" ";
            inOrder1(root->rchild);
        }
    } 
    //非递归实现
    void inOrder2(BinTree *root)      //非递归中序遍历
    {
        stack<BinTree*> s;
        BinTree *p=root;
        while(p!=NULL||!s.empty())
        {
            while(p!=NULL)
            {
                s.push(p);
                p=p->lchild;
            }
            if(!s.empty())
            {
                p=s.top();
                cout<<p->data<<" ";
                s.pop();
                p=p->rchild;
            }
        }    
    } 
    

    3、postOrder

      要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,则可以直接访问它;或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。  

    //递归
    void postOrder1(BinTree *root)    //递归后序遍历
    {
    if(root!=NULL)
    {
    postOrder1(root->lchild);
    postOrder1(root->rchild);
    cout<<root->data<<" ";
    }
    }
    //非递归
    void postOrder(BinTree *root) //非递归后序遍历 { stack<BinTree*> s; BinTree *cur; //当前结点 BinTree *pre=NULL; //前一次访问的结点 s.push(root); while(!s.empty()) { cur=s.top(); if((cur->lchild==NULL&&cur->rchild==NULL)|| (pre!=NULL&&(pre==cur->lchild||pre==cur->rchild))) { cout<<cur->data<<" "; //如果当前结点没有孩子结点或者孩子节点都已被访问过 s.pop(); pre=cur; } else { if(cur->rchild!=NULL) s.push(cur->rchild); if(cur->lchild!=NULL) s.push(cur->lchild); } } }

    4、层次遍历

    一次从左到右输出一颗二叉树的 每一层元素。

    定义两个queue,将其中一个queue中每个元素的左右节点一次push进另一个queue中,直到该队列为空。

    然后访问另一queue执行同样的操作。

    //leetcode中遍历的方法
    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     * };
     */
    class Solution {
    public:
        vector<vector<int>> levelOrder(TreeNode* root) {
            queue<TreeNode *> in1,in2;
            vector<vector<int>> re;
            if (root == NULL) return re;
            in1.push(root);
            while (!in1.empty()||!in2.empty()){
                vector<int> temp;
                if (!in1.empty()){
                    while (!in1.empty()){
                        TreeNode    *p = in1.front();
                        in1.pop();
                        temp.push_back(p->val);
                        if (p->left != NULL) in2.push(p->left);
                        if (p->right!= NULL) in2.push(p->right);
                    }
                }
                else {
                    while (!in2.empty()){
                        TreeNode    *p = in2.front();
                        in2.pop();
                        temp.push_back(p->val);
                        if (p->left != NULL) in1.push(p->left);
                        if (p->right != NULL) in1.push(p->right);
                    }
                }
                re.push_back(temp);
            }
            return re;
        }
    };
  • 相关阅读:
    计算机网络第五版答案 谢希仁
    AJAX代码示例(不使用AJAX控件)
    软件工程期末资料
    各类编程语言视频教程(300G)
    AJAX无刷新分页练习
    C#使用IrisSkin2.dll美化WinForm程序界面
    asp.net判断浏览器版本代码
    C#中国身份证验证
    在IIS中使用SSL配置HTTPS网站(转)
    silverLight导出报表
  • 原文地址:https://www.cnblogs.com/NeilZhang/p/6607060.html
Copyright © 2011-2022 走看看