二叉树的前、中、后序遍历(递归与非递归)

二叉树的遍历

常见的二叉树的遍历有三种方式:前序遍历(根节点,左子树,右子树)

                                                   中序遍历(左子树,根节点,右子树)

                                                   后序遍历(左子树,右子树,根节点)

每种方式都可以用递归非递归来实现

 

一、递归遍历

 

1.先序遍历:

          先访问根节点,再访问左子树,左子树访问完之后,访问右子树

void BTreePrevOrder(BTNode* root)
{
	if (root == NULL)
		return;
	printf("%d ", root->_data);
	BTreePrevOrder(root->_left);
	BTreePrevOrder(root->_right);
}

2.中序遍历:

          先访问左子树,左子树访问完之后,访问根节点,访问右子树

void BTreeInOrder(BTNode* root)
{
	if (root == NULL)
		return;
	BTreeInOrder(root->_left);
	printf("%d ", root->_data);
	BTreeInOrder(root->_right);
}

3.后序遍历:

          先访问左子树,再访问右子树,最后访问根节点

void BTreePostOrder(BTNode* root)
{
	if (root == NULL)
	{
		return;
	}
	BTreePostOrder(root->_left);
	BTreePostOrder(root->_right);
	printf("%d ", root->_data);
}

二叉树遍历的递归实现非常简单

 

二、非递归遍历(用栈来实现)

 

1.先序遍历

          首先打印根节点,将其入栈,判断其左孩子是否为空,若不为空,打印左孩子,将其入栈,重复上述操作,直至左孩子为空。然后取出栈顶元素,将其右孩子当成根节点,重复上述操作。参照下图进行理解。

《二叉树的前、中、后序遍历(递归与非递归)》           

void BTreePrevOrderNonR(BTNode* root)
{	
	Stack s;
	BTNode* cur = root;
	BTNode* top = NULL;

	if (root == NULL)
		return;
	StackInit(&s);
	while (cur || StackEmpty(&s) != 0)
	{
		while (cur)
		{
			printf("%d ", cur->_data);
			StackPush(&s, cur);
			cur = cur->_left;
		}
		top = StackTop(&s);
		StackPop(&s);
		cur = top->_right;
	}
	printf("\n");
}

 

2.中序遍历

 

          中序遍历与先序遍历过程较为相似,只需要改变printf的位置即可。

void BTreeInOrderNonR(BTNode* root)
{
	Stack s;
	BTNode* cur = root;
	BTNode* top = NULL;
	if (root == NULL)
		return;
	StackInit(&s);
	while (cur || StackEmpty(&s) != 0)
	{
		while (cur)
		{
			StackPush(&s, cur);
			cur = cur->_left;
		}
		top = StackTop(&s);
		printf("%d ", top->_data);
		StackPop(&s);
		cur = top->_right;
	}
	printf("\n");

}

 

3.后序遍历:

 

          后序遍历只需要在中序遍历的基础上判断其右子树是否为空,或者是否已经被访问过即可。

void BTreePostOrderNonR(BTNode* root)
{
	Stack s;
	BTNode* cur = root;
	BTNode* top = NULL;
	BTNode* prev = NULL;
	if (root == NULL)
		return;
	StackInit(&s);
	while (cur || StackEmpty(&s) != 0)
	{
		while (cur)
		{
			StackPush(&s, cur);
			cur = cur->_left;
		}
		top = StackTop(&s);
		if (top->_right == NULL || top->_right == prev)
		{
			printf("%d ", top->_data);
			prev = top;
			StackPop(&s);
		}
		else
		{
			cur = top->_right;
		}
	}
        printf("\n");
}

测试代码:

void TestBinaryTree()
{
	DataType a[] = { 1, 2, 3, '#',7,'#', '#', 4, '#', '#', 5, 6, '#', '#','#' };
	size_t index = 0;
	BTNode* tree = CreateBTree(a, &index, '#');
	printf("前序遍历递归  :");
	BTreePrevOrder(tree);
	printf("\n");
	printf("前序遍历非递归:");
	BTreePrevOrderNonR(tree);

	printf("中序遍历递归  :");
	BTreeInOrder(tree);
	printf("\n");
	printf("中序遍历非递归:");
	BTreeInOrderNonR(tree);

	printf("后序遍历递归  :");
	BTreePostOrder(tree);
	printf("\n");
	printf("后序遍历非递归:");
	BTreePostOrderNonR(tree);
}

运行结果:

《二叉树的前、中、后序遍历(递归与非递归)》

 

 

 

 

 

 

 

 

 

    原文作者:夏岚丶苍老的小孩
    原文地址: https://blog.csdn.net/qq_38181018/article/details/79904291
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