二叉树的非递归操作

这里涉及到二叉树的非递归操作有:先序遍历、中序遍历、后序遍历

====数据结构====

树结点:
struct Node
{
    
char data;
    Node 
* left;
    Node 
* right;
};

标志:
enum Tag{goLeft, goRight, goBack };
goLeft指示访问左子树
goLeft指示访问右子树(左子树已访问)
goBack指示回溯(左右子树均已访问)

两个栈:
vector<Node *> vec_node;
vector
<Tag> vec_flag;
两个栈同时消长、空

所有操作相同的部分:
Node *curNode = vec_node.back();//栈顶
Tag curFlag = vec_flag.back();  //栈顶

switch(curFlag)
        {
            
case goLeft:
                
//更改标志
                vec_flag.pop_back();
                vec_flag.push_back(goRight);

                
//左子树入栈
                if(curNode->left != NULL)
                {
                    vec_node.push_back(curNode
->left);
                    vec_flag.push_back(goLeft);
                }
                
break;

            
case goRight:
                
//更改标志
                vec_flag.pop_back();
                vec_flag.push_back(goBack);

                
//右子树入栈
                if(curNode->right != NULL)
                {
                    vec_node.push_back(curNode
->right);
                    vec_flag.push_back(goLeft);
                }
                
break;

            
case goBack:
                
//结点出栈
                vec_flag.pop_back();
                vec_node.pop_back();
                
break;

            
default:
                
break;
        }
//switch-end

几种操作唯一不同的是:需要的操作放置的位置不同。
先序遍历:打印结点放在goLeft中
中序遍历:打印结点放在goRight中
后续遍历:打印结点放在goBack中
打印所有路径:在goBack中判断是否为叶子结点,如果是,打印栈中所有路径;如果否,直接出栈

