非递归遍历二叉树
来源:互联网 发布:战地2数据修改器 编辑:程序博客网 时间:2024/05/04 20:08
// 中序递归遍历
void InOrderTrvDiGui(NODE* pNode)
{
if(pNode)
{
InOrderTrvDiGui(pNode->leftNode);
cout << pNode->info; // visit node
InOrderTrvDiGui(pNode->rightNode);
}
}
然而,当树的深度很大(比如16)时(假设为满二叉树),树的节点数为 2^0 + 2^1 + 2^2 + ... + 2^15 = 2^16 = 65536,遍历整个二叉树意味着有65536次函数调用,这将极大地增加程序运行时间。这时,应该采取非递归便利二叉树的算法。
非递归遍历二叉树模拟递归调用时程序地址的压栈、出栈操作,必须引入一个stack保存结点地址。它的程序运行开销大大低于递归遍历算法。
下面列举出三种非递归遍历二叉树算法代码。
// 代码经过调试成功
#include
#include
#include
#include
using namespace std;
typedef struct tagNode{
char info;
struct tagNode* leftNode;
struct tagNode* rightNode;
}NODE;
typedef struct tagTree{
NODE* pRootNode;
}TREE;
// 初始化树
void InitTree(TREE* pTree)
{
NODE* pNode[24];
char str[30] = "qian, i love you so much";
for(int i=0;i<24;i++)
{
pNode[i] = new NODE;
pNode[i]->info = str[i];
pNode[i]->leftNode = NULL;
pNode[i]->rightNode = NULL;
}
pTree->pRootNode = pNode[11];
pNode[11]->leftNode = pNode[7];
pNode[11]->rightNode = pNode[16];
pNode[7]->leftNode = pNode[3];
pNode[7]->rightNode = pNode[9];
pNode[3]->leftNode = pNode[0];
pNode[3]->rightNode = pNode[5];
pNode[0]->rightNode = pNode[2];
pNode[2]->leftNode = pNode[1];
pNode[5]->leftNode = pNode[4];
pNode[5]->rightNode = pNode[6];
pNode[9]->leftNode = pNode[8];
pNode[9]->rightNode = pNode[10];
pNode[16]->leftNode = pNode[14];
pNode[16]->rightNode = pNode[19];
pNode[14]->leftNode = pNode[12];
pNode[12]->rightNode = pNode[13];
pNode[14]->rightNode = pNode[15];
pNode[19]->leftNode = pNode[17];
pNode[17]->rightNode = pNode[18];
pNode[19]->rightNode = pNode[21];
pNode[21]->leftNode = pNode[20];
pNode[21]->rightNode = pNode[23];
pNode[23]->leftNode = pNode[22];
}
// 先序非递归遍历
void PreOrderTrv(NODE* pRootNode)
{
stack NodePtrStack;
NODE* pNode = pRootNode;
while(pNode != NULL || !NodePtrStack.empty())
{
if(pNode != NULL)
{
NodePtrStack.push(pNode);
cout << pNode->info; // visit node
pNode = pNode->leftNode;
}
else
{
pNode = NodePtrStack.top();
NodePtrStack.pop();
pNode = pNode->rightNode;
}
}
}
// 中序非递归遍历
void InOrderTrv(NODE* pRootNode)
{
stack NodePtrStack;
NODE* pNode = pRootNode;
while(pNode != NULL || !NodePtrStack.empty())
{
if(pNode != NULL)
{
NodePtrStack.push(pNode);
pNode = pNode->leftNode;
}
else
{
pNode = NodePtrStack.top();
NodePtrStack.pop();
cout << pNode->info; // visit node
pNode = pNode->rightNode;
}
}
}
// 中序递归遍历
void InOrderTrvDiGui(NODE* pNode)
{
if(pNode)
{
InOrderTrvDiGui(pNode->leftNode);
cout << pNode->info;
InOrderTrvDiGui(pNode->rightNode);
}
}
// 后序非递归遍历
void PostOrderTrv(NODE* pRootNode)
{
stack NodePtrStack;
NODE* pNode = pRootNode;
NODE* pre = NULL;
while(pNode != NULL || !NodePtrStack.empty())
{
//沿着左孩子方向走到最左下 。
while(pNode)
{
NodePtrStack.push(pNode);
pNode = pNode->leftNode;
}
//get the top element of the stack
pNode = NodePtrStack.top();
//如果p没有右孩子或者其右孩子刚刚被访问过
if(pNode->rightNode == NULL || pNode->rightNode == pre)
{
cout << pNode->info; // visit node
NodePtrStack.pop();
pre = pNode;
pNode = NULL;
}
else
{
pNode = pNode->rightNode;
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
TREE tree;
InitTree(&tree);
wcout << "中序非递归遍历二叉树" << endl;
InOrderTrv(tree.pRootNode);
cout << endl;
wcout << "先序非递归遍历二叉树" << endl;
PreOrderTrv(tree.pRootNode);
cout << endl;
wcout << "后序非递归遍历二叉树" << endl;
PostOrderTrv(tree.pRootNode);
cout << endl;
return 0;
}
- 非递归遍历二叉树
- 二叉树遍历非递归
- 非递归遍历二叉树
- 二叉树非递归遍历
- 二叉树非递归遍历
- 非递归遍历二叉树
- 二叉树非递归遍历
- 非递归遍历二叉树
- 非递归遍历二叉树
- 非递归遍历二叉树
- 非递归遍历二叉树
- 非递归遍历二叉树
- 二叉树非递归遍历
- 二叉树遍历--非递归
- 二叉树非递归遍历
- 非递归遍历二叉树
- 二叉树非递归遍历
- 二叉树非递归遍历
- vsftpd 虚拟用户 多用户不同权限管理
- 创建网站快捷方式
- pthread_join
- 深度剖析WinPcap之(九)——数据包的发送过程(10)
- vsftpd虚拟用户 权限配置
- 非递归遍历二叉树
- 深度剖析WinPcap之(九)——数据包的发送过程(11)
- asp.net gridview表头排序代码(全部代码),供以后使用方便 VS2008
- c#.NET winform 利用windows media player播放视频,循环播放视频
- DIV边框样式设置
- DeepWaterAnimationandRendering
- 深度剖析WinPcap之(九)——数据包的发送过程(12)
- svn服务器配置
- 委托和事件 10.6.23