chriszeng87 发表于 2013-1-26 13:33:24

编程之美3.8 求二叉树节点的最大距离

如果我们把二叉树看成一个图,父子节点之间的连线看成是双向的,我们姑且定义“距离”为两个节点之间边的个数。写一个程序求一棵二叉树相距最远的两个节点之间的距离。
 
分析: 对任意一个节点,以该节点为根,假设这个根有k个孩子节点,那么相距最远的两个节点U和V之间的路径与这个根节点的关系有两种情况。
 1.若路径经过根Root,则U和V是属于不同的子树的,且它们都是该子树中到根节点最远的节点,否则跟它们的距离最远相矛盾。
2.若路径不经过Root,那它们一定同属于根的左子树或右子树,并且它们也是该子树中相距最远的两个顶点。
 
因此,问题就可以转化为在子树上的解,从而能够利用动态规划来解决。上代码:
 
 
#include <stdio.h>#include <stdlib.h>struct NODE{NODE* pLeft;NODE* pRight;int nMaxLeft; //左子树中的最大深度int nMaxRight; //右子树中的最大深度char chValue; //该节点的值};int nMaxLen = 0;void FindMaxLen(NODE*pRoot) {if(pRoot == NULL) {return;}if(pRoot->pLeft == NULL) {pRoot->nMaxLeft = 0;}else {FindMaxLen(pRoot->pLeft);int nTempMax = 0;if(pRoot->pLeft->nMaxLeft > pRoot->pLeft->nMaxRight) {nTempMax = pRoot->pLeft->nMaxLeft;}else {nTempMax = pRoot->pLeft->nMaxRight;}            //加上到根节点的距离pRoot->nMaxLeft = nTempMax + 1; }if(pRoot->pRight == NULL) {pRoot->nMaxRight = 0;}else {FindMaxLen(pRoot->pRight);int nTempMax = 0;if(pRoot->pRight->nMaxLeft > pRoot->pRight->nMaxRight) {nTempMax = pRoot->pRight->nMaxLeft;}else {nTempMax = pRoot->pRight->nMaxRight;}pRoot->nMaxRight = nTempMax + 1; //加上到根节点的距离}if(pRoot->nMaxLeft + pRoot->nMaxRight > nMaxLen) //最长距离经过rootnMaxLen = pRoot->nMaxLeft + pRoot->nMaxRight;}void createBinaryTree(NODE** pRoot) { //建二叉树char c;scanf("%c",&c);if(c == '#') {(*pRoot) = NULL;}else {(*pRoot) = (struct NODE*) malloc(sizeof(struct NODE));(*pRoot)->chValue = c;createBinaryTree(&((*pRoot)->pLeft));createBinaryTree(&((*pRoot)->pRight));}}void printBinaryTree(NODE* pRoot) { //打印二叉树if(pRoot == NULL)return;printf("%c",pRoot->chValue);printBinaryTree(pRoot->pLeft);printBinaryTree(pRoot->pRight);}int main() {struct NODE* root = NULL;createBinaryTree(&root);printBinaryTree(root);FindMaxLen(root);printf("\nThe max length is: %d\n",nMaxLen);return 0;}  
页: [1]
查看完整版本: 编程之美3.8 求二叉树节点的最大距离