二叉树的4种非递归遍历

目录

1.用队列实现层序遍历(判断是否为完全二叉树)

1.实现层序遍历

2.判断二叉树是否为完全二叉树

 2.二叉树的前序遍历(非递归)

3.二叉树的中序遍历(非递归)

4.二叉树的后序遍历(非递归)


1.用队列实现层序遍历(判断是否为完全二叉树)

二叉树的4种非递归遍历_第1张图片

1.实现层序遍历

void LevelOrder(BTNode* root)
{
	Queue q;//创建一个队列,
	QueueInit(&q);//队列初始化

	if (root)
	{
		QueuePush(&q, root);//将头节点入队列
	}

	while (!QueueEmpty(&q))//队列不为空,则继续
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);//节点出队列

		printf("%d ", front->data);
		if (front->left)//左孩子进队列
		{
			QueuePush(&q, front->left);
		}

		if (front->right)//右孩子进队列
		{
			QueuePush(&q, front->right);
		}
	}

	printf("\n");
	QueueDestory(&q);//销毁队列
}

2.判断二叉树是否为完全二叉树

思想:用队列实现层序遍历,孩子为NULL也进队列,当出队列的元素是NULL时,把后面所有元素都出队列。若后面元素都为空,即是完全二叉树,若不是,则非完全二叉树。2

bool BTreeComplete(BTNode* root)
{
	Queue q;
	QueueInit(&q);

	if (root)
		QueuePush(&q, root);
	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);
		if (front == NULL)//队列出元素,若是NULL,则break,后面把所有元素出队列
			break;

		QueuePush(&q, front->left);
		QueuePush(&q, front->right);
	}

	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);
		if (front)// 空后面出到非空,那么说明不是完全二叉树
		{
			QueueDestory(&q);
			return false;
		}
	}

	QueueDestory(&q);
	return true;

 2.二叉树的前序遍历(非递归)

根->左子树->右子树


	List* p1 = (List*)malloc(sizeof(List));
	List* p2 = (List*)malloc(sizeof(List));
	List* p3 = (List*)malloc(sizeof(List));
	List* p4 = (List*)malloc(sizeof(List));
	List* p5 = (List*)malloc(sizeof(List));
	List* p6 = (List*)malloc(sizeof(List));
	p1->a = 'A';
	p2->a = 'B';
	p3->a = 'C';
	p4->a = 'D';
	p5->a = 'E';
	p6->a = 'F';
	p1->left = p2;
	p1->right = p3;
	p2->left = p4;
	p2->right = p5;
	p3->left = p3->right = NULL;
	p4->left = p4->right = NULL;
	p5->left = NULL;
	p5->right = p6;
	p6->left = p6->right = NULL;
    创建的二叉树如下图

思想:如图:

二叉树的4种非递归遍历_第2张图片

 二叉树的4种非递归遍历_第3张图片

 二叉树的4种非递归遍历_第4张图片

二叉树的4种非递归遍历_第5张图片

 二叉树的4种非递归遍历_第6张图片

 二叉树的4种非递归遍历_第7张图片

 二叉树的4种非递归遍历_第8张图片

二叉树的4种非递归遍历_第9张图片

 代码实现:

    ST ps;//创建一个栈:ps
	StackInit(&ps);
	StackPush(&ps,p1);//先将头节点入栈
	while (!StackEmpty(&ps))//栈不为空则继续
	{
		List* front = StackTop(&ps);
		StackPop(&ps);//头节点出栈
		printf("%c ", front->a);
		if (front->right)//先将右孩子入栈
		{
			StackPush(&ps,front->right);
		}
		if (front->left)//再将左孩子入栈
		{
			StackPush(&ps, front->left);
		}
	}

3.二叉树的中序遍历(非递归)

左子树->根->右子树

思路:遇到节点,先把它入栈,后面依次遍历它的左子树,若该节点的左子树为空,将其出栈,然后遍历该节点的右子树(遍历右子树的方法:先把它入栈,后面依次遍历它的左子树,若该节点的左子树为空,将其出栈,然后遍历该节点的右子树)。

    ST ps;
	StackInit(&ps);
	List* front = p1;
	while (!StackEmpty(&ps)||front)
	{
		while (front)
		{
			StackPush(&ps, front);//节点不为空,就入栈
			front = front->left;//找左孩子
		}
		if (!StackEmpty(&ps))
		{
			front = StackTop(&ps);若该节点左孩子为空,将其出栈,后找该节点右孩子
			StackPop(&ps);
			printf("%c ", front->a);
			front = front->right;//后以同样的方法遍历右孩子
		}	  
	}

4.二叉树的后序遍历(非递归)

思路:在前序遍历的过程中,孩子入栈的顺序颠倒一下(先进左孩子,再进右孩子),再把出栈的元素放入另一个栈B。遍历完后,再将栈B元素出栈,即使后序遍历

    ST ps;
	ST pss;
	StackInit(&ps);//创建两个栈ps,pss
	StackInit(&pss);
	StackPush(&ps, p1);
	while (!StackEmpty(&ps))
	{
		List* front = StackTop(&ps);
		StackPop(&ps);
		StackPush(&pss, front);//将出栈元素放入新的栈中
		if (front->left)
		{
			StackPush(&ps, front->left);//先将左孩子入栈
		}
		if (front->right)//再将右孩子入栈
		{
			StackPush(&ps, front->right);
		}
	}
	while (!StackEmpty(&pss))
	{
		List* front = StackTop(&pss);
		StackPop(&pss);
		printf("%c ", front->a);
	}

你可能感兴趣的:(数据结构,数据结构)