二叉树的非递归遍历

1.非递归前序遍历步骤:

                                   1.申请一个辅助栈

                                    2.循环遍历二叉树:如果二叉树结点非空,则打印,结点入栈,二叉树向左走

                                    3. 栈顶元素弹出

                                     4.判断弹出得栈顶元素的右子树:如果右子树存在,则继续重复步骤2,3,4

                                                                                       如果右子树不存在,重复步骤2,3,4

                                     循环直到栈为空时结束

代码如下:

typedef struct node1
{
	int nValue;
	struct node1 *pLeft;
	struct node1 *pRight;
}BinaryTree;

typedef struct node
{
	BinaryTree* nValue;
	struct node *pNext;
}MyStack;

typedef struct node2
{
	MyStack *pTop;
	int nCount;
}Stack;


//用到栈的基本操作
void s_Init(Stack **pStack)
{
	*pStack = (Stack *)malloc(sizeof(Stack));
	(*pStack)->pTop = NULL;
	(*pStack)->nCount = 0;
}

void s_Push(Stack *pStack,BinaryTree* nNum)
{
	if(pStack == NULL)
	{
		printf("stack is not exist.\n");
		return;
	}

	MyStack *pTemp = NULL;
	pTemp = (MyStack*)malloc(sizeof(MyStack));
	pTemp->nValue = nNum;
	
	//新来节点的下一个是原来的栈顶
	pTemp->pNext = pStack->pTop;

	//新来节点成为新的栈顶
	pStack->pTop = pTemp;
	
	//计数器
	pStack->nCount++;
}

BinaryTree* s_Pop(Stack *pStack)
{
	if(pStack == NULL || pStack->pTop == NULL)return NULL;

	MyStack *pDel = NULL;
	pDel = pStack->pTop;

	BinaryTree* nNum = NULL;
	nNum = pDel->nValue;

	//原来栈顶的下一个成为新的栈顶
	pStack->pTop = pStack->pTop->pNext;

	free(pDel);
	pDel = NULL;

	pStack->nCount--;
	return nNum;
}

void UnRecPreTraversal(BinaryTree *pTree)
{
	if(pTree == NULL)return;

	//申请辅助栈
	Stack *pStack = NULL;
	s_Init(&pStack);

	while(1)
	{
		while(pTree)
		{
			//打印 
			printf("%d ",pTree->nValue);

			//入栈
			s_Push(pStack,pTree);

			//向左走
			pTree = pTree->pLeft;
		}
		
		//弹出
		pTree = s_Pop(pStack);

		//结束条件
		if(pTree == NULL)break;
		
		//向右走
		pTree = pTree->pRight;
	}
	
}

树的中序非递归遍历步骤:

                                     1.申请一个辅助栈

                                    2.循环遍历二叉树:如果二叉树结点非空,则结点入栈,二叉树向左走

                                    3. 栈顶元素弹出,后打印栈顶元素

                                     4.判断弹出得栈顶元素的右子树:如果右子树存在,则继续重复步骤2,3,4

                                                                                       如果右子树不存在,重复步骤2,3,4

                                     循环直到栈为空时结束

中序遍历就是把前序遍历的打印移到栈顶元素弹出后

代码如下:

//栈的基本操作
void s_Init(Stack **pStack)
{
	*pStack = (Stack *)malloc(sizeof(Stack));
	(*pStack)->pTop = NULL;
	(*pStack)->nCount = 0;
}

void s_Push(Stack *pStack,BinaryTree* nNum)
{
	if(pStack == NULL)
	{
		printf("stack is not exist.\n");
		return;
	}

	MyStack *pTemp = NULL;
	pTemp = (MyStack*)malloc(sizeof(MyStack));
	pTemp->nValue = nNum;
	
	//新来节点的下一个是原来的栈顶
	pTemp->pNext = pStack->pTop;

	//新来节点成为新的栈顶
	pStack->pTop = pTemp;
	
	//计数器
	pStack->nCount++;
}

