惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

大猫的无限游戏
大猫的无限游戏
博客园 - 【当耐特】
Cloudbric
Cloudbric
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Attack and Defense Labs
Attack and Defense Labs
爱范儿
爱范儿
The Cloudflare Blog
腾讯CDC
Security Archives - TechRepublic
Security Archives - TechRepublic
TaoSecurity Blog
TaoSecurity Blog
云风的 BLOG
云风的 BLOG
Recent Announcements
Recent Announcements
C
Check Point Blog
Schneier on Security
Schneier on Security
S
Schneier on Security
J
Java Code Geeks
B
Blog RSS Feed
Cisco Talos Blog
Cisco Talos Blog
Vercel News
Vercel News
Stack Overflow Blog
Stack Overflow Blog
博客园_首页
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
A
About on SuperTechFans
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Google DeepMind News
Google DeepMind News
阮一峰的网络日志
阮一峰的网络日志
罗磊的独立博客
A
Arctic Wolf
S
Secure Thoughts
P
Palo Alto Networks Blog
The Last Watchdog
The Last Watchdog
SecWiki News
SecWiki News
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
博客园 - 三生石上(FineUI控件)
D
Darknet – Hacking Tools, Hacker News & Cyber Security
量子位
U
Unit 42
I
InfoQ
D
DataBreaches.Net
P
Privacy International News Feed
T
Troy Hunt's Blog
博客园 - 叶小钗
T
Threatpost
博客园 - Franky
K
Kaspersky official blog
Hugging Face - Blog
Hugging Face - Blog
IT之家
IT之家
www.infosecurity-magazine.com
www.infosecurity-magazine.com
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
C
Cisco Blogs

博客园 - begincsdn

C# 自定义光标使用的常见方法 Pentium指令的执行周期数[转] 计算机图形学 -- 光栅图形学扫描线填充多边形[转] 推荐一个跨平台内存分配器【转载】 几何图形库-GEOS使用示例(1) 开源几何计算数学库 C++中固定长度短字符串比较是否相同,忽略大小写比对时的小技巧 二维图形变换公式推导---------旋转变换 .NET 漫淡(一) --- 需要充分认识的应用程序域-AppDomain Gerber 文件格式(一):RS-274X 语法 SCRUM 系列之一 ----- 认识SRCUM GERBER文件格式简介 迷思微软两大框架的RTTI(Run-Time Type Identification) Remoting中,关于获取某接口派生的自定义属性(CustomAttribute)的问题 让你的VS。NET2003可以调试ASP服务器脚本。 UNION,EXISTS,IN等在SQL语句中的灵活应用和场境的选择。 欢迎大家加入我申请的QQ群。 客户端独立弹出详细的实现过程 - begincsdn - 博客园 Microsoft.Visual.Studio..NET.2005.预发行版 EMULE下载
二叉树的递归遍历以及非递归遍历(一)----先序遍历(转)
begincsdn · 2012-10-12 · via 博客园 - begincsdn

二叉树的递归遍历以及非递归遍历(一)----先序遍历

1.二叉树的遍历方式:

先序遍历、中序遍历、后序遍历(此处不考虑层次遍历)

先序遍历:先访问根节点,再访问左子树,然后是右子树

中序遍历:先访问左子树,然后是根节点,然后是右子树

后序遍历:先访问左子树,然后右子树,最后是根节点。

2. 二叉树基本数据结构定义:

typedef struct TNode

{

int val;

struct TNode* pLeft;

struct TNode* pRight;

TNode(int val, TNode* pLeft, TNode* pRight)

{

this->val = val;

this->pLeft = pLeft;

this->pRight = pRight;

}

TNode()

{

}

~TNode()

{

if (pLeft)

{

delete pLeft;

pLeft = NULL;

}

if (pRight)

{

delete pRight;

pRight = NULL;

}

}

}TNode;

二叉树的构造:

/**************************************************************************************

4

1 5

2 3 6 7

***************************************************************************************/

TNode* buildTree()

{

TNode *p = new TNode(1,

new TNode(2, NULL,NULL),

new TNode(3, NULL,NULL));

TNode *q = new TNode(4,

p,

new TNode(5,

new TNode(6, NULL,NULL),

new TNode(7, NULL,NULL)));

return q;

};

树的逻辑结构如下:

clip_image002[4]

图一(测试用树结构)

3. 先序遍历

3.1 先序遍历的递归写法:

/**********************************************

功能:递归先序遍历

注:遍历顺序为根左右

**********************************************/

void preTraverse(TNode* pRoot)

{

if (!pRoot) return;

visit(pRoot);

preTraverse(pRoot->pLeft);

preTraverse(pRoot->pRight);

}

3.2 先序遍历的非递归写法:

/**********************************************

功能:非递归先序遍历

住:遍历顺序为根左右

**********************************************/

void preNoRecTraverse(TNode* pRoot)

{

stack<TNode*> s;

TNode* p = pRoot;

s.push(p);

while (p || !s.empty())

{

p = s.top();

s.pop();

visit(p);

if (p->pRight) s.push(p->pRight);

if (p->pLeft) s.push(p->pLeft);

}

}

3.3 过程模拟及结果展示:

递归调用过程:

clip_image003

图二:递归调用的函数调用层次关系

非递归的遍历过程,其实就是模拟递归算法中的堆栈进出顺序。

在递归调用中,可以看到在每一次的递归调用中,总是首先访问根,然后访问左子树,然后访问右子树。对右子树的访问在左子树访问的后面。所以右子树的根先入栈,右子树的根后入栈。

栈的进出图如下:

clip_image005

图三:非递归调用的栈进出图

遍历结果为:(4,1,2,3,5,6,7)

递归算法和非递归算法的比较:

此处把正在运行的函数看成是一个栈,调用其他函数看成是进栈,调用函数运行完认为是出栈,模拟一下递归调用的栈:

clip_image007

共同点:两者对节点的遍历次序一致

区别:在非递归调用中,对右子树的访问在左子树后面,所以先将右子树节点压栈,再压左子树节点,这样在出栈进行遍历的时候起到先遍历左子树,再遍历右子树的效果。
在递归调用中,对左右子树调用的先后区别在于是先调用左子树的遍历函数,再调用右子树的遍历函数,起到的效果是一致的。