求二叉树中节点的最大距离算法(C)

来源:互联网 发布:1.12魔兽世界数据库 编辑:程序博客网 时间:2024/05/22 08:18

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

书中对这个问题的分析是很清楚的,我尝试用自己的方式简短覆述。

计算一个二叉树的最大距离有两个情况:

  • 情况A: 路径经过左子树的最深节点,通过根节点,再到右子树的最深节点。
  • 情况B: 路径不穿过根节点,而是左子树或右子树的最大距离路径,取其大者。

只需要计算这两个情况的路径距离,并取其大者,就是该二叉树的最大距离。

我也想不到更好的分析方法。本文文字分析转载至博客“http://www.cnblogs.com/miloyip/archive/2010/02/25/1673114.html”,其中这篇博客中的一些评论是很有用的,比如说求二叉树中节点的最大距离问题其实就是求树的直径问题,又可以通过求树的直径方法来找到别的一些参考资料,在本文中主要利用两种方法实现了文中要求,具体代码如下:

#include "string.h"#include "stdio.h"    #include "stdlib.h"   #include "io.h"  #include "math.h"  #include "time.h"#define OK 1#define ERROR 0#define TRUE 1#define FALSE 0#define MAXSIZE 100 /* 存储空间初始分配量 */typedef int Status;/* Status是函数的类型,其值是函数结果状态代码,如OK等 *//* 用于构造二叉树********************************** */int index=1;typedef char String[24]; /*  0号单元存放串的长度 */String str;int MaxLen=0;int MaxLen1=0;Status StrAssign(String T,char *chars){ int i;if(strlen(chars)>MAXSIZE)return ERROR;else{T[0]=strlen(chars);for(i=1;i<=T[0];i++)T[i]=*(chars+i-1);return OK;}}/* ************************************************ */typedef char TElemType;TElemType Nil=' '; /* 字符型以空格符为空 */Status visit(TElemType e){printf("%c ",e);return OK;}typedef struct BiTNode  /* 结点结构 */{   TElemType data;/* 结点数据 */   struct BiTNode *lchild,*rchild; /* 左右孩子指针 */   int Maxleft;   int Maxright;}BiTNode,*BiTree;/* 构造空二叉树T */Status InitBiTree(BiTree *T){ *T=NULL;return OK;}/* 按前序输入二叉树中结点的值(一个字符) *//* #表示空树,构造二叉链表表示二叉树T。 */void CreateBiTree(BiTree *T){ TElemType ch;/* scanf("%c",&ch); */ch=str[index++];if(ch=='#') *T=NULL;else{*T=(BiTree)malloc(sizeof(BiTNode));if(!*T)exit(OVERFLOW);(*T)->data=ch; /* 生成根结点 */CreateBiTree(&(*T)->lchild); /* 构造左子树 */CreateBiTree(&(*T)->rchild); /* 构造右子树 */} }/* 初始条件: 二叉树T存在 *//* 操作结果: 若T为空二叉树,则返回TRUE,否则FALSE */Status BiTreeEmpty(BiTree T){ if(T)return FALSE;elsereturn TRUE;}#define ClearBiTree DestroyBiTree/* 初始条件: 二叉树T存在。操作结果: 返回T的深度 */int BiTreeDepth(BiTree T){int i,j;if(!T)return 0;if(T->lchild)i=BiTreeDepth(T->lchild);elsei=0;if(T->rchild)j=BiTreeDepth(T->rchild);elsej=0;return i>j?i+1:j+1;}//寻找树中最长的两段距离int FindMaxLen(BiTree pRoot){int nTempMax=0;//遍历到叶子节点返回if (pRoot==NULL)return 0;//如果左子树为空,那么该节点的左边最长距离为0if (pRoot->lchild==NULL)pRoot->Maxleft=0;//如果右子树为空,那么该节点的右边最长距离为0;if (pRoot->rchild==NULL)pRoot->Maxright=0;//如果左子树不为空,递归寻找左子树最长距离if (pRoot->lchild!=NULL) FindMaxLen(pRoot->lchild);//如果右子树不为空,递归寻找右子树最长距离if (pRoot->rchild!=NULL) FindMaxLen(pRoot->rchild);//计算左子树最长节点距离if (pRoot->lchild!=NULL){nTempMax=0;if (pRoot->lchild->Maxleft > pRoot->lchild->Maxright)nTempMax=pRoot->lchild->Maxleft;elsenTempMax=pRoot->lchild->Maxright;pRoot->Maxleft=nTempMax+1;}//计算右子树最长节点距离if (pRoot->rchild!=NULL){nTempMax=0;if (pRoot->rchild->Maxleft > pRoot->rchild->Maxright)nTempMax=pRoot->rchild->Maxleft;elsenTempMax=pRoot->rchild->Maxright;pRoot->Maxright=nTempMax+1;}//更新最长距离if (pRoot->Maxleft+pRoot->Maxright>MaxLen){MaxLen=pRoot->Maxleft+pRoot->Maxright;}return MaxLen;}int FindMaxLen1(BiTree pRoot){if (pRoot==NULL)return 0;if (pRoot->lchild==NULL)pRoot->Maxleft=0;if (pRoot->rchild==NULL)pRoot->Maxright=0;if (pRoot->lchild!=NULL) FindMaxLen1(pRoot->lchild);if (pRoot->rchild!=NULL) FindMaxLen1(pRoot->rchild);if (pRoot->lchild!=NULL)pRoot->Maxleft=BiTreeDepth(pRoot->lchild); //利用计算子树深度的方法计算if (pRoot->rchild!=NULL)pRoot->Maxright=BiTreeDepth(pRoot->rchild);if (pRoot->Maxleft+pRoot->Maxright>MaxLen1){MaxLen1=pRoot->Maxleft+pRoot->Maxright;}return MaxLen1;}int main(){BiTree T;int Max,Max1;InitBiTree(&T);StrAssign(str,"ABDH#KW####EF#G#M###C##");CreateBiTree(&T);Max=FindMaxLen(T);printf("二叉树中节点的最大距离为1:");printf("%d \n",MaxLen);Max1=FindMaxLen1(T);printf("二叉树中节点的最大距离为2:");printf("%d \n",MaxLen1);system("pause");return 0;}



原创粉丝点击