typedef struct Node{ struct Node *lchild; char data; struct Node *rchild; }BTNode;
//求二叉搜索树的公共祖先 1.二叉搜索树具有一个很好的特点。以当前结点为根节点的左边结点的值都是小于根节点的值,右边结点的值都大于根节点的值。 2.根据这个特点,如果给的两个节点的值都小于根节点,那么它们的最低公共祖先就一定在它左子树。 3.如果给的两个节点的值都大于根节点,那么它们的最低公共祖先就一定在它右子树。 4.如果一个结点的值大于根节点的值,一个结点的值小于根节点的值,那么这个根节点就是它的最低公共祖先。 BTNode* getLowestCommonParent(BTNode* root, BTNode* node1, BTNode* node2) { if (root == NULL || node1 == NULL || node2 == NULL) return NULL; if ((node1->data < root->data) && (node2->data< root->data)) { return getLowestCommenParent(root->lchild, node1, node2); }else if ((node1->data > root->data) && (node2->data > root->data)){ return getLowestCommenParent_R(root->rchild, node1, node2); }else{ return root; } }
//求普通二叉树的最低公共祖先 二叉树问题一般都可以用递归去解决,要想通过递归实现,就需要先确定临界条件。那么什么是临界条件呢?换句话说,临界条件就是递归中能够直接返回的特殊情况。 (1)第一点则是最常见的“判空”,判断根结点是否是空节点,如果是,那么肯定就可以马上返回了; (2)再来考虑题意,在以root为根结点的树中找到p结点和q结点的最近公共祖先,那么特殊情况是什么呢?很显然,特殊情况就是根结点就等于q结点或p结点的情况,想一下,如果根结点为二者之一,那么根结点就必定是最近公共祖先了,这时直接返回root即可。 由此看来,这道题共有三种特殊情况即root == q 、root == p以及root==null,均直接返回root即可。 根据临界条件,此题已经被简化为查找以root为根结点的树上是否有p结点或者q结点,如果有就返回p结点或q结点,否则返回null。 这样一来就很简单了,从左右子树分别进行递归,即查找左右子树上是否有p结点或者q结点,就一共有4种情况: 第一种:左右子树均没有找到p或者q结点;(虽然题上说p和q结点必定都存在,但递归的时候必须考虑所有情况,因为题目是针对整棵树,而递归会到局部,局部不一定都满足整体条件) 第二种:左子树上能找到,但右子树上找不到,此时就应当直接返回左子树的查找结果; 第三种:右子树上能找到,但左子树上找不到,此时就应当直接返回右子树的查找结果; 第四种:左右子树上均能找到,说明此时的p和q结点分居root两侧,此时就应当直接返回root结点了。 BTNode* getLowestCommonParent(BTNode* root, BTNode* node1, BTNode* node2) { if (root == NULL || node1 == root || node2 == root) return root; BTNode* left =getLowestCommonParent(root->lchild, node1,node2); BTNode* right = getLowestCommonParent(root->rchild, node1,node2); if(left==NULL && right==NULL){ return NULL; } else if(left!=NULL && right==NULL){ return left; } else if(right!=NULL&&left==NULL){ return right; } else{ return root; } }
二叉树任意两节点之间的最短路径长度 1.求出两个节点的最近公共祖先lowestCommonRoot 2.利用深度搜索(先序)分别求出node1和node2到root的路径 3.对两个路径长度求和即得所求 bool getPath(BTNode* root,BTNode* target,Queue<TreeNode*> queue){ if (root==target){ return true; } in(queue,root); bool found=false; if (root->lchild!=NULL) found=getPath(root->lchild,target,queue); if (!found && root->rchild!=NULL) found=getPath(root->rchild,target,queue); if (!found) reverseOut(queue); return found; } BTNode* lowestCommonRoot = getLowestCommonParent(root,node1,node2); getPath(lowestCommonRoot,node1,queue1); getPath(lowestCommonRoot,node2,queue2); queue1->length+queue2->length