您的位置:首页 > 其它

二叉树的遍历(递归和非递归)

2012-07-06 22:01 246 查看
包括前序、中序、后序的递归与非递归,以及层次遍历

前序非递归

(1) 当节点不为空时,访问完该节点数据后,该节点需要进栈保存,然后访问其左子树节点

(2) 当栈中节点出栈时,说明该节点及其左子树节点已经访问完成,出栈后进入其右子树进行访问

中序非递归

(1) 和前序非递归类似,不同的是访问节点数据的时机,在出栈时访问即可

后序非递归

(1) 需要一个标志来记录该节点数据是否被访问

(2) 若栈不为空且栈顶元素的tag为1,表明栈点元素的左右子树已经访问完成,接下来应该访问栈顶点元素数据

层次:用队列来实现

(1) 首先将根节点入队

(2) 当队列不为空时,出队并访问该节点数据,然后将该节点左子树(存在)、右子树(存在)分别入队

实现代码如下:

#include <iostream>
#include <stack>
#include <queue>

using namespace std;

struct TreeNode
{
	int data;
	int tag;		//0表示未被访问,1表示已经访问(应用于后序非递归)
	TreeNode *lChid;
	TreeNode *rChidl;

	TreeNode(int key, TreeNode *pLeft, TreeNode *pRight):data(key),tag(0), lChid(pLeft), rChidl(pRight) {}
};

void createTree(TreeNode **root);

//前序
void preOrderTraverse(TreeNode *root);
void preOrderTraverse_not_recursive(TreeNode *root);

//中序
void inOrderTraverse(TreeNode *root);
void inOrderTraverse_not_recursive(TreeNode *root);

//后序
void postOrderTraverse(TreeNode *root);
void postOrderTraverse_not_recursive(TreeNode *root);

//按层次遍历
void levelOrderTraverse(TreeNode *root);

int main()
{
	TreeNode *root = NULL;
	createTree(&root);

	//前序
	cout << "前序:";
	preOrderTraverse(root);		
	cout << "\n前序非递归:";
	preOrderTraverse_not_recursive(root);	
	cout << endl;

	//中序
	cout << "\n中序:";
	inOrderTraverse(root);
	cout << "\n中序非递归:";
	inOrderTraverse_not_recursive(root);
	cout << endl;

	//后序
	cout << "\n后序:";
	postOrderTraverse(root);
	cout << "\n后序非递归:";
	postOrderTraverse_not_recursive(root);
	cout << endl;

	//层次
	cout << "\n层次:";
	levelOrderTraverse(root);
	cout << endl;

	//这里没有考虑销毁树(即没考虑内存泄露)
	system("pause");
	return 0;
}

void createTree(TreeNode **root)
{
	TreeNode *node7 = new TreeNode(7, NULL, NULL);
	TreeNode *node6 = new TreeNode(6, NULL, NULL);
	TreeNode *node5 = new TreeNode(5, node7, NULL);
	TreeNode *node4 = new TreeNode(4, NULL, NULL);
	TreeNode *node3 = new TreeNode(3, node5, node6);
	TreeNode *node2 = new TreeNode(2, NULL, node4);
	*root = new TreeNode(1, node2, node3);
}

/***********************************************************************/
//FUNCTION:前序遍历
void preOrderTraverse(TreeNode *root)
{
	if (root != NULL)
	{
		cout << root->data << "  ";
		preOrderTraverse(root->lChid);
		preOrderTraverse(root->rChidl);
	}
}

void preOrderTraverse_not_recursive(TreeNode *root)
{
	stack<TreeNode*> stk;
	while (root != NULL || !stk.empty())
	{
		while (root != NULL)			
		{
			cout << root->data << "  ";	
			stk.push(root);				
			root = root->lChid;			
		}

		if (!stk.empty())				
		{
			root = stk.top();
			stk.pop();					
			root = root->rChidl;	
		}
	}
}

/***********************************************************************/
//FUNCTION:中序遍历
void inOrderTraverse(TreeNode *root)
{
	if (root != NULL)
	{
		inOrderTraverse(root->lChid);
		cout << root->data << "  ";
		inOrderTraverse(root->rChidl);
	}
}

void inOrderTraverse_not_recursive(TreeNode *root)
{
	stack<TreeNode*> stk;
	while (root != NULL || !stk.empty())
	{
		while (root != NULL)			
		{
			stk.push(root);				
			root = root->lChid;		
		}

		if (!stk.empty())				
		{
			root = stk.top();
			stk.pop();					
			cout << root->data << "  ";	
			root = root->rChidl;	
		}
	}
}

/***********************************************************************/
//FUNCTION:后序遍历
void postOrderTraverse(TreeNode *root)
{
	if (root != NULL)
	{
		postOrderTraverse(root->lChid);
		postOrderTraverse(root->rChidl);
		cout << root->data << "  ";
	}
}

void postOrderTraverse_not_recursive(TreeNode *root)
{
	stack<TreeNode*> stk;
	while (root != NULL || !stk.empty())
	{
		while (root != NULL)			
		{
			stk.push(root);				
			root = root->lChid;			
		}

		while (!stk.empty() && stk.top()->tag == 1)
		{
			root = stk.top();
			cout << root->data << "  ";
			stk.pop();
		}

		if (!stk.empty())				
		{
			root = stk.top();
			root->tag = 1;					
			root = root->rChidl;		
		}
		else
			root = NULL;
	}
}

/***********************************************************************/
//FUNCTION:按层次遍历
void levelOrderTraverse(TreeNode *root)
{
	queue<TreeNode*> qQueue;
	if (root != NULL)
	{
		qQueue.push(root);

		while (!qQueue.empty())
		{
			root = qQueue.front();
			cout << root->data << "  ";
			qQueue.pop();

			if (root->lChid != NULL)
				qQueue.push(root->lChid);

			if (root->rChidl != NULL)
				qQueue.push(root->rChidl);
		}
	}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: