二叉树递归遍历与非递归遍历

二叉树递归遍历与非递归遍历_第1张图片

  1. 递归前序遍历

二叉树的创建就是递归的思想,每个结点都可以看作一个树。前序遍历是根->左->右的顺序,先打印根结点,分别将根的左右结点递归打印

#include 
#include
typedef struct node
{

	int value;
	struct node *pLeft;
	struct node *pRight;

}BinaryTree;

void RPreTraversal(BinaryTree * br)
{
	if(br==NULL)
		return;
	printf("%d\n",br->value);
	RPreTraversal(br->pLeft);
	RPreTraversal(br->pRight);

}

2.非递归前序遍历

借助辅助栈来进行非递归的前序遍历

  • 结点非空,打印,入栈向左遍历(循环)
  • 弹出栈顶元素
  • 判断元素的的右结点,进入循环,执行第一步
//辅助栈
#include
#include 
#include
typedef struct node
{

	int value;
	struct node *pLeft;
	struct node *pRight;

}BinaryTree;
typedef struct Node
{
	BinaryTree* nValue;
	struct Node *pNext;
}Mystack;
typedef struct StackNode
{
	Mystack *pTop;
	int length;//栈元素长度
	bool flag;//栈标志
}StackInt;
void Myinit(StackInt**s)
{
	*s=(StackInt*)malloc(sizeof(StackInt));
	if(*s == NULL)
	{
		printf("create stack failed");
		return;
	}
	(*s)->pTop = NULL;
	(*s)->length =0;
	(*s)->flag =true;

}
void listpush(StackInt *s,BinaryTree *n)
{
	if(s->flag==false)
		return;
	Mystack*pTemp = NULL;
	pTemp = (Mystack*)malloc(sizeof(Mystack));
	pTemp->nValue =n;
	pTemp->pNext = s->pTop;
	s->pTop = pTemp;
	s->length++;

}
BinaryTree* listpop(StackInt *s)
{
	if(s->flag == false)
		return NULL;
	if(s->pTop == NULL)
		return NULL;
	else
	{
		BinaryTree* n;
		Mystack*pTemp =NULL;
		pTemp =s->pTop;
		n=(s->pTop)-> nValue;
		s->pTop=(s->pTop)->pNext;
		s->length--;
		free(pTemp);
		pTemp = NULL;
		return n;
	}
}
void ClearStack(StackInt *s)
{
	if(s->flag == false)
		return;
	while(s->pTop!=NULL)
	{
		listpop(s);

	}


}
void DestoryStack(StackInt **s)
{
	ClearStack(*s);
	(*s)->flag=false;
	free(*s);
	(*s) =NULL;
	printf("stack destorystack!");

}
BinaryTree* GetTop(StackInt *s)
{
	BinaryTree* n;
	if(s->pTop == NULL)
	{
		printf("Top is null");
		return NULL;

	}
	n=(s->pTop)->nValue;
	return n;
}
int Getcount(StackInt *s)
{

	if(s == NULL ||s->pTop == NULL)
	{
		printf("stack is null");
		return -1;

	}
	return (s->length);
}
int isEmpty(StackInt *s)
{
	if(s== NULL||s->pTop == NULL)
		return 1;
	else
	{
		return 0;
	}

}
void URPreTraversal(BinaryTree *tree)
{
	if(tree ==NULL)
		return;
	//申请栈
	StackInt *s = NULL;
	Myinit(&s);
	//节点非空,打印,入栈,
	while(1)
	{
		while (tree!=NULL)
		{
			printf("%d ",tree->value);
			listpush(s,tree);
			tree=tree->pLeft;
		}
		//弹出
		tree =listpop(s);
		//判断是否为空,当栈内元素为空时,结束循环
		if(tree == NULL)
			break;
		//向右遍历
		tree = tree->pRight;

	}


}

3.递归中序遍历

中序遍历的顺序是左->根->右

void RInorderTraversal(BinaryTree *br)
{
	if(br == NULL)
		return;
	RInorderTraversal(br->pLeft);
	printf("%d\n",br->value);
	RInorderTraversal(br->pRight);
}

4.非递归中序遍历

void URInorderTraversal(BinaryTree *tree)
{
	if(tree ==NULL)
		return;
	StackInt *s = NULL;
	Myinit(&s);
	while(1)
	{
		while(tree !=NULL)
		{
			listpush(s,tree);
			tree =tree->pLeft;

		}
		tree =listpop(s);
		if(tree== NULL)
			break;
		printf("%d ",tree->value);
		tree=tree->pRight;
	}
}

5.递归后序遍历

后序遍历的顺序是左->右->根

void RPostTraversal(BinaryTree *br)
{
	if(br == NULL)
		return;
	RPostTraversal(br->pLeft);
	RPostTraversal(br->pRight);
	printf("%d\n",br->value);
}

6.非递归后序遍历

‘非递归后序遍历不能直接弹出根节点,因为要通过根节点去找他的右结点,当根结点的右结点为空或者右结点为栈内刚刚上一次弹出的结点,就可以弹出根节点。

void URPostTraversal(BinaryTree *tree)
{
	if(tree==NULL)
		return;
	StackInt *s =NULL;
	Myinit(&s);
	BinaryTree *p = NULL;
	while(1)
	{
		while(tree !=NULL)
		{
			listpush(s,tree);
			tree=tree->pLeft;

		}
		if(s->pTop ==NULL)
			break;
		if(s->pTop->nValue->pRight==NULL||s->pTop->nValue->pRight==p)
		{
			p=listpop(s);
			printf("%d ",p->value);

		}
		else
			tree =s->pTop->nValue->pRight;
	}
}

 

你可能感兴趣的:(二叉树)