/* *寻找最近共同祖先结点 *方法1 : 从根开始,查找他的子树中是不是包含两个节点,分别向左右子树递归(层次遍历),知道某一节点找不到两颗子树中的一棵,那么 *其双亲结点就是最近共同祖先。 *方法2 : 首先预处理每个结点在树中的深度 下面是主要步骤 while( p所指结点 != q 所指结点 ) { if p所指结点较深 就将p指向它的父结点 if q所指结点较深 就将q指向它的父结点 if 深度相同 就同时指向各自的父结点 } 当循环退出时 p , q 所指结点就是最近公共祖先 ------------这个使用双亲表示法比较好,最好生成树的时候还能生成深度 */ #include <stdio.h> #include <stdlib.h> #define MAX_TREE_SIZE 128 typedef struct _TreeNode { char TNode; int parent; int other; // other 可以当深度,也可以当权重等等 }TreeNode; typedef struct _PTree { TreeNode PTNode[MAX_TREE_SIZE]; int r,n; // r为根的事情,n为结点的数目 }PTree; PTree* CreateTree(PTree* root, TreeNode newNode) { if (!root) { root = (PTree*)calloc(1,sizeof(PTree)); root->r = 0; root->n = 0; } root->PTNode[root->n] = newNode; ++root->n; return root; } int main(void) { PTree* ptree = NULL; TreeNode newNode; int p,q; printf("请建树:/n例如:/n结点/t层次/t双亲/n以'$/t-1/t-1'结束/n"); while (scanf("%c/t%d/t%d",&newNode.TNode,&newNode.other,&newNode.parent)) { fflush(stdin); if (newNode.TNode == '</p>) break; ptree = CreateTree(ptree , newNode); } printf("请输入两个结点的指针p,q:/n"); scanf("%d/t%d",&p,&q); while (p != q) { if (ptree->PTNode[p].other > ptree->PTNode[q].other) //p的深度>q的深度 p = ptree->PTNode[p].parent; // p指向其父节点 else if (ptree->PTNode[p].other < ptree->PTNode[q].other) q = ptree->PTNode[q].parent; else { p = ptree->PTNode[p].parent; q = ptree->PTNode[q].parent; } } printf("%d/n",p); return 0; }