树是一种在实际编程中经常遇到的数据结构,它的逻辑很简单,除根节点之外每个节点只有一个父节点,根节点没有父节点:除叶节点之外,所有的节点都有一个或者多个子节点,叶节点没有子节点。父节点和子节点用指针相连接。由于树的操作会涉及大量的指针,因此与树有关的面试都不太容易。当面试官想考查应聘者在有复杂指针操作的情况下写代码时,他往往会想到用于树有关的面试题。
面试的时候提到的树,大部分是二叉树。所谓二叉树是树的一种特殊结构,在二叉树中的每个节点最多只能有两个子节点。在二叉树中的额最重要的操作莫过于遍历,即按照某一个顺序访问树中的所有节点。通常树有三种遍历方式
前序遍历
先访问根节点,在访问左子节点,最后访问右子节点
中序遍历
先访问左子节点,再访问根节点,最后访问右子节点
后序遍历
先访问左子节点,在访问右子节点,最后访问根节点。
这三种遍历都有递归和循环两种不同的实现方法,每种遍历的递归实现都比循环实现要简单的多。
二叉树有很多特例,二叉搜索树就是其中之一。在二叉搜索树中左子节点总是小于或者等于根节点,而右子节点总是大于或者等于根节点。我们可以平均在logn的时间内根据数值在二叉搜索树中找到一个及诶点
二叉树的另外另个特例是堆和红黑树。堆分为最大堆和最小堆。在最大堆中根节点的值最大,在最小堆中根节点的值最小。
红黑树就是把树中的节点定义为红、黑两种颜色。并通过规则确保从根节点到叶节点的最长路径长度不超过最短路径的两倍。
面试题7 重建二叉树
package question7_build_tree;
/**
* @Classname Solution1
* @Description TODO
* @Date 2020/3/7 20:44
* @Created by mmz
*/
public class Solution1 {
public static class TreeNode{
int val;
TreeNode left;
TreeNode right;
TreeNode(int val){
this.val = val ;
}
@Override
public String toString() {
return "TreeNode{" +
"val=" + val +
", left=" + left +
", right=" + right +
'}';
}
}
public static TreeNode reConstructBinary(int[] pre,int[] mid){
if(pre.length <0 || mid.length < 0){
return null;
}
return ConstructBinaryTree(pre,0,pre.length-1,mid,0,mid.length-1);
}
public static TreeNode ConstructBinaryTree(int[] pre,int ps,int pe,int[] mid, int ms,int me){
if(ps >pe || ms >me){
return null;
}
TreeNode root = new TreeNode(pre[ps]);
for(int i = ms;i<=me;++i){
if(pre[ps] == mid[i]){
root.left = ConstructBinaryTree(pre,ps+1,ps+i-ms,mid,ms,i-1);
root.right = ConstructBinaryTree(pre,ps+i+1-ms,pe,mid,i+1,me);
break;
}
}
return root;
}
public static void main(String[] args) {
int[] pre =new int[]{1,2,4,7,3,5,6,8};
int[] mid = new int[]{4,7,2,1,5,3,8,6};
System.out.println(reConstructBinary(pre, mid));
}
}
面试8 二叉树的下一个节点
分析:如果一个节点有右子树,那么它的下一个节点就是它右子树中的最左子节点。
如果没有右子树,并且该节点是父节点的左子树节点,那么下一个节点就是父节点
如果既没有右子树,也不是左子树节点,那么就可能是根节点,或者是父节点的右子树节点
package question8_find_next_node;
import java.util.HashMap;
/**
* @Classname Solution
* @Description TODO
* @Date 2020/3/7 21:28
* @Created by mmz
*/
public class Solution {
public static class TreeNode{
String val ;
TreeNode left;
TreeNode right;
TreeNode parent;
TreeNode(TreeNode left,TreeNode right,String val){
this.left = left;
this.right = right;
this.parent = null;
this.val = val;
}
}
public static TreeNode findNextNode(TreeNode treeNode){
if(treeNode == null){
return null;
}
if(treeNode.right!=null){
treeNode = treeNode.right;
while(treeNode.left!= null){
treeNode = treeNode.left;
}
return treeNode;
}else if (treeNode.parent != null && treeNode.parent.left ==treeNode) {
return treeNode.parent;
}else if(treeNode.parent == null){
return treeNode;
}else if(treeNode.parent.parent.right == treeNode.parent || treeNode.parent!= null|| treeNode.parent.parent != null){
while(treeNode.parent.parent.right == treeNode.parent|| treeNode.parent!= null|| treeNode.parent.parent != null){
treeNode = treeNode.parent;
if(treeNode.parent.parent.left == treeNode.parent){
return treeNode.parent.parent;
}
}
}else{
return null;
}
return null;
}
public static void main(String[] args) {
TreeNode f = new TreeNode(null,null,"f");
TreeNode g = new TreeNode(null,null,"g");
TreeNode h = new TreeNode(null,null,"h");
TreeNode i = new TreeNode(null,null,"i");
TreeNode d = new TreeNode(null,null,"d");
TreeNode e =new TreeNode(h,i,"e");
TreeNode b= new TreeNode(d,e,"b");
TreeNode c = new TreeNode(f,g,"c");
TreeNode a = new TreeNode(b,c,"a");
h.parent = e;
i.parent = e;
d.parent =b;
e.parent= b;
f.parent =c;
g.parent= c;
b.parent = a;
c.parent = a;
System.out.println(findNextNode(e).val);
}
}
改良版
package question8_find_next_node;
import java.util.HashMap;
/**
* @Classname Solution
* @Description TODO
* @Date 2020/3/7 21:28
* @Created by mmz
*/
public class Solution {
public static class TreeNode{
String val ;
TreeNode left;
TreeNode right;
TreeNode parent;
TreeNode(TreeNode left,TreeNode right,String val){
this.left = left;
this.right = right;
this.parent = null;
this.val = val;
}
@Override
public String toString() {
return "TreeNode{" +
"val='" + val + '\'' +
'}';
}
}
public static TreeNode findNextNode(TreeNode treeNode){
if(treeNode == null){
return null;
}
if(treeNode.right!=null){
treeNode = treeNode.right;
while(treeNode.left!= null){
treeNode = treeNode.left;
}
return treeNode;
}
while(treeNode.parent!= null){
TreeNode root = treeNode.parent;
if(root.left == treeNode){
return root;
}
treeNode = root;
}
return null;
}
public static void main(String[] args) {
TreeNode f = new TreeNode(null,null,"f");
TreeNode g = new TreeNode(null,null,"g");
TreeNode h = new TreeNode(null,null,"h");
TreeNode i = new TreeNode(null,null,"i");
TreeNode d = new TreeNode(null,null,"d");
TreeNode e =new TreeNode(h,i,"e");
TreeNode b= new TreeNode(d,e,"b");
TreeNode c = new TreeNode(f,g,"c");
TreeNode a = new TreeNode(b,c,"a");
h.parent = e;
i.parent = e;
d.parent =b;
e.parent= b;
f.parent =c;
g.parent= c;
b.parent = a;
c.parent = a;
System.out.println(findNextNode(i));
}
}