详细代码见下面:(注意其中红色的地方是唯一差别的地方:
#include <iostream>
#include 
<vector>
#include 
<cstdlib>
using namespace std;


struct Node
{
    
char data;
    Node 
* left;
    Node 
* right;
};

enum Tag{goLeft, goRight, goBack };

void PreOrder(Node *root)
{
    assert(root 
!= NULL);

    vector
<Node *> vec_node;
    vector
<Tag> vec_flag;
    
//init
    vec_node.push_back(root);
    vec_flag.push_back(goLeft);

    
while(!vec_node.empty())
    {
        Node 
*curNode = vec_node.back();
        Tag curFlag 
= vec_flag.back();

        
switch(curFlag)
        {
            
case goLeft:
                cout << curNode->data << "  ";
                vec_flag.pop_back();
                vec_flag.push_back(goRight);

                
if(curNode->left != NULL)
                {
                    vec_node.push_back(curNode
->left);
                    vec_flag.push_back(goLeft);
                }
                
break;

            
case goRight:
                vec_flag.pop_back();
                vec_flag.push_back(goBack);

                
if(curNode->right != NULL)
                {
                    vec_node.push_back(curNode
->right);
                    vec_flag.push_back(goLeft);
                }

                
break;


            
case goBack:
                vec_flag.pop_back();
                vec_node.pop_back();
                
break;

            
default:
                
break;
        }
//switch-end
    }//while-end

}

void InOrder(Node *root)
{
    assert(root 
!= NULL);

    vector
<Node *> vec_node;
    vector
<Tag> vec_flag;
    
//init
    vec_node.push_back(root);
    vec_flag.push_back(goLeft);

    
while(!vec_node.empty())
    {
        Node 
*curNode = vec_node.back();
        Tag curFlag 
= vec_flag.back();

        
switch(curFlag)
        {
            
case goLeft:
                vec_flag.pop_back();
                vec_flag.push_back(goRight);

                
if(curNode->left != NULL)
                {
                    vec_node.push_back(curNode
->left);
                    vec_flag.push_back(goLeft);
                }
                
break;

            
case goRight:
                cout << curNode->data << "  ";
                vec_flag.pop_back();
                vec_flag.push_back(goBack);

                
if(curNode->right != NULL)
                {
                    vec_node.push_back(curNode
->right);
                    vec_flag.push_back(goLeft);
                }

                
break;


            
case goBack:


                vec_flag.pop_back();
                vec_node.pop_back();
                
break;

            
default:
                
break;
        }
//switch-end
    }//while-end

}

void PostOrder(Node *root)
{
    assert(root 
!= NULL);

    vector
<Node *> vec_node;
    vector
<Tag> vec_flag;
    
//init
    vec_node.push_back(root);
    vec_flag.push_back(goLeft);

    
while(!vec_node.empty())
    {
        Node 
*curNode = vec_node.back();
        Tag curFlag 
= vec_flag.back();

        
switch(curFlag)
        {
            
case goLeft:
                vec_flag.pop_back();
                vec_flag.push_back(goRight);

                
if(curNode->left != NULL)
                {
                    vec_node.push_back(curNode
->left);
                    vec_flag.push_back(goLeft);
                }
                
break;

            
case goRight:
                vec_flag.pop_back();
                vec_flag.push_back(goBack);

                
if(curNode->right != NULL)
                {
                    vec_node.push_back(curNode
->right);
                    vec_flag.push_back(goLeft);
                }

                
break;


            
case goBack:
                cout << curNode->data << "  ";


                vec_flag.pop_back();
                vec_node.pop_back();
                
break;

            
default:
                
break;
        }
//switch-end
    }//while-end

}


/* 打印从根到叶子结点之路径 */
void PrintPath( const vector<Node *> & v )
{
    vector
< Node *>::const_iterator vi;
    
for( vi = v.begin(); vi!=v.end(); ++vi )
    {
        Node 
* n = reinterpret_cast< Node *>(*vi);
        cout
<< n->data<< " ";
    }
    cout
<< endl;
}

void PrintAllPaths(Node *root)
{
    assert(root 
!= NULL);

    vector
<Node *> vec_node;
    vector
<Tag> vec_flag;
    
//init
    vec_node.push_back(root);
    vec_flag.push_back(goLeft);

    
while!vec_node.empty())
    {
        Node 
*curNode = vec_node.back();
        Tag curFlag 
= vec_flag.back();


        
switch(curFlag)
        {
            
case goLeft:
                vec_flag.pop_back();
                vec_flag.push_back(goRight);

                
if(curNode->left != NULL)
                {
                    vec_node.push_back(curNode
->left);
                    vec_flag.push_back(goLeft);
                }
                
break;

            
case goRight:
                vec_flag.pop_back();
                vec_flag.push_back(goBack);

                
if(curNode->right != NULL)
                {
                    vec_node.push_back(curNode
->right);
                    vec_flag.push_back(goLeft);
                }

                
break;


            
case goBack:
                
if(NULL == curNode->left && NULL == curNode->right)
                    PrintPath(vec_node);

                vec_flag.pop_back();
                vec_node.pop_back();
                
break;

            
default:
                
break;
        }
//switch-end
    }//while-end
}

int main()
{
    Node root, b, c, d, e, f, g, h;
    root.data
='a';
    root.left
=&b;
    root.right
=&e;

    b.data
='b';
    b.left
=&c;
    b.right
=&d;

    c.data
='c';
    c.left
=NULL;
    c.right
=NULL;

    d.data
='d';
    d.left
=NULL;
    d.right
=NULL;

    e.data
='e';
    e.left
=&f;
    e.right
=&g;

    f.data
='f';
    f.left
=NULL;
    f.right
=NULL;

    g.data
='g';
    g.left
=NULL;
    g.right
=&h;

    h.data
='h';
    h.left
=NULL;
    h.right
=NULL;


    cout 
<< "Print all paths:\n";
    PrintAllPaths(
&root);
    cout 
<< "\n";

    cout 
<< "PostOrder:\n";
    PostOrder(
&root);
    cout 
<< "\n";

    cout 
<< "PreOrder:\n";
    PreOrder(
&root);
    cout 
<< "\n";

    cout 
<< "InOrder:\n";
    InOrder(
&root);
    cout 
<< "\n\n";

    system(
"PAUSE");
    
return 0;
}

