非递归遍历二叉树

来源:互联网 发布:战地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;
}

原创粉丝点击