二叉树
wiki上二叉树的介绍
二叉树的详细介绍
参阅:http://yameing.blog.163.com/blog/static/1120259402010088233927/
概念:二叉树就是每个结点最多有两个子树的树形存储结构。
满二叉树:在一棵二叉树中,所有分支结点都存在左子树和右子树,并且所有叶子都在同一层上。
完全二叉树:完全二叉树是每个结点都与深度为k的满二叉树中编号从1到n一一对应。
二叉树的表示方式
- 顺序(用数组存储),简单但浪费空间
- 链式
二叉树的实现
二叉搜索树
1 | //main.c |
二叉树的遍历
非递归实现1
Morris遍历
http://www.cnblogs.com/dolphin0520/archive/2011/08/25/2153720.html
递归
1 | //递归的方法 |
中序遍历的非递归方法
中序遍历,非递归的方法
对于任一结点P,
1)若其不为空,则将P入栈并将P的左孩子置为当前的P,然后对当前结点P再进行相同的处理;
2)若其为空,则取栈顶元素并进行出栈操作,访问该栈顶结点,然后将当前的P置为栈顶结点的右孩子;
3)直到P为NULL并且栈为空则遍历结束。
1 | //非递归的方法,中序遍历 |
前序遍历的非递归方法
1 | //非递归前序遍历 |
后续遍历的非递归方法
因为后序遍历的顺序是:左子树->右子树->根节点,于是我们在前序遍历的代码中,当访问完当前节点后,先把当前节点的左子树入栈,再把右子树入栈,这样最终得到的顺序为:根节点->右子树->左子树,刚好是后序遍历倒过来的版本,于是把这个结果做一次翻转即为真正的后序遍历。而翻转可以通过使用另外一个栈简单完成,这样的代价是需要两个栈,但就复杂度而言,空间复杂度仍然是O(h)
1 | vector<int> postorderTraversal(tnode *r) { |
二叉树的相关问题
LCA,最低公共祖先
给定一棵树,同时给出树中的两个结点(n1和n2),求它们的最低公共祖先。也就是常见的LCA(Lowest Common Ancestor )问题。
解法一:
(1)找到从根节点到n1的路径,
(2)找到从根节点到n2的路径;
(3)找出两条路径中第一个不相同的点,则它的父节点即是所求。
1 |
|
解法2:递归的方法
(1)从一个根节点r开始找,如果r中的val是其中的一个,那么r就是所求的节点
(2)否则的话,遍历r->left和r->right,如果在r->left中找到两个节点,就返回
1 | tnode *findLCA(tnode *r, int num1, int num2) |
二叉树中两个节点的距离
公式计算
Dist(n1, n2) = Dist(root, n1) + Dist(root, n2) - 2*Dist(root, LCA)
二叉树的面试题
http://www.acmerblog.com/?s=%E4%BA%8C%E5%8F%89%E6%A0%91