问题要求:任意给出二叉树中的两个节点,求他们的最近祖先
分三种情况:
1、该二叉树是搜索二叉树
如果两个节点的值都大于根节点,则遍历右子树查找一个处于两节点之间的值为最近祖先,如果两个节点的值都小于根节点,则遍历左子树查找一个两节点之间的值为最近祖先
插入代码
Node* SearchNearAncestor(Node* root,Node* node1,Node*node2) { if (root==NULL|| node1==NULL|| node2==NULL) { return NULL; } if(node1==node2||node1->_parent!=NULL) { return node1; } Node* cur=root; while (cur) { if(cur->_key>node1->_key&& cur->_key>node2->_key) { cur=cur->_left; } else if(cur->_key<node1->_key&& cur->_key<node2->_key) { cur=cur->_right; } else { if(node1->_parent==node2) return node2->_parent; else if(node2->_parent==node1) return node1->_parent; else return cur; } } return NULL; }2、该二叉树为普通二叉树,但其有父节点,这时候,将node1的父节点和node2的parent->parent.......一直比较下去,直到二者相同,如果一直不同,则将node1再往上走,继续上步循环
查找代码为
Node* NearAncetor(Node* root,Node* node2) { if(node1==root||node2==root) { return root; } Node* tmp; while (node1!=NULL) { node1=node1->_parent; tmp=node2; while (tmp!=NULL) { if(node1==tmp->_parent) return node1; tmp=tmp->_parent; } } return NULL ; }
3、该二叉树为普通二叉树,他也没有父节点,这时候要分别递归左右子树,如果一个节点出现在左子树,另一个出现在右子树,则返回根节点,如果两个都出现在左,则最近祖先在子树,如果两个都出现在右,则最近祖先在右子树上
代码如下
Node* NearAncetor(Node* root,Node* node2) { if (root==NULL|| node1==NULL|| node2==NULL) { return NULL; } if(node1==root||node2==root) { return root; } Node* left=NearAncetor(root->_left,node1,node2); Node* right=NearAncetor(root->_right,node2); if(left&&right) return root; if(left==NULL) return right; else return left; }
二叉搜索树全部代码
#include<iostream> using namespace std; template<class K> struct SearchTreeNode { typedef SearchTreeNode<K> Node; Node* _left; Node* _right; Node* _parent; K _key; SearchTreeNode(const K& key) :_left(NULL),_right(NULL),_parent(NULL),_key(key) {} }; template<class K> class SearchTree { typedef SearchTreeNode<K> Node; public: SearchTree() :_root(NULL) {} ~SearchTree() { delete _root; } SearchTree(const SearchTree<K>& t) { _root=t._root; } Node* GetRoot() { return _root; } bool Find(const K& key) { if(_root==NULL) return false; Node* cur=_root; while (cur) { if(cur->_key>key) cur=cur->_left; else if(cur->_key<key) cur=cur->_right; else return true; } } bool Insert(const K&key) { _Insert(_root,key); return true; } void Inorder() { _Inorder(_root); cout<<endl; } Node* SearchNearAncestor(Node* root,Node*node2) { if (root==NULL|| node1==NULL|| node2==NULL) { return NULL; } if(node1==node2||node1->_parent!=NULL) { return node1; } Node* cur=root; while (cur) { if(cur->_key>node1->_key&& cur->_key>node2->_key) { cur=cur->_left; } else if(cur->_key<node1->_key&& cur->_key<node2->_key) { cur=cur->_right; } else { if(node1->_parent==node2) return node2->_parent; else if(node2->_parent==node1) return node1->_parent; else return cur; } } return NULL; } protected: bool _Insert(Node*& root,const K& key) { if(root==NULL) { root=new Node(key); return true; } if(root->_key>key) { return _Insert(root->_left,key); } else if(root->_key<key) { return _Insert(root->_right,key); } else return false; } void _Inorder(Node* root) { Node* cur=root; if(cur==NULL) return; _Inorder(cur->_left); cout<<cur->_key<<" "; _Inorder(cur->_right); } protected: Node* _root; }; //void testSearch() //{ // int arr[]={3,4,1,5,2,6,8,7,9}; // SearchTree<int> t; // // // for(int i=0;i<sizeof(arr)/sizeof(arr[0]);i++) // { // t.Insert(arr[i]); // } // t.Inorder(); // //} void test() { int arr[]={5,3,9}; SearchTree<int> t1; for(int i=0;i<sizeof(arr)/sizeof(arr[0]);i++) { t1.Insert(arr[i]); } t1.Inorder(); SearchTreeNode<int>* root=t1.GetRoot(); SearchTreeNode<int>* node1=root->_left->_right; SearchTreeNode<int>* node2=root->_right->_left; SearchTreeNode<int>* ancetor=t1.SearchNearAncestor(root,node2); cout<<node1->_key<<"和"<<node2->_key<<"的最近祖先是"<<ancetor->_key<<endl; SearchTreeNode<int>* node3=root->_right->_right->_right; SearchTreeNode<int>* node4=root->_right->_left; SearchTreeNode<int>* ancetor2=t1.SearchNearAncestor(root,node3,node4); cout<<node3->_key<<"和"<<node4->_key<<"的最近祖先是"<<ancetor2->_key<<endl; cout<<endl; }
这里查找4,6的最近祖先和9,6的最近祖先
结果
普通二叉树有父节点的全部代码
#include <iostream> using namespace std; struct TreeNode { TreeNode* _left; TreeNode* _right; TreeNode* _parent; int _key; TreeNode(const int& key) :_left(NULL),_key(key) {} }; class BinrayTree { typedef TreeNode Node; public: BinrayTree() :_root(NULL) {} ~BinrayTree() { delete _root; } Node* GetRoot() { return _root; } bool Insert2(const int& key) { _Insert(_root,key); return true; } void Inorder2() { _Inorder(_root); cout<<endl; } Node* NearAncetor(Node* root,Node* node2) { if(node1==root||node2==root) { return root; } Node* tmp; while (node1!=NULL) { node1=node1->_parent; tmp=node2; while (tmp!=NULL) { if(node1==tmp->_parent) return node1; tmp=tmp->_parent; } } return NULL ; } protected: bool _Insert(Node*& root,const int& key) { Node* node=new Node(key); node->_key=key; node->_left=node->_right=node->_parent=NULL; if(root==NULL) { root=node; return true; } if(root->_left == NULL && root->_key > key) { node->_parent=root; root->_left=node; return true; } if(root->_right == NULL && root->_key < key) { node->_parent=root; root->_right=node; return true; } if(root->_key > key) _Insert(root->_left,key); else if(root->_key < key) _Insert(root->_right,key); else return true; } void _Inorder(Node* root) { Node* cur=root; if(cur==NULL) return; _Inorder(cur->_left); cout<<cur->_key<<" "; _Inorder(cur->_right); } Node* _root; }; void test2() { int arr[]={5,9}; BinrayTree t1; for(int i=0;i<sizeof(arr)/sizeof(arr[0]);i++) { t1.Insert2(arr[i]); } t1.Inorder2(); TreeNode* root=t1.GetRoot(); TreeNode* node1=root->_left->_left; TreeNode* node2=root->_right->_right; cout<<node1->_key<<"和"<<node2->_key<<"的最近祖先是"; TreeNode* ancetor=t1.NearAncetor(root,node2); if(ancetor) cout<<ancetor->_key<<endl; cout<<endl; }
这里测试1,8的最近祖先
普通二叉树且无父节点全部代码
#include <iostream> using namespace std; struct NoParentTreeNode { NoParentTreeNode* _left; NoParentTreeNode* _right; int _key; NoParentTreeNode(const int& key) :_left(NULL),_key(key) {} }; class NoParentBinrayTree { typedef NoParentTreeNode Node; public: NoParentBinrayTree() :_root(NULL) {} ~NoParentBinrayTree() { delete _root; } Node* GetRoot() { return _root; } bool Insert2(const int& key) { _Insert(_root,node2); if(left&&right) return root; if(left==NULL) return right; else return left; } protected: bool _Insert(Node*& root,const int& key) { if(root==NULL) { root=new Node(key); return true; } if(key>root->_key) { return _Insert(root->_right,key); } else if(key<root->_key) { return _Insert(root->_left,key); } else return false; } void _Inorder(Node* root) { Node* cur=root; if(cur==NULL) return; _Inorder(cur->_left); cout<<cur->_key<<" "; _Inorder(cur->_right); } Node* _root; }; void test3() { int arr[]={5,9}; NoParentBinrayTree t1; for(int i=0;i<sizeof(arr)/sizeof(arr[0]);i++) { t1.Insert2(arr[i]); } t1.Inorder2(); NoParentTreeNode* root=t1.GetRoot(); NoParentTreeNode* node1=root->_left->_left; NoParentTreeNode* node2=root->_right->_right->_right; NoParentTreeNode* ancetor=t1.NearAncetor(root,node2); cout<<node1->_key<<"和"<<node2->_key<<"的最近祖先是"<<ancetor->_key<<endl; cout<<endl; }
这里测试1,9的最近祖先
测试代码
#include "SearchTree.h" #include "HaveParentUnsearchTree.h" #include "NoParentSearchTree.h" #include <cstdlib> int main() { test(); test2(); test3(); system("pause"); return 0; }原文链接:https://www.f2er.com/datastructure/382393.html