创的技术博客
导航
C++博客
首页
新随笔
联系
聚合
管理
<
2008年7月
>
日
一
二
三
四
五
六
29
30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
7
8
9
统计
随笔 - 144
文章 - 0
评论 - 422
引用 - 0
公告
常用链接
我的随笔
我的评论
我参与的随笔
留言簿
(22)
给我留言
查看公开留言
查看私人留言
随笔分类
(152)
C\C++(17)
(rss)
ccache(3)
(rss)
CGL(5)
(rss)
Linux/Unix(20)
(rss)
Perl(3)
(rss)
操作系统(1)
(rss)
读书笔记(3)
(rss)
服务器设计(21)
(rss)
脚本语言(1)
(rss)
其他(4)
(rss)
设计模式(24)
(rss)
算法与数据结构(36)
(rss)
图形学(1)
(rss)
网络编程(13)
(rss)
随笔档案
(144)
2008年9月 (12)
2008年8月 (11)
2008年7月 (5)
2008年6月 (2)
2008年4月 (3)
2008年3月 (3)
2008年2月 (1)
2008年1月 (2)
2007年12月 (3)
2007年11月 (3)
2007年8月 (1)
2007年7月 (2)
2007年6月 (2)
2007年5月 (9)
2007年4月 (1)
2007年3月 (8)
2007年2月 (3)
2007年1月 (5)
2006年12月 (4)
2006年11月 (3)
2006年10月 (5)
2006年9月 (4)
2006年8月 (13)
2006年7月 (28)
2006年4月 (1)
2006年3月 (4)
2006年2月 (4)
2006年1月 (1)
2005年12月 (1)
相册
文件
开源项目
Larbin
libevent
lighttpd
memcached
PCRE for Windows (Win32)
sqlite
STLFilt
论坛
ChinaUnix
OldLinux
朋友
cugb_cat
Edengundam
win_hate
ypxing
老罗
收藏
Dictionary of Algorithms and Data Structures
unixtoolbox
最新随笔
1. (算法导论习题解exercise2.3-4)递归版插入排序
2. (算法导论习题解problem2.4)寻找一个序列中逆序对的数量
3. (算法导论习题解exercise2.3-7)给定一个整数序列以及一个数X,确定该序列中是否有两个数的和为X
4. 原地归并算法
5. lighttpd1.4.18代码分析(八)--状态机(2)CON_STATE_READ状态
6. lighttpd1.4.18代码分析(七)--状态机(1)CON_STATE_REQUEST_START状态
7. lighttpd1.4.18代码分析(六)--处理连接fd的流程
8. AVL树删除节点算法
9. AVL树中单,双旋转的解释
10. lighttpd1.4.18代码分析(五)--处理超时连接
搜索
积分与排名
积分 - 144311
排名 - 9
最新随笔
1. (算法导论习题解exercise2.3-4)递归版插入排序
2. (算法导论习题解problem2.4)寻找一个序列中逆序对的数量
3. (算法导论习题解exercise2.3-7)给定一个整数序列以及一个数X,确定该序列中是否有两个数的和为X
4. 原地归并算法
5. lighttpd1.4.18代码分析(八)--状态机(2)CON_STATE_READ状态
6. lighttpd1.4.18代码分析(七)--状态机(1)CON_STATE_REQUEST_START状态
7. lighttpd1.4.18代码分析(六)--处理连接fd的流程
8. AVL树删除节点算法
9. AVL树中单,双旋转的解释
10. lighttpd1.4.18代码分析(五)--处理超时连接
最新评论
1. re: 常见设计模式的解析和实现(C++)文档及源码打包下载[未登录]
@云卷去舒
原来写的代码不是很严谨,有不少硬伤,你凑合着看,重点放在设计模式的实现上了.
--创
2. re: [算法]红黑树的实现代码(修订版)
评论内容较长,点击标题查看
--创
3. re: 常见设计模式的解析和实现(C++)文档及源码打包下载
评论内容较长,点击标题查看
--云卷去舒
4. re: 08年个人学习计划
看来你的基础却是不怎么的,四年后才来弄算法。
不过有经验就是比我们学校学生强。
--TALENT
5. re: (算法导论习题解exercise2.3-7)给定一个整数序列以及一个数X,确定该序列中是否有两个数的和为X[未登录]
算法导论给出的算法复杂度精确计算应为nlgn+2*n 额外辅助空间为o(n)
上面那个算法空间复杂度o(1),算法复杂度精确为nlgn+n
--Uo
阅读排行榜
1. 08年个人学习计划(5438)
2. 常见设计模式的解析和实现(C++)文档及源码打包下载(3983)
3. epoll学习笔记(3017)
4. 使用tolua++创建基于C\C++语言的lua脚本(2902)
5. 二叉树遍历算法集合(前中后序遍历的递归和非递归算法,层序遍历算法)(2871)
6. [数据结构]红黑树的实现源码(2621)
7. 探索C++的秘密之一详解extern "C"(2477)
8. 发布我的开源cache库ccache(2228)
9. [算法]红黑树的实现代码(修订版)(2220)
10. (C++)一个愚蠢的错误(2187)
11. P2P原理的解释与实现(2179)
12. 第一个socket程序-C\S模式的文件传输程序(2005)
13. 两种网络数据格式的比较(1986)
14. [算法]找出m个数中最小的n个数(1899)
15. AVL树的实现代码(1872)
16. lighttpd1.4.18代码分析(一)--watcher,worker模型(1869)
17. 研究了一下SGI STL的内存算法(1853)
18. 程序设计经验总结(1759)
19. NeHe OpenGL教程第六课--Texture Mapping(纹理映射)的学习笔记(1723)
20. 服务器公共库开发-内存池管理模块(1689)
21. 如何使用位操作得到大于N且为2的次方的最小的数(1664)
22. 服务器公共库开发--log系统(1610)
23. 架构图 && 瓶颈(1519)
24. [算法问题]合并两个已经排序的数组为另一个数组(1434)
25. AVL树中单,双旋转的解释(1402)
26. 服务器公共库开发--读取ini文件格式的类(1401)
27. 二叉查找树的解析与实现(1400)
28. memcache内存池的设计原理(1381)
29. 探索C++的秘密之二:重载,覆盖,和隐藏 (1365)
30. 服务器公共库开发--线程安全的singleton类, 可配置的线程锁管理类 (1362)
31. 服务器公共库开发--定时器管理器模块(1360)
32. lighttpd1.4.18代码分析(三)--网络IO事件处理器的使用(1355)
33. ccache发布0.2版本(1337)
二叉树遍历算法集合(前中后序遍历的递归和非递归算法,层序遍历算法)
费了两天时间写的,包括前中后序遍历的递归和非递归算法,还有层序遍历总共2*3 + 1 = 7中遍历二叉树的算法,感觉其中后序遍历的非递归算法比较困难,想了很久最后的实现还是不够优雅,请大家指正~~
总共三个文件,一个头文件,一个对应的cpp文件,还有一个用于测试的文件.
头文件:
/**/
/*
*******************************************************************
created: 2006/07/04
filename: BinaryTree.h
author: 李创
http://www.cppblog.com/converse/
purpose: 演示二叉树的算法
********************************************************************
*/
#ifndef BinaryTree_H
#define
BinaryTree_H
#include
<
stdlib.h
>
#include
<
stack
>
class
BinaryTree
{
private
:
typedef
int
Item;
typedef
struct
TreeNode
{
Item Node;
TreeNode
*
pRight;
TreeNode
*
pLeft;
TreeNode(Item node
=
0
, TreeNode
*
pright
=
NULL, TreeNode
*
pleft
=
NULL)
: Node(node)
, pRight(pright)
, pLeft(pleft)
{
}
}
TreeNode,
*
PTreeNode;
public
:
enum
TraverseType
{
PREORDER
=
0
,
//
前序
INORDER
=
1
,
//
中序
POSTORDER
=
2
,
//
后序
LEVELORDER
=
3
//
层序
}
;
BinaryTree(Item Array[],
int
nLength);
~
BinaryTree();
PTreeNode GetRoot()
{
return
m_pRoot;
}
//
遍历树的对外接口
//
指定遍历类型和是否是非递归遍历,默认是递归遍历
void
Traverse(TraverseType traversetype,
bool
bRec
=
true
);
private
:
PTreeNode CreateTreeImpl(Item Array[],
int
nLength);
void
DetroyTreeImpl(PTreeNode pTreenode);
void
PreTraverseImpl(PTreeNode pTreenode);
//
递归前序遍历树
void
InTraverseImpl(PTreeNode pTreenode);
//
递归中序遍历树
void
PostTraverseImpl(PTreeNode pTreenode);
//
递归后序遍历树
void
NoRecPreTraverseImpl(PTreeNode pTreenode);
//
非递归前序遍历树
void
NoRecInTraverseImpl(PTreeNode pTreenode);
//
非递归中序遍历树
void
NoRecPostTraverseImpl(PTreeNode pTreenode);
//
非递归后序遍历树
void
LevelTraverseImpl(PTreeNode pTreenode);
PTreeNode m_pRoot;
//
根结点
//
采用STL里面的stack作为模拟保存链表结点的stack容器
typedef std::stack
<
BinaryTree::PTreeNode
>
TreeNodeStack;
}
;
#endif
实现文件:
/**/
/*
*******************************************************************
created: 2006/07/04
filename: BinaryTree.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: 演示二叉树的算法
********************************************************************
*/
#include
<
iostream
>
#include
<
assert.h
>
#include
<
queue
>
#include
"
BinaryTree.h
"
BinaryTree::BinaryTree(Item Array[],
int
nLength)
: m_pRoot(NULL)
{
assert(NULL
!=
Array);
assert(nLength
>
0
);
m_pRoot
=
CreateTreeImpl(Array, nLength);
}
BinaryTree::
~
BinaryTree()
{
DetroyTreeImpl(m_pRoot);
}
//
按照中序递归创建树
BinaryTree::PTreeNode BinaryTree::CreateTreeImpl(Item Array[],
int
nLength)
{
int
mid
=
nLength
/
2
;
PTreeNode p
=
new
TreeNode(Array[mid]);
if
(nLength
>
1
)
{
p
->
pLeft
=
CreateTreeImpl(Array, nLength
/
2
);
p
->
pRight
=
CreateTreeImpl(Array
+
mid
+
1
, nLength
/
2
-
1
);
}
return
p;
}
void
BinaryTree::DetroyTreeImpl(PTreeNode pTreenode)
{
if
(NULL
!=
pTreenode
->
pLeft)
{
DetroyTreeImpl(pTreenode
->
pLeft);
}
if
(NULL
!=
pTreenode
->
pRight)
{
DetroyTreeImpl(pTreenode
->
pRight);
}
delete pTreenode;
pTreenode
=
NULL;
}
//
遍历树的对外接口
//
指定遍历类型和是否是非递归遍历,默认是递归遍历
void
BinaryTree::Traverse(TraverseType traversetype,
bool
bRec
/**/
/*
= true
*/
)
{
switch
(traversetype)
{
case
PREORDER:
//
前序
{
if
(
true
==
bRec)
{
std::cout
<<
"
递归前序遍历树\n
"
;
PreTraverseImpl(m_pRoot);
}
else
{
std::cout
<<
"
非递归前序遍历树\n
"
;
NoRecPreTraverseImpl(m_pRoot);
}
}
break
;
case
INORDER:
//
中序
{
if
(
true
==
bRec)
{
std::cout
<<
"
递归中序遍历树\n
"
;
InTraverseImpl(m_pRoot);
}
else
{
std::cout
<<
"
非递归中序遍历树\n
"
;
NoRecInTraverseImpl(m_pRoot);
}
}
break
;
case
POSTORDER:
//
后序
{
if
(
true
==
bRec)
{
std::cout
<<
"
递归后序遍历树\n
"
;
PostTraverseImpl(m_pRoot);
}
else
{
std::cout
<<
"
非递归后序遍历树\n
"
;
NoRecPostTraverseImpl(m_pRoot);
}
}
break
;
case
LEVELORDER:
//
层序
{
std::cout
<<
"
层序遍历树\n
"
;
LevelTraverseImpl(m_pRoot);
}
}
std::cout
<<
std::endl;
}
//
递归前序遍历树
void
BinaryTree::PreTraverseImpl(PTreeNode pTreenode)
{
if
(NULL
==
pTreenode)
return
;
std::cout
<<
"
Item =
"
<<
pTreenode
->
Node
<<
std::endl;
PreTraverseImpl(pTreenode
->
pLeft);
PreTraverseImpl(pTreenode
->
pRight);
}
//
非递归前序遍历树
void
BinaryTree::NoRecPreTraverseImpl(PTreeNode pTreenode)
{
if
(NULL
==
pTreenode)
return
;
TreeNodeStack NodeStack;
PTreeNode pNode;
NodeStack.push(pTreenode);
while
(
!
NodeStack.empty())
{
while
(NULL
!=
(pNode
=
NodeStack.top()))
//
向左走到尽头
{
std::cout
<<
"
Item =
"
<<
pNode
->
Node
<<
std::endl;
//
访问当前结点
NodeStack.push(pNode
->
pLeft);
//
左子树根结点入栈
}
NodeStack.pop();
//
左子树根结点退栈
if
(
!
NodeStack.empty())
{
pNode
=
NodeStack.top();
NodeStack.pop();
//
当前结点退栈
NodeStack.push(pNode
->
pRight);
//
当前结点的右子树根结点入栈
}
}
}
//
中序遍历树
//
中序遍历输出的结果应该和用来初始化树的数组的排列顺序一致
void
BinaryTree::InTraverseImpl(PTreeNode pTreenode)
{
if
(NULL
==
pTreenode)
return
;
if
(NULL
!=
pTreenode
->
pLeft)
{
InTraverseImpl(pTreenode
->
pLeft);
}
std::cout
<<
"
Item =
"
<<
pTreenode
->
Node
<<
std::endl;
if
(NULL
!=
pTreenode
->
pRight)
{
InTraverseImpl(pTreenode
->
pRight);
}
}
//
非递归中序遍历树
void
BinaryTree::NoRecInTraverseImpl(PTreeNode pTreenode)
{
if
(NULL
==
pTreenode)
return
;
TreeNodeStack NodeStack;
PTreeNode pNode;
NodeStack.push(pTreenode);
while
(
!
NodeStack.empty())
{
while
(NULL
!=
(pNode
=
NodeStack.top()))
//
向左走到尽头
{
NodeStack.push(pNode
->
pLeft);
}
NodeStack.pop();
if
(
!
NodeStack.empty()
&&
NULL
!=
(pNode
=
NodeStack.top()))
{
std::cout
<<
"
Item =
"
<<
pNode
->
Node
<<
std::endl;
NodeStack.pop();
NodeStack.push(pNode
->
pRight);
}
}
}
//
后序遍历树
void
BinaryTree::PostTraverseImpl(PTreeNode pTreenode)