精华内容
下载资源
问答
  • 二叉树非递归遍历

    2013-03-09 13:50:01
    二叉树非递归遍历,数据结构,C语言代码的实验报告
  • 主要介绍了C++实现二叉树非递归遍历方法实例总结,是算法设计中比较经典的一个遍历算法,需要的朋友可以参考下
  • 今天小编就为大家分享一篇用Python实现二叉树、二叉树非递归遍历及绘制的例子,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • 二叉树的递归遍历很简单就可以实现,二叉树非递归遍历却想不出来?那你可以看看下面的例子。一个二叉树的例子var root = {val: 1,left: {val: 2,left: {val: 4,},right:{val:5}},right: {val: 3,left: {val: 6},...

    二叉树的递归遍历很简单就可以实现,二叉树非递归遍历却想不出来?那你可以看看下面的例子。

    一个二叉树的例子

    var root = {

    val: 1,

    left: {

    val: 2,

    left: {

    val: 4,

    },

    right:{

    val:5

    }

    },

    right: {

    val: 3,

    left: {

    val: 6

    },

    right: {

    val: 7

    }

    }

    }

    先实现三种遍历的递归算法以作比较。

    先序遍历递归算法

    function DLR(root){

    if(root!=null){

    console.log(root.val);

    DLR(root.left);

    DLR(root.right);

    }

    }

    DLR(root)//1,2,4,5,3,6,7

    中序遍历递归算法

    function LDR(root){

    if(root!=null){

    LDR(root.left);//先遍历到最左边的节点,然后输出

    console.log(root.val);

    LDR(root.right);

    }

    }

    LDR(root)//4,2,5,1,6,3,7

    后序遍历

    function LRD(root){

    if(node!=null){

    LRD(root.left);

    LRD(root.right);

    console.log(root.val);

    }

    }

    LRD(root)//4,5,2,6,7,3,1

    看完上面的递归遍历,下面对比一下非递归的二叉树遍历。你会发现递归真心简单。

    非递归前序遍历

    function DLR(root){

    var arr=[],res=[];

    if(root!=null){

    arr.push(root);

    }

    while(arr.length!=0){

    var temp=arr.pop();

    res.push(temp.val);

    //这里先放右边再放左边是因为取出来的顺序相反

    if(temp.right!=null){

    arr.push(temp.right);

    }

    if(temp.left!=null){

    arr.push(temp.left);

    }

    }

    return res;

    }

    DLR(root)//1,2,4,5,3,6,7

    非递归中序遍历

    //先把左边的,全部放进arr再输出,处理右边的。

    function LDR(root){

    var arr=[],res=[];

    while(true){

    while(root!=null){

    arr.push(root);

    root=root.left;

    }

    //终止条件:最后树遍历完了自然就结束

    if(arr.length==0){

    break;

    }

    var temp=arr.pop();

    res.push(temp.val);

    root=temp.right;

    }

    return res;

    }

    LDR(root)//4,2,5,1,6,3,7

    后序遍历

    function LRD(root){

    var arr=[],res=[];

    arr.push(root);

    while(arr.length!=0){

    var p=arr.pop();

    res.push(p.val);

    if(p.left!=null){

    arr.push(p.left);

    }

    if(p.right!=null){

    arr.push(p.right);

    }

    }

    return res.reverse();

    }

    LRD(root)//4,5,2,6,7,3,1

    展开全文
  • 二叉树非递归遍历C

    2013-09-18 15:14:41
    C语言实现二叉树非递归遍历,前序、中序、后序、层序遍历的具体实现
  • 二叉树非递归遍历算法 1. 前序遍历 /** * 前序非递归遍历 借助链表和栈 */ @Override public void preOrderByStack() { System.out.print("前序非递归遍历:"); if (root==null){ System.out.println...

    二叉树非递归遍历算法

    1. 前序遍历

        /**
         * 前序非递归遍历 借助链表和栈
         */
        @Override
        public void preOrderByStack() {
            System.out.print("前序非递归遍历:");
            if (root==null){
                System.out.println("二叉树为空!!!");
            }else {
                LinkedList<BinaryNode> list = new LinkedList<BinaryNode>();
                Queue<BinaryNode> stack = new LinkedList<>();
                BinaryNode current = root;
                while (current!=null || !stack.isEmpty()){
                    while (current!=null){
                        list.add(current);
                        ((LinkedList<BinaryNode>) stack).push(current);
                        current = current.left;
                    }
                    if(!stack.isEmpty()){
                        current =((LinkedList<BinaryNode>) stack).pop();
                        current =current.right;
                    }
                }
    
                for(BinaryNode binaryNode : list){
                    System.out.print(binaryNode.value+" ");
                }
                System.out.println();
            }
        }
    

    2. 中序遍历

        /**
         * 二叉树的中序遍历(非递归)   借助栈
         */
        @Override
        public void inOrderByStack() {
            System.out.print("中序非递归遍历:");
            //创建栈
            Deque<BinaryNode> stack = new LinkedList<BinaryNode>();
            BinaryNode current =root;
            while (current!=null || !stack.isEmpty()){
                while (current!=null){
                    stack.push(current);
                    current=current.left;
                }
                if(!stack.isEmpty()){
                    current=stack.pop();
                    System.out.print(current.value+" ");
                    current=current.right;
                }
            }
            System.out.println();
        }
    

    3. 后序遍历

        /**
         * 后序非递归遍历  借助栈与 队列
         */
        @Override
        public void postOrderByStack() {
            System.out.print("后序非递归遍历:");
            ArrayList<BinaryNode> list = new ArrayList<BinaryNode>();
            if(root!=null){
                Deque<BinaryNode> stack = new LinkedList<>();
                stack.push(root);
                while (!stack.isEmpty()){
                    BinaryNode current = stack.pop();
                    list.add(0,current);
                    if(current.left!=null){
                        stack.push(current.left);
                    }
                    if(current.right!=null){
                        stack.push(current.right);
                    }
                }
                Iterator<BinaryNode> iterator  = list.iterator();
                while (iterator.hasNext()){
                    System.out.print(iterator.next().value+" ");
                }
                System.out.println();
            }
        }
    
    展开全文
  • 二叉树 非递归遍历前序中序遍历 c语言
  • C++版二叉树非递归遍历 1.二叉树前序遍历 /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right...

    C++版二叉树非递归遍历

    一.二叉树前序遍历

    /**
     * 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<int> preorderTraversal(TreeNode* root) {
            stack<TreeNode*>s;
            vector<int>s1;
            TreeNode* cur=root;
            TreeNode* top1;//记录栈定元素
           while(!s.empty()||cur)
           {
               while(cur)//如果左子树存在,用cur标记,把所有的左孩子入栈
               {
                   s1.push_back(cur->val);//把根结点的值放到vector<int>s1中
                   s.push(cur);//把根结点入栈
                   cur=cur->left;//寻找当前根结点的左孩子
               }
               top1=s.top();//拿到最后一个左孩子用top1标记
               s.pop();//因为最后一个左孩子在上一个循环内已经打印了,所以把栈顶元素直接出栈
               cur=top1->right;//进行找右孩子
           }
            return s1;
        }
    };
    

    二.二叉树中序遍历

    /**
     * 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<int> inorderTraversal(TreeNode* root) {
            vector<int>ret;
            stack<TreeNode*> s;
            TreeNode* cur = root;
            TreeNode* topp;
            while(cur||!s.empty())
            {
                while(cur)
                {
                    s.push(cur);
                    cur=cur->left;
                }
                topp=s.top();
                s.pop();
                ret.push_back(topp->val);
                cur=topp->right;
            }
            return ret;
        }
    };
    

    三.二叉树后序遍历

    /**
     * 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<int> postorderTraversal(TreeNode* root) {
            stack<TreeNode*>s;
    		vector<int>ret;
    		TreeNode* cur = root;
    		TreeNode* top1;//记录栈定元素
    		TreeNode* top2 = nullptr;//用来标记是否已经放到ret中
    		while (cur || !s.empty())
    		{
    			while (cur)//循环一直把左孩子入栈
    			{
    				s.push(cur);
    				cur = cur->left;
    			}
    			top1 = s.top();//当没有左孩子时,用top1取栈顶元素
    			if (top1->right == nullptr || top1->right == top2)//只有当该节点的右孩子为空或右孩子被top2标记,才能把当前根结点放到ret中
    			{
    				ret.push_back(top1->val);
    				s.pop();
    				top2 = top1;//用top2记录top1节点已经放到ret中
                    top1=nullptr;//没必要,但最好加上,防止内存泄漏问题
    			}
    			else
    			{
    				cur = top1->right;
    			}
    		}
    		return ret;
            
        }
    };
    
    展开全文
  • 二叉树非递归遍历前序非递归遍历中序非递归遍历后序非递归遍历 在上一篇博客中我们介绍了二叉树的前中后序递归遍历,本篇博客我们来看看如何将递归遍历变为非递归遍历。博客链接:二叉树存储、递归遍历(前、中、...

    在上一篇博客中我们介绍了二叉树的前中后序递归遍历,本篇博客我们来看看如何将递归遍历变为非递归遍历。博客链接:二叉树存储、递归遍历(前、中、后序).

    前序非递归遍历

    对于前序遍历我们知道它的访问顺序是根节点---->根节点的左子树---->根节点的右子树。

    对于递归改为非递归,一般有两种思路:

    • 借助栈实现
    • 通过for循环实现

    因此,我们的递归遍历就采用借助栈来实现。并且对于前序非递归遍历我们有两种思路。

    思路一:

    我们先思考一下,前序遍历是先访问根节点,然后依次访问根节点的左右子树。对于栈,栈的特点是先进后出,我们如何将两者结合起来呢?

    先进后出?对于后出(最后访问的)节点我们首先需要把他压入栈中,所以,

    • 对于根节点,它是一开始就被访问,直接入栈,每次直接访问(打印、存储等操作);

    • 在前序遍历中,右子树是最后访问的,那么就需要先于左子树入栈

    • 对于左子树,他是第二顺序被访问,那么它就需要在右子树的后面进栈

    我们总结一下,先序非递归的遍历实现步骤如下:

    1. 空树—>直接返回
    2. 树不为空:将根节点入栈,循环进行以下操作
      • 取栈顶元素:cur = stack.peek()
      • 遍历该元素:也就是访问该根节点
      • 删除栈顶元素
      • 如果cur的右子树存在,将右子树入栈
      • 如果cur的左子树存在,将左子树入栈

    代码实现:

    //前序非递归遍历
    public void preOrderNor()
    {
         if(root==null)
         {
             return ;
         }
         Stack<BTNode> s=new Stack<>();
         s.push(root);
         while(!s.isEmpty())
         {
             BTNode cur=s.peek();
             System.out.print(cur.val+" ");
             s.pop();
             if(cur.right!=null)
             {
                 s.push(cur.right);
             }
             if(cur.left!=null)
             {
                 s.push(cur.left);
             }
         }
     }
    

    思路二:

    以没有被遍历的节点为一颗新的子树,顺着一条路径往左走,如果当前节点有右孩子将其右孩子保存在栈中,没有则向左走(遍历该节点)

    先序非递归的遍历实现步骤如下:

    1. 空树—>直接返回
    2. 树不为空:将根节点入栈,循环进行以下操作(循环条件:栈不为空):
      • 取栈顶元素: cur = stack.peek()
      • 让该元素出栈,循环进行以下操作(循环条件:cur!=null,即:让当前路径一直向左走):
        • 遍历当前元素(cur)
        • 如果cur的右子树存在,将右子树入栈
        • 如果cur的右子树不存在,一直向左走( cur=cur.left )

    代码实现:

    public void preOrderNor2()
    {
        if(root==null)
        {
            return ;
        }
        Stack<BTNode> s=new Stack<>();
        s.push(root);
        while(!s.isEmpty())
        {
            BTNode cur=s.peek();
            s.pop();
            //cur!=null,也就是顺着一条路径一直向左
            while(null!=cur)
            {
                //顺着cur左侧这条路路径,遍历左子树,保存右子树
                System.out.print(cur.val+" ");
                if(cur.right!=null)
                {
                    s.push(cur.right);
                }
                cur=cur.left;
            }
        }
    }
    

    中序非递归遍历

    中序遍历非递归的两种方式见我的另一篇博客,里边有详细的分析以及代码。
    博客链接:Leetcode94-二叉树中序非递归遍历.

    后序非递归遍历

    在看了二叉树的中序非递归遍历后,其实后序非递归遍历和中序非递归遍历的唯一区别就是访问(打印)根节点的先后顺序不同。

    在这里插入图片描述
    具体步骤如下:

    1. 先找以root为根的左子树最左下的节点,并保存所经路径的所有节点-----》保存到栈里。

      • 以上图中的二叉树为例,最终会停留在3这个节点。 可以认为3的左子树已经遍历结束,接下来只能遍历3的右子树
      • 循环条件:while(cur!=nll || !s.empty() ),
    2. 获取栈顶元素----->获取3的右子树的根节点,拿到栈顶的元素(也就是3),然后遍历3的右子树

      • 右子树为null:遍历3这个节点,并且将该节点出栈
      • 右子树非空:将3的右子树当成新的树进行遍历,这个时候不能打印栈顶元素(值为3)否则就变成中序非递归
    3. 最后才打印栈顶元素(没有右孩子)

    代码实现:

     public void lastOrderNor()
        {
            System.out.println("非递归后续遍历:");
    
            if(root==null)
            {
                return;
            }
    
            //1>先找以root为根的左子树最左下的节点,并保存所经路径的所有节点---》保存到栈里。
            Stack<BTNode> s =new Stack<>();
            BTNode cur= root ;
    
            BTNode prev=null;//标记刚刚遍历过的节点
            while (!s.empty()  ||  cur!=null)
            {
            //先将左子树依次入栈
                while (cur!=null)
                {
                    s.push(cur);
                    cur=cur.left;
                }
                //2.获取栈顶元素
                BTNode node=s.peek();
    
                //node右孩子为空----》就可以遍历根节点
                //node的右孩子已经遍历完成-----》就可以遍历根节点
                if(node.right==null &&  node.right==prev)//没右孩子
                {
                    //没有右孩子:打印该节点,并出栈
                    System.out.print(node.val+" ");
                    prev=node;//将访问过的右节点标记起来,来避免循环压栈
                    s.pop();
    
                }else {//有右孩子
                    cur=node.right;
                }
            }
        }
    
    展开全文
  • 经典的数据结构问题:二叉树非递归遍历算法实现 二叉树递归遍历算法实现
  • 本文主要讲解二叉树非递归遍历,由于是非递归遍历,所以需要用到栈stack,我们如果仔细考虑递归遍历的代码,就能明白非递归种栈的应用。 由于几种遍历方式只是在处理中间节点的时候会有不同,所以下面主要讲后序遍历...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 13,407
精华内容 5,362
关键字:

二叉树非递归遍历