二叉树——前序、中序、后序(递归、非递归遍历)、层序(队列、数组实现)

结构体:

typedef char BTDataType;

typedef struct BTNode
{
	struct BTNode* pLeft;
	struct BTNode* pRight;
	BTDataType data;
}BTNode;

前序遍历(递归,非递归):


void PreOrder(BTNode* pRoot)   //前序
{
	if (pRoot == NULL)
		return;

	printf("%d", pRoot->data);
	PreOrder(pRoot->pLeft);
	PreOrder(pRoot->pRight);
}


//先序遍历(非递归):
//①首先访问根节点是否为空,则入栈→输出栈顶元素→当前节点的左子树入栈     
//②当左子树为空,则栈顶元素出栈,转向该节点的右子树                  
//③全部元素出栈以后,结束循环
void PreOrderNor(BTNode* pRoot, vector<int> &path)
{
	//非递归前序遍历

	    stack<BTNode *> s;
		BTNode *p = pRoot;

		while (p != NULL || !s.empty())
		{
			while (p != NULL)
			{
				path.push_back(p->data);
				s.push(p);
				p = p->pLeft;
			}

			if (!s.empty())
			{
				p = s.top();
				s.pop();
				p = p->pRight;
			}
		}
	
}

中序遍历(递归、非递归):

void InOrder(BTNode* pRoot)  //中序
{
	if (pRoot == NULL)
		return;

	PreOrder(pRoot->pLeft);
	printf("%d", pRoot->data);
	PreOrder(pRoot->pRight);
}

//中序遍历:
//①入栈→当前节点的左子树入栈
//②当左子树为空,则栈顶元素出栈,输出栈顶元素→转向该节点的右子树
//③栈为空时,结束循环
void InOrderNor(BTNode* pRoot, vector<int> &path)
{
	//非递归中序遍历
		stack<BTNode *> s; 
		BTNode *p = pRoot; 
		while (p != NULL || !s.empty())
		{
			while (p != NULL)
			{ 
				s.push(p); 
				p = p->pLeft;
			}        
			if (!s.empty())
			{ 
				p = s.top(); 
				path.push_back(p->data);
				s.pop(); 
				p = p->pRight;
			}
		}
}

后序遍历(递归、非递归):


void PostOrderNor(BTNode* pRoot, vector<int> &path)
{
	//非递归后序遍历-迭代
		stack<BTNode *> s; 
		BTNode *p = pRoot;  
		BTNode *temp;  
		while (p != NULL || !s.empty()) 
		{
			while (p != NULL) //沿左子树一直往下搜索,直至出现没有左子树的结点  
			{
				BTNode *tempNode = new BTNode;         
				tempNode->btnode = p;
				tempNode->isFirst = true; 
				s.push(tempNode); 
				p = p->pLeft;
			}        
			if (!s.empty())
			{
				temp = s.top();
				s.pop();
				if (temp->isFirst == true)   //表示是第一次出现在栈顶     
				{
					temp->isFirst = false; 
					s.push(temp); 
					p = temp->btnode->right;
				}     
				else  //第二次出现在栈顶     
				{
					path.push_back(temp->btnode->val);    
					p = NULL; 
				} 
			}
		}
}

层序遍历(队列实现):

//队列实现:
//1、首先将二叉树的根节点push到队列中,判断队列不为NULL,就输出队头的元素,
//2、判断节点如果有孩子,就将孩子push到队列中,
//3、遍历过的节点出队列,
//4、循环以上操作,直到Tree == NULL

void LevelOrder1(BTNode &Tree) //层序遍历_队列实现
{
	queue < BTNode> q;
	if (Tree != NULL)
	{
		q.push(Tree);   //根节点进队列
	}

	while (q.empty() == false)  //队列不为空判断
	{
		cout << q.front()->data << " → ";

		if (q.front()->pLeft != NULL)   //如果有左孩子,左孩子入队列
		{
			q.push(q.front()->pLeft);
		}

		if (q.front()->pRight != NULL)   //如果有右孩子,右孩子入队列
		{
			q.push(q.front()->pRight);
		}
		q.pop();  //已经遍历过的节点出队列
	}
}

层序遍历(数组实现):


//数组实现:
//实现过程
//1、创建一个指针数组,保存二叉树结构体指针,
//2、保存二叉树根节点,再申请变量 in、out ,控制数组,在遍历过程中,始终能找到节点和该节点的前一个节点,
//3、循环以上过程
void LevelOrder2(BTNode Tree)  //层序遍历
{
	BTNode temp[100];   //创建指针数组
	int in = 0;
	int out = 0;

	temp[in++] = Tree;  //先保存二叉树根节点 

	while (in > out)
	{
		if (temp[out])
		{
			cout << temp[out]->data << " → ";
			temp[in++] = temp[out]->leftPtr;
			temp[in++] = temp[out]->rightPtr;
		}
		out++;
	}
}

猜你喜欢

转载自blog.csdn.net/qq_42659468/article/details/89481606