二叉树的前序、中序、后序、层次遍历的递归与非递归实现

二叉树的遍历有前序遍历、中序遍历、后序遍历、层次遍历等,笔者在这里总结一下各种遍历的实现。

一.前序遍历。

前序遍历访问节点顺序为:根节点->左子节点->右子节点。

递归实现如下:

void preorder(TreeNode* root, vector<int>& nodes) {
    if (!root) return;
    nodes.push_back(root -> val);
    preorder(root -> left, nodes);
    preorder(root -> right, nodes);
}
vector<int> preorderTraversal(TreeNode* root) {
    vector<int> nodes;
    preorder(root, nodes);
    return nodes;
}

非递归实现(使用栈)如下:

对于任一结点P:

①访问结点P,并将结点P入栈;

②判断结点P的左孩子是否为空,若为空,则取栈顶结点并进行出栈操作,并将栈顶结点的右孩子置为当前的结点P,循环至①;若不为空,则将P的左孩子置为当前的结点P;

③直到P为NULL并且栈为空,则遍历结束。

vector<int> preorderTraversal(TreeNode *root) {
    vector<int> v;
    if (root == NULL) return v;
    stack<TreeNode*> s;
    TreeNode* temp = root;
    while (temp != NULL || !s.empty()) {
        while (temp != NULL) {
            v.push_back(temp->val);
            s.push(temp);
            temp = temp->left;
        }
        if (!s.empty()) {
            temp = s.top();
            s.pop();
            temp = temp->right;
        }
    }
    return v;
}

二.中序遍历。

中序遍历访问节点顺序为:左子节点->根节点->右子节点。

递归实现如下:

void inorder(TreeNode* root, vector<int>& nodes) {
    if (!root) return;
    inorder(root -> left, nodes);
    nodes.push_back(root -> val);
    inorder(root -> right, nodes);
}
vector<int> inorderTraversal(TreeNode* root) {
    vector<int> nodes;
    inorder(root, nodes);
    return nodes;
}

非递归实现(使用栈)如下:

对于任一结点P,

  ①若其左孩子不为空,则将P入栈并将P的左孩子置为当前的P,然后对当前结点P再进行相同的处理;

  ②若其左孩子为空,则取栈顶元素并进行出栈操作,访问该栈顶结点,然后将当前的P置为栈顶结点的右孩子;

  ③直到P为NULL并且栈为空则遍历结束

vector<int> inorderTraversal(TreeNode *root) {
    vector<int> v;
    if (root == NULL) return v;
    stack<TreeNode*> s;
    TreeNode *temp = root;
    while (temp != NULL || !s.empty()) {
        while (temp != NULL) {
            s.push(temp);
            temp = temp->left;
        }
        if (!s.empty()) {
            temp = s.top();
            s.pop();
            v.push_back(temp->val);
            temp = temp->right;
        }
    }
    return v;
}

三.后序遍历。

后序遍历访问节点顺序为:左子节点->右子节点->根节点。

递归实现如下:

void postorder(TreeNode* root, vector<int>& nodes) {
    if (!root) return;
    postorder(root -> left, nodes);
    postorder(root -> right, nodes);
    nodes.push_back(root -> val);
}
vector<int> postorderTraversal(TreeNode* root) {
    vector<int> nodes;
    postorder(root, nodes);
    return nodes;
}

非递归实现(使用栈)如下:

vector<int> postorderTraversal(TreeNode *root) {
    vector<int> v;
    stack<TreeNode*> s;
    TreeNode * curr = root;
    TreeNode * previsited = NULL;
    while (curr != NULL || !s.empty()) {
        while (curr != NULL) {
            s.push(curr);
            curr = curr->left;
        }
        curr = s.top();
        // 当前节点的右孩子如果为空或者已经被访问,则访问当前节点
        if (curr->right == NULL || curr->right == previsited) {
            v.push_back(curr->val);
            previsited = curr;
            s.pop();
            curr = NULL;
        }
        else curr = curr->right; //否则访问右孩子
    }
    return v;
}

四.层次遍历。

使用队列:

vector<vector<int>> levelOrder(TreeNode *root) {
    queue<TreeNode*> q;
    int count = 0;
    vector<int> v;
    vector<vector<int>> v2;
    if (root == NULL) return v2;
    q.push(root);
    count++;
    int count2 = 1;
    while (!q.empty()) {
        count = count2;
        count2 = 0;
        v.clear();
        for (int i = 0; i < count; i++) {
            TreeNode * top = q.front();
            v.push_back(top->val);
            if (top->left != NULL) {
                q.push(top->left);
                count2++;
            }
            if (top->right != NULL) {
                q.push(top->right);
                count2++;
            }
            q.pop();
        }
        v2.push_back(v);
    }
    return v2;
}
时间: 2024-10-16 04:27:42

二叉树的前序、中序、后序、层次遍历的递归与非递归实现的相关文章

分别求二叉树前、中、后序的第k个节点

