二叉树作为树的一种,是一种重要的数据结构,也是面试官经常考的东西。昨天看了一下关于树中的面试题,发现二叉树中的面试题比较常见的题型大概有下面几个:创建一颗二叉树(先序,中序,后序)、遍历一颗二叉树(先序,中序,后序和层次遍历)、求二叉树中叶子节点的个数、求二叉树的高度、求二叉树中两个节点的最近公共祖先、打印和为某一值的全部路径、求某一节点是否在一个树中等等。
再详细的说这些面试题之前,不妨先看一下几种常见的二叉树:
完全二叉树:若二叉树的高度是h,除第h层之外,其他(1~h-1)层的节点数都达到了最大个数,并且第h层的节点都连续的集中在最左边。想到点什么没?实际上,完全二叉树和堆联系比较紧密哈~~~
满二叉树:除最后一层外,每一层上的所有节点都有两个子节点,最后一层都是叶子节点。
哈夫曼树:又称为最有数,这是一种带权路径长度最短的树。哈夫曼编码就是哈夫曼树的应用。
平衡二叉树:所谓平衡二叉树指的是,左右两个子树的高度差的绝对值不超过 1。
红黑树:红黑树是每个节点都带颜色的树,节点颜色或是红色或是黑色,红黑树是一种查找树。红黑树有一个重要的性质,从根节点到叶子节点的最长的路径不多于最短的路径的长度的两倍。对于红黑树,插入,删除,查找的复杂度都是O(log N)。
1. 二叉树最近公共父节点
原文地址:
http://blog.csdn.net/wcyoot/article/details/6427179
找寻二叉树中两个节点的公共父节点中最近的那个节点
情况1. 节点只有left/right,没有parent指针,root已知
解析:对于此种情形,只需找到两个节点到根节点的路径,然后就相当于两个链表中找公共节点。
1 template<typename T> 2 struct TreeNode1 3 { 4 T data; 5 TreeNode1* pLChild; 6 TreeNode1* pRChild; 7 }; 8 9 #include <vector> 10 11 // 找寻节点路径,倒序,根节点在最后 12 template<typename T> 13 bool FindNodePath(TreeNode1<T>* pRoot, TreeNode1<T>* p, std::vector<TreeNode1<T>*>& path) 14 { 15 if(pRoot == NULL) 16 return false; 17 if(p == pRoot) 18 { 19 path.push_back(pRoot); 20 return true 21 } 22 else if(FindNodePath(pRoot->pLChild, p, path)) 23 { 24 path.push_back(pRoot->pLChild); 25 return true; 26 } 27 else if(FindNodePath(pRoot->pRChild, p, path)) 28 { 29 path.push_back(pRoot->pRChild); 30 return true; 31 } 32 return false; 33 } 34 template<typename T> 35 TreeNode1<T>* FindNearestParentNode(TreeNode1<T>* pRoot, TreeNode1<T>* p1, TreeNode1<T>* p2) 36 { 37 std::vector<TreeNode1<T>*> path1, path2; 38 bool bFind = FindNodePath(pRoot, p1, path1); 39 bFind &= FindNodePath(pRoot, p2, path2); 40 if(!bFind) 41 return NULL; 42 43 TreeNode1<T>* pReturn = NULL; 44 size_t minSize = path1.size() > path2.size() ? path2.size() : path1.size(); 45 46 // 起始点设在可能出现共同节点的部分的起点 47 for(size_t i = path1.size() - minSize, j = path2.size()-minSize; i < path1.size() && j < path2.size(); ++i, ++j) 48 { 49 if(path1[i] == path2[j]) 50 { 51 pReturn = path1[i]; 52 } 53 } 54 55 return pReturn; 56 }