数据结构:二叉树的前序,中序,后序遍历(递归和非递归)

来源:互联网 发布:巫师3 4g内存优化 编辑:程序博客网 时间:2024/04/30 14:49

二叉树的使用,在数据结构中是比较常见的。这里列举了二叉树的四种遍历方式:前序,中序,后序遍历(递归和非递归的方式)以及层次遍历的方法,供大家参考。

先给出文章中所用的二叉树:

         8

      /             \

    6               10

  /          \          /        \

 5           7     9         11

   \         /        /                \

  12    16    13               15

                        \

                        14

首先是前序遍历:

递归的方式:

1.  遍历根节点

2.  遍历左子树

3.  遍历右子树

void preOrser(TreeNode *s){    if ( s != nullptr )    {        cout << s->val << "  ";          preOrser(s->left);        preOrser(s->right);    }}
非递归的方式:详细解释见注释

void preOrser(node *t){    //  用于保存节点    stack<node*> s;    if ( t == nullptr )        return;    // 当指针非空,或者 栈非空时 继续遍历    while( t || !s.empty() )    {        // 一直找到最左端        while(t)        {            // 因为是先序遍历,所以需要先打印节点的值            cout << t->val << " " ;            s.push( t );            t = t->left;        }  // 当空节点时,跳出循环        t = s.top();        s.pop();        //  找到右孩子        t = t->right;    }}


其次是中序遍历:

递归的方式:

1.  遍历左子树

2.  遍历根节点

3.  遍历右子树

void midOrder(TreeNode *s){    if ( s != nullptr )    {        midOrder(s->left);        cout << s->val << "  ";        midOrder(s->right);    }}


非递归的方式:

//  完成了二叉树的中序遍历的非递归形式//  通过 栈 能实现二叉树的遍历过程void midOrder(node *t){    //  用于储存遍历的元素    stack<node*> sta;    while( t ||  !sta.empty() )    {        if ( t != nullptr )        {            sta.push(t);            t = t->left;        }        else        {            t = sta.top();            sta.pop();            cout << t->val << " ";            t = t->right;        }    }}

再则是后续遍历:

1.  遍历左子树

2.  遍历右子树

3.  遍历根节点

void postOrder(TreeNode *s){    if ( s != nullptr )    {        postOrder(s->left);        postOrder(s->right);        cout << s->val << "  ";    }}


非递归的方式:

//非递归实现二叉树后续遍历,需要借助两个容器来实现 //第一个栈按前序遍历将二叉树节点压栈 //第二个容器是当第一个栈要出栈的时候,将当前出栈的节点压栈到第二个容器 //如果当前节点存在左孩子节点,则压栈到第一个栈 //如果当前节点存在右孩子节点,则压栈到第一个栈 //最后当第一个栈为空的时候,这时候遍历第二个容器,让第二个容器一直输出当前节点值 void postOrser(node *t){    stack<node*> pre;    vector<int> post;    if ( t == nullptr )        return;    pre.push(t);    while( !pre.empty() )    {        node* p;        p = pre.top();        post.push_back(p->val);        pre.pop();        if ( p->left != nullptr )            pre.push(p->left);        if ( p->right != nullptr )            pre.push(p->right);    }    for ( auto it = post.end() -1; it >= post.begin(); it-- )        cout << *it << " ";}



最后给出层次遍历的方法:

层次遍历就是按照二叉树的高度,从上往下,从左向右依次遍历每一个节点

vector<int> PrintFromTopToBottom(TreeNode *root){    vector<struct TreeNode*> v;    vector<int> s;    if ( root == nullptr )        return s;    v.push_back(root);    int i = 0;    while(i != v.size())    {        if ( v[i]->left != nullptr )        {             v.push_back(v[i]->left);        }        if ( v[i]->right != nullptr )        {            v.push_back(v[i]->right);        }        i++;    }    for ( int i = 0 ; i < v.size();i++ )    {        s.push_back(v[i]->val);    }    return s;}

以上所有程序的执行结果对应上面的二叉树为:







1 0
原创粉丝点击