构建二叉树(据后序遍历序列)---后续遍历二叉树(递归与非递归)

#include <stdio.h>
#include <stdlib.h> 

#define A 4

//二叉树后序遍历序列
//-1表示空节点,-100表示遍历的开始标记
int buffer[16]={-100,-1,-1,4,-1,-1,8,6,-1,-1,12,-1,-1,16,14,10};

//二叉树结构体
typedef struct binary_tree_node
{
	int data;
	struct binary_tree_node* ltree;
	struct binary_tree_node* rtree;
}Btnode;

//创建新节点
Btnode* create_node(void)
{
	Btnode* node;
	node=(Btnode*)malloc(sizeof(Btnode));
	return node;
}

//据后序序列创建二叉树
/*
	基本思想:

	将后序遍历序列逆序来读,就变成‘根右左’的顺序,则此时构建的方法

	与先序的构建方法相同

	明确问题:

	(1)何时进行二叉树分支的切换

		①右分支遍历到叶子节点时

		②左分支有新的节点加入时

	(2)何时节点入栈

		新加入的非空节点

	(3)何时节点出栈

		某分支遍历到叶子节点时
*/
Btnode* create_tree(int* buf)
{
	Btnode* root;
	Btnode* pnode,*temp;
	Btnode* s[A];
	bool ltree=false;
	int index=15;
	int m=0;
	
	root=create_node();
	root->data=buf[index--];
	s[m++]=root;
	pnode=root;

	while(buf[index]!=-100)
	{
		if(ltree==true)
		{
			if(buf[index]==-1)
			{
				pnode->ltree=NULL;
				index--;				
				pnode=s[--m];
			}
			else
			{
				temp=create_node();
				temp->data=buf[index--];
				pnode->ltree=temp;
				s[m++]=temp;
				pnode=temp;
				ltree=false;
			}
		}
		else
		{
			if(buf[index]==-1)
			{
				pnode->rtree=NULL;
				index--;
				pnode=s[--m];
				ltree=true;
			}
			else
			{
				temp=create_node();
				temp->data=buf[index--];
				pnode->rtree=temp;
				s[m++]=temp;
				pnode=temp;
			}
		}
	}

	return root;
}

//递归方法后序遍历
void postorder_traversal(Btnode* pnode)
{
	if(pnode!=NULL)
	{
		postorder_traversal(pnode->ltree);
		postorder_traversal(pnode->rtree);
		printf("%d ",pnode->data);
	}
	else
	{
		return;
	}	
	return;
}


//非递归法后序遍历
/*
	基本思想:
	
	即保证按“左右根”的顺序输出节点内容,建立结构体

	struct information,结构体中的标志flag用于标示入

	栈节点的右子树是否处理完毕。根节点的显示原则是右
	
	子树处理完毕(flag==0),而整体上的输出顺序由循
	
	环结构和flag标志控制。

	明确问题:

	(1)分支切换的条件
	
	  ①左子树为空

	  ②右子树不为空

	(2)节点入栈条件

		左子树不为空或者右子树不为空

	(3)出栈显示条件

		当处理右分支,右子树节点为空时

	(4)修改标志条件

	  ①左子树为空时,修改栈顶节点标志位

	  ②右子树为空且出栈结束时,修改栈顶节点标志位
 */
typedef struct information
{
	Btnode* node;
	int flag;
}N_INF;

void postorder_traversal1(Btnode* root)
{
	N_INF s[A];
	Btnode* pnode;
	int m=0;
	bool ltree=true;

	pnode=root;
	s[m].node=pnode;
	s[m++].flag=1;

	while(pnode!=NULL)
	{
		if(ltree==true)
		{
			if(pnode->ltree!=NULL)
			{
				pnode=pnode->ltree;
				s[m].node=pnode;
				s[m++].flag=1;
			}
			else
			{
				s[m-1].flag=0;
				ltree=false;
			}
		}
		else
		{
			if(pnode->rtree!=NULL)
			{
				pnode=pnode->rtree;
				s[m].node=pnode;
				s[m++].flag=1;
				ltree=true;
			}
			else
			{
				while(s[m-1].flag==0)
				{
					pnode=s[--m].node;
					printf("%d ",pnode->data);			
				}
				pnode=s[m-1].node;
				s[m-1].flag=0;
			}
		}
	}

}

int main(void)
{
	Btnode* root;
	root=create_tree(buffer);

	printf("Recursive postorder traversal result is:\n");
	postorder_traversal(root);
	printf("\n\n");
	printf("Non-Recursive postorder traversal result is:\n");
	postorder_traversal1(root);
	printf("\n\n");
	system("pause");
	return 0;
}
构建二叉树(据后序遍历序列)---后续遍历二叉树(递归与非递归)_第1张图片

你可能感兴趣的:(递归,二叉树,非递归,后序遍历,后序遍历序列)