遍历二叉树——非线性数据 到 线性数据

遍历二叉树,有6种可能,主要是根、左子树、右子树的先后排序。其中三种是先右后左,不符合人类习惯,排除这种方式,只采取从左到右的排序。因此,剩下的三种排序方式是常见的:

1.先序遍历——“先”访问根节点,然后到左子树,最后右子树。

2.中序遍历——先遍历左子树,“中”访问根,后遍历右子树。

3.后序遍历——先遍历左,再遍历右,“后”访问根节点。

可见,先、中、后描述的是根节点被访问的位置,而左和右的关系已经确定是先左后右的,因此,很容易记忆这三种遍历顺序。


http://write.blog.csdn.net/postedit/21389195

上一篇给出了构建二叉树的代码,如上图,构建的是非线性数据结构,遍历后得到的结果是:

先序:e,a,c,b,d,f,h,g

中序:a,b,c,d,e,f,g,h

后序:b,d,c,a,g,h,f,e

可见,遍历过程是“非线性数据结构”到“线性数据结构”的转变,遍历后的得到线性数据结构。

这三种遍历方法可以用递归过程实现.在上一篇基础上增加三个函数,其中中序、后序都是基于先序的小改。下面程序运行通过,留意三个遍历函数

pre_order_travel()

post_order_travel()

middle_order_travel()

只是打印tree字符,很简单的递归函数。

#include<stdio.h>
#include<stdlib.h>
struct _tree_node
{
  char data;
  struct _tree_node *lchild;
  struct _tree_node *rchild;
};

typedef struct _tree_node tree_node;

//init the binary tree's node
void tree_init(tree_node **node)
{
	*node = (tree_node *)malloc(sizeof(tree_node));
	(*node)->lchild = (*node)->rchild = NULL;
	(*node)->data = 0;
}

//node:root node
//data:node value
void construct(char data, tree_node **node)
{
	int i=0;
	tree_node *temp_node = *node;
	while(temp_node)
	{

		if(!temp_node->data)
		{
	//this situation only happen the first time,when the root is NULL
			temp_node->data=data;
			break;
		}
		else if(data <= temp_node->data)
		{
			//if lchild is NULL,then init it
			if(!temp_node->lchild)
			{
				tree_init(&temp_node->lchild);
				temp_node->lchild->data = data;
				break;    //for while loop
			}
			else  //if lchild not NULL,continue to compare it
			{
				temp_node = temp_node->lchild;
				continue; //for while loop
			}
		}
		else if(data>temp_node->data)
		{
			if(!temp_node->rchild)
			{
				tree_init(&temp_node->rchild);
				temp_node->rchild->data = data;
				break;
			}
			else
			{
				temp_node = temp_node->rchild;
				continue;  //for while loop
			}
		}
	}

	return;
}

int pre_order_travel(tree_node *node)
{
  if(!node)
  {
    return 1;
  }

  printf("%c ",node->data);
  pre_order_travel(node->lchild);
  pre_order_travel(node->rchild);
	
}

int post_order_travel(tree_node *node)
{
  if(!node)
  {
    return 1;
  }

  post_order_travel(node->lchild);
  post_order_travel(node->rchild);
  printf("%c ",node->data);
	
}
int middle_order_travel(tree_node *node)
{
  if(!node)
  {
    return 1;
  }

  middle_order_travel(node->lchild);
  printf("%c ",node->data);
  middle_order_travel(node->rchild);
	
}
int main()
{
	int i;
	tree_node *root;
	char data[8]={'e','f','h','g','a','c','b','d'};
	tree_init(&root);
	
	for(i=0;i<8;i++)
	{
		construct(data[i],&root);
	}
	printf("construct finished!\n");

	printf("pre_order travel begin\n");
	pre_order_travel(root);
	printf("\n");
	post_order_travel(root);
	printf("\n");
	middle_order_travel(root);
	printf("\n");
	return 0;

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值