C语言求连续20个点,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);

}

运行截图:

c2549173b805f8f94a6b3774108b3d30.png

f571c6736b3e21202f99868eb799e986.png

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值