ODOA(2) 求二叉树中两个节点的最大距离(C语言实现)

问题描述;

如果我们把二叉树看成一个图,父子节点之间的连线看成是双向的,我们姑且定义"距离"为两节点之间边的个数。写一个程序求一棵二叉树中相距最远的两个节点之间的距离。


算法很容易想得到:

 

  • 如果根节点的左子树或右子树为空,那么最大距离即为树的深度
  • 否则,最大距离等于左子树的深度+右子树的深度
虽然这个问题很简单,但是在实现的时候,还树出了点问题,导致卡了两天才实现。
原因:
1 树的基本操作的实现不熟练
2 对递归的使用不熟悉
3 在递归建树的时候,输入序列一直没搞清楚。。

经验:
1 遇到树,首先想到的是递归处理
2 使用递归,一定要有一个终止条件
3 强类型语言真心不方便,比如节点值设置为整形,那么读入的一定要是整形(强制类型转换除外),导致必须要用一个数字(我用的0)表示空节点(即递归的终止条件)。
4 巩固了树的基本算法,是在这个问题上的最大的收获,只有真正实现它了,才能从更深的层次掌握它。

代码如下:
依然只是很简单的实现,并没有过多的异常处理。

/* 
  Name: main.c 
  Author: suzhou 
  Date:   2014.02.18
  Num.    2
 */  


#include "btree.h"

int main()
{
	BTree mytree = NULL;
	int choice;
	
	while (1) {
		printf("\n请选择您想要进行的操作:\n");
		printf("  [ 1 ] 先序次序建立二叉树\n");
		printf("  [ 2 ] 先序打印二叉树节点\n");
		printf("  [ 3 ] 求树的深度\n");
		printf("  [ 4 ] 求树中相距最远的两个节点的距离\n");
		printf("  [ 0 ] 退出\n");

		scanf("%d", &choice);

		switch(choice)
		{
		case 0:
			printf("%s\n", "谢谢使用");
			exit(0);
		case 1:
			printf("%s",
				   "请以先序遍历次序输入各个节点的数值:\n");
			createBTree(&mytree);
			continue;
		case 2:
			preOrderVisit(mytree);
			continue;
		case 3:
			printf("树的深度为: %d\n",
				   depth(mytree));
			continue;
		case 4:
			printf("最大距离为: %d\n",
				   maxDistance(mytree)
				);
			continue;
		default:
			printf("%s\n",
				   "请输入正确的选择");
			continue;
		}
	}
	
	printf("Congratulations! It works!\n");
	return 0;
}


/* 
  Name: btree.h
  Author: suzhou 
  Date:   2014.02.18
  Num.    2
 */  




#ifndef BTREE
#define BTREE

#include "stdio.h"
#include "stdlib.h"

typedef struct BTNode
{
	int val;
	struct BTNode* pLeft;
	struct BTNode* pRight;
}BTNode, *BTree;


/*
  建立二叉树
 */
void createBTree (
	BTree* tree
	);

/*
  先序遍历二叉树
 */
void preOrderVisit (
	BTree tree
	);

/*
  按树状打印节点
 */
void printTree (
	BTree tree,
	int depth
	);


/*
 * 求树的深度
 */
int depth(
	BTree tree
	);

/*
 * 求树的两个节点的最远距离
 */
int maxDistance(
	BTree tree
	);

#endif


/* 
  Name: btree.c 
  Author: suzhou 
  Date:   2014.02.18
  Num.    2
 */  



#include "btree.h"


/*
  建立二叉树
 */
void createBTree (
	BTree* tree
	)
{
	int val;
	
	scanf("%d", &val);

	if ( val == 0 )
	{
		*tree = NULL;
	}
	else
	{
		*tree = (BTNode*) malloc (sizeof(BTNode));
		(*tree)->val = val;
		createBTree(&((*tree)->pLeft));
		createBTree(&((*tree)->pRight));
	}
}


/*
  先序遍历二叉树
 */
void preOrderVisit (
	BTree tree
	)
{
	if ( tree != NULL )
	{
		printf("%d\n", tree->val);
		preOrderVisit(tree->pLeft);
		preOrderVisit(tree->pRight);
	}
}


/*
  按树状打印节点
 */
void printTree (
	BTree tree,
	int depth
	)
{
	int i;
	
	if ( tree == NULL )
		return;
	for ( i=depth; i>=0; i-- )
		printf("%c", ' ');
	printf("%d\n" , tree->val);

	printTree(tree->pLeft, depth+1);
	printTree(tree->pRight, depth+1);
	
}


/*
 * 求树的深度
 */
int depth(
	BTree tree
	)
{
	if (tree == NULL)
		return 0;
	else
		return 1 + 
			(depth(tree->pLeft) >= depth(tree->pRight)
			? depth(tree->pLeft) : depth(tree->pRight));
}


/*
 * 求树的两个节点的最远距离
 */
int maxDistance(
	BTree tree
	)
{
	if (tree->pLeft == NULL
		|| tree->pRight == NULL)
		return depth(tree);
	else
		return depth(tree->pLeft) + depth(tree->pRight);
}


运行截图:



 

 

posted @ 2014-02-18 23:54  suzhou  阅读(470)  评论(0编辑  收藏  举报