BinaryTree* s_Pop(Stack *pStack)
{
	if(pStack == NULL || pStack->pTop == NULL)return NULL;

	MyStack *pDel = NULL;
	pDel = pStack->pTop;

	BinaryTree* nNum = NULL;
	nNum = pDel->nValue;

	//原来栈顶的下一个成为新的栈顶
	pStack->pTop = pStack->pTop->pNext;

	free(pDel);
	pDel = NULL;

	pStack->nCount--;
	return nNum;
}

void UnRecInTraversal(BinaryTree *pTree)
{
	if(pTree == NULL)return;

	//申请辅助栈
	Stack *pStack = NULL;
	s_Init(&pStack);

	while(1)
	{
		while(pTree)
		{

			//入栈
			s_Push(pStack,pTree);

			//向左走
			pTree = pTree->pLeft;
		}
		
		//弹出
		pTree = s_Pop(pStack);

		//结束条件
		if(pTree == NULL)break;
                //注意要在结束条件之后判断,如果在结束条件之前输出,如果pTree已经为空了,在Linux下就会出现段错误
		//打印 
		printf("%d ",pTree->nValue);
		
		//向右走
		pTree = pTree->pRight;
	}
	
}

树的后续遍历非递归步骤:

             1.申请一个辅助栈

              2.循环遍历树的结点,如果结点非空,结点入栈,树等于树的左孩子

              3.判断栈顶元素:

                                     栈顶元素有右子树,且右子树被标记过,或者无右子树,则弹出栈顶元素,并打印,标记

                                    栈顶元素有右子树,且没有被标记过,则重复2,3 步

循环直到栈为空时结束

代码如下:

栈的基本操作
void s_Init(Stack **pStack)
{
	*pStack = (Stack *)malloc(sizeof(Stack));
	(*pStack)->pTop = NULL;
	(*pStack)->nCount = 0;
}

void s_Push(Stack *pStack,BinaryTree* nNum)
{
	if(pStack == NULL)
	{
		printf("stack is not exist.\n");
		return;
	}

	MyStack *pTemp = NULL;
	pTemp = (MyStack*)malloc(sizeof(MyStack));
	pTemp->nValue = nNum;
	
	//新来节点的下一个是原来的栈顶
	pTemp->pNext = pStack->pTop;

	//新来节点成为新的栈顶
	pStack->pTop = pTemp;
	
	//计数器
	pStack->nCount++;
}

BinaryTree* s_Pop(Stack *pStack)
{
	if(pStack == NULL || pStack->pTop == NULL)return NULL;

	MyStack *pDel = NULL;
	pDel = pStack->pTop;

	BinaryTree* nNum = NULL;
	nNum = pDel->nValue;

	//原来栈顶的下一个成为新的栈顶
	pStack->pTop = pStack->pTop->pNext;

	free(pDel);
	pDel = NULL;

	pStack->nCount--;
	return nNum;
}

void UnRecLastTraversal(BinaryTree *pTree)
{
	if(pTree == NULL)return;

	//申请辅助栈
	Stack *pStack = NULL;
	s_Init(&pStack);
	BinaryTree *pMark = NULL;

	while(1)
	{
		while(pTree)
		{

			//入栈
			s_Push(pStack,pTree);

			//向左走
			pTree = pTree->pLeft;
		}
		
		if(pStack->pTop == NULL)break;

		//栈顶元素无右 或者有右且被标记过
		if(pStack->pTop->nValue->pRight == NULL || pStack->pTop->nValue->pRight == pMark)
		{
			//弹出 打印 标记
			pMark = s_Pop(pStack);
			
			printf("%d ",pMark->nValue);
		}

		//有右 且 未被标记
		else
		{
			pTree = pStack->pTop->nValue->pRight;
		}
	}
	
}

图解:


 

无奈没有详细的图解(*^▽^*)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值