一.求二叉树的前序遍历中的第k个节点 //求先序遍历中的第k个节点的值 int n=1; elemType preNode(BTNode *root,int k){ if(root==NULL) return ' '; if(n==k) return root->data; n++; elemType ch = preNode(root->lchild,k); if(ch!=' ') return ch; ch = preNode(root->rchild,k); return ch;

二叉树前、中、后、层次、遍历的非递归法

一.二叉树 非递归前序遍历 class Solution { public List<Integer> preorderTraversal(TreeNode root) { List<Integer> res = new ArrayList<>(); if(root == null) return res; Stack<TreeNode> st = new Stack<>(); st.push(root); while(!st.empty()){

算法实验-二叉树的创建和前序-中序-后序-层次 遍历

对于二叉树的创建我是利用先序遍历的序列进行创建 能够对于树节点的内容我定义为char型变量 '0'为空,即此处的节点不存在 头文件 Tree.h //链式二叉树的头文件 #pragma once #include<iostream> #include<queue> using namespace std; class BinaryTreeNode { public: char data; BinaryTreeNode *leftChild,*rightChild; BinaryTr

二叉树遍历算法——包含递归前、中、后序和层次,非递归前、中、后序和层次遍历共八种

首先,要感谢网上的参考资料. http://mengliao.blog.51cto.com/876134/1178079(作者:BlackAlpha) http://blog.csdn.net/fzh1900/article/details/14056735(作者:_云淡风轻) http://blog.csdn.net/stpeace/article/details/8138458(作者:stpeace) 二叉树是使用的比较广泛的一种数据结构,这里我写了二叉树的相关操作,包括初始化.新建.以及遍

二叉树的前序中序后序遍历相互求法

二叉树的前中后序遍历,他们的递归非递归.还有广度遍历,参见二叉树的前中后序遍历迭代&广度遍历和二叉树的前中后序遍历简单的递归 现在记录已知二叉树的前序中序后序遍历的两个,求另外一个.一般,这两个中一定有中序遍历. 1.已知前序和中序,求后序遍历: 前序:ABDECFG  中序:DBEAFCG 思路简单:前序的第一个节点就是根节点, 中序中找到根节点的位置,根节点之前是其左子树,之后是右子树   按此顺序,依次在左子树部分遍历,右子树部分遍历 C++ 代码: TreeNode *BinaryTre

经典白话算法之二叉树中序前序序列(或后序)求解树

这种题一般有二种形式,共同点是都已知中序序列.如果没有中序序列,是无法唯一确定一棵树的. <1>已知二叉树的前序序列和中序序列,求解树. 1.确定树的根节点.树根是当前树中所有元素在前序遍历中最先出现的元素. 2.求解树的子树.找出根节点在中序遍历中的位置,根左边的所有元素就是左子树,根右边的所有元素就是右子树.若根节点左边或右边为空,则该方向子树为空:若根节点 边和右边都为空,则根节点已经为叶子节点. 3.递归求解树.将左子树和右子树分别看成一棵二叉树,重复1.2.3步,直到所有的节点完成定

二叉树的前序、中序、后序遍历(递归、非递归)实现

本文部分来源于CSDN兰亭风雨大牛的原创.链接为http://blog.csdn.net/ns_code/article/details/12977901 二叉树是一种非常重要的数据结构,很多其他数据机构都是基于二叉树的基础演变过来的.二叉树有前.中.后三种遍历方式,因为树的本身就是用递归定义的,因此采用递归的方法实现三种遍历,不仅代码简洁且容易理解,但其开销也比较大,而若采用非递归方法实现三种遍历,则要用栈来模拟实现(递归也是用栈实现的).下面先简要介绍三种遍历方式的递归实现,再详细介绍三种遍

二叉树的先序、中序、后序、层次遍历的递归和非递归解法

二叉树的先序.中序.后序.层次遍历的递归和非递归解法 package tree; import java.util.LinkedList; import java.util.Queue; import java.util.Stack; public class TreeTraverse { /** * 先序递归 * @param root */ public static void preOrderTraverse(TreeNode root) { if (root == null) { ret

已知二叉树前、中序遍历,求后序 / 已知二叉树中、后序遍历,求前序

void solve(int start,int end,int root) { // 前序和中序 -> 后序 // 每次调用solve()函数,传入pre-order的start,end,root if (start > end) // 递归边界 return; int i = start; while (i < end && in.at(i) != pre.at(root)) // 找到左右子树的分割点 i++; solve(start, i - 1, root +

日常学习随笔-用链表的形式实现普通二叉树的新增、查找、遍历(前、中、后序)等基础功能(侧重源码+说明)

一.二叉树 1.二叉树的概念 二叉树是每个节点最多有两个子树的树结构.通常子树被称作"左子树"(left subtree)和"右子树"(right subtree),其次序不能任意颠倒. 2.性质 (1)若二叉树的层次从0开始,则在二叉树的第i层至多有2^i个结点(i>=0): (2)高度为k的二叉树最多有2^(k+1) - 1个结点(k>=-1). (空树的高度为-1): (3)对任何一棵二叉树,如果其叶子结点(度为0)数为m, 度为2的结点数为n,