运行结果:

转载于:https://www.cnblogs.com/chio/archive/2007/10/24/935784.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/464039.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

UDT源码剖析(二):UDT自带例程recvfile注释

这几天学习了UDT自带的例子&#xff0c;结合源码进行了测试如下&#xff1a; #ifndef WIN32 #include <arpa/inet.h>#include <netdb.h>#else#include <winsock2.h>#include <ws2tcpip.h>#endif#include <fstream>#include <iostream>#…

建立公司

最近标哥说有创业的想法&#xff0c;然后我帮忙搜了下关于创办公司的一些文章&#xff0c;晓宇的这篇文章把创业的过程写了个大概&#xff0c;也分享给大家&#xff0c;如果有创业想法的&#xff0c;按照这样的思路去寻找自己的合伙人。 自从17年4月份开始辞职创业&#xff0c;…

想在创建虚拟机的时候指定ip调研

想调研一下libvit xml能否提供类似的配置选项&#xff1a; xml应该写成这个样子&#xff0c;预先要在宿主机上面创建br0&#xff0c;配置要分配指定ip Using an existing host bridge Since 0.9.4 This shows how to use a pre-existing host bridge "br0". The gues…

UDT源码剖析(三):UDT::startup()过程代码注释

调用路线 UDT::startup()->CUDT::startup()->CUDTUnited::startup() 1 int startup() 2 { 3 return CUDT::startup(); 4 } 1 int CUDT::startup() 2 { 3 return s_UDTUnited.startup(); 4 } 查看源代码 打印帮助1 int CUDTUnited::startup() 2 { 3 // 开启一个…

第五节 CImage和CBmp(二)

由于这个库主要用于VC MFC下开发应用&#xff0c;因此目前可以下载到版本只支持MFC开发。如果您需要标准Win32的库&#xff0c;可以在回复时留下您的邮箱&#xff0c;或跟我联系。Email&#xff1a;wuchunlei163.comQQ&#xff1a;819543772EasyAnalysis图像分析库测试版以及源…

Linux 新系统易用性向 Windows 看齐

大家好&#xff0c;今天是一年一度的高考&#xff0c;不知道各位在多年以前有没有后悔选择电子专业&#xff0c;如果再给你一次机会&#xff0c;你会选择其他专业吗&#xff1f;以下是内容正文&#xff0c;由黄工整理&#xff01;来源 | 网络嵌入式开发&#xff0c;很多工程师都…

深度剖析SOC高性能实时事件关联分析引擎

【引言】安全管理平台&#xff08;SOC&#xff09; 的一项关键技术就是事件关联分析。借助实时的事件关联分析引擎&#xff0c;安全管理平台能够发掘出复杂的海量安全日志和事件背后隐藏的信息&#xff0c;引导安全管理人员发现外 部***和内部违规行为。作为本系列的第五篇文章…

P3165 [CQOI2014]排序机械臂

传送门 就是说要维护一个数据结构资瓷区间反转和查询第\(K\)大&#xff0c;那么splay吧 我们可以把原数组按高度为第一关键字&#xff0c;下标为第二关键字排序&#xff0c;然后直接建出splay 这样的话每次第\(K\)大直接查询编号然后把它转到根节点&#xff0c;那么左子树大小1…

靠,嘉立创打板又降价

说个题外话&#xff0c;我前段时间和同事聊天&#xff0c;我同事是一个项目经理&#xff0c;我跟他说我有朋友在嘉立创&#xff0c;然后随口说了句&#xff0c;我们这个行业应该没有不知道嘉立创的吧&#xff0c;我同事回了一句&#xff0c;什么是嘉立创&#xff0c;然后我愣了…

动态提示的下拉框

<html> <head> <meta http-equiv"Content-Type" content"text/html; charsetgb2312"> <META content"fason,阿信" nameAuthor> <title>动态提示的下拉框</title> <style> a{color:red;text-decoratio…

深度解析Cocoa异步请求和libxml2.dylib教程(1)

深度解析Cocoa异步请求和libxml2.dylib教程是本文要介绍的内容&#xff0c;不多说&#xff0c;直接进入话题&#xff0c;很早就在cocoachina上看到这个框架了,今天终于有机会来使用这个东东了. 我这里写一下,如何往iphone项目中添加这个框架. 步骤如下: 1.下载该framework : ht…

UDT源码剖析(四):UDT的GC线程相关过程代码注释

着UDT::Startup()的启动&#xff0c;GC线程也随之运行了。 GC主要关注的就是UDTSocket的释放&#xff0c;下面我们来看看这个GC线程是怎么实现的。 查看源代码 打印帮助1 #ifndef WIN32 2 void* CUDTUnited::garbageCollect(void* p) 3 #else 4 DWORD WINAPI CUDTUnited:…

那年高考

每年高考&#xff0c;都会让我想起很多事情。我第一次高考前几天&#xff0c;我舅舅和舅娘过来看我&#xff0c;他们拉我到教室后门&#xff0c;我舅说我妈叮嘱他一定来看我&#xff0c;然后跟我说不要给自己太大压力&#xff0c;啰嗦了几分钟&#xff0c;要走的时候硬塞给我10…

vimdiff的简单使用

Vimdiff的使用 1、首先vimdiff是一款高效的文件的比较和合并的工具&#xff0c;它具有以下一些特点&#xff1a;命令行方式的比较工具&#xff1b;简单明了的界面&#xff1b;对比较出来的多处差异之间快速定位&#xff1b;进行文件合并。再使用vimdiff命令之前&#xff0c;我们…

拆解一个比亚迪的车钥匙,这个黑黑的元器件是什么?

今天抽屉突然找到一个比亚迪的车钥匙&#xff0c;寻思着没事拆开看看用什么方案做的。正面照&#xff0c;哪款车型的&#xff0c;不知道了背面照&#xff0c;很简洁&#xff0c;只有一个BYD的Logo接下来就是撬开了&#xff0c;过程非常顺利&#xff0c;之前撬开一个宝马车的钥匙…

分布式事物(同样适用于dubbo事务等分布式事务)

转载于:https://www.cnblogs.com/tian1993/p/10081901.html

一些web开发中常用的、做成cs文件的js代码 - 搜刮来的

using System;using System.Web;using System.Web.UI;namespace COCOWO.COMP{ /// <summary> /// 一些常用的Js调用 /// 创建时间&#xff1a;2006-8-3 /// 创建者&#xff1a;马先光 /// </summary> public class Jscript { …

库里扛起了勇士对凯尔特人的第四场

最近临近毕业季&#xff0c;有朋友这样说「我一定是要支持勇士的&#xff0c;毕竟库里和詹姆斯陪了整个大学四年啊」。昨晚上加班到11点半&#xff0c;到家洗完澡已经是凌晨1点了&#xff0c;那时候是想得很清楚的&#xff0c;明天是不想被其他事情打扰我看球赛的。这场比赛&am…

Nginx应用案例分享:压力测试

2019独角兽企业重金招聘Python工程师标准>>> 在运维工作中&#xff0c;压力测试是一项非常重要的工作。比如在一个网站上线之前&#xff0c;能承受多大访问量、在大访问量情况下性能怎样&#xff0c;这些数据指标好坏将会直接影响用户体验。 但是&#xff0c;在压力…

shell 判断文件是否存在,没有则创建

没有该文件则创建&#xff0c;有则 ls -l 输出文件信息。 #!/bin/bash echo "enter the name:" read filename if test -e $filename ; then ls -l $filename else touch $filename fi 输出 enter the name: sss.sh -rwxr-xr-x 1 root root 147 Dec 3 09:02 sss.sh …