算法必会基本内容
1,递归实现
感觉一句话可以概括了。。先看前序遍历:
public void bianli(TreeNode root){
if(root==null)return;
System.out.println(root.val);
bianli(root.left);
bianli(root.right);
}
中序遍历和后序遍历就是依次改变System.out.println()那句话的位置,中序放中间,后序放后面。
2,非递归实现
主要使用栈或者队列实现,网上还有不用这两个辅助方式的Morris算法。。看到大神写过,有机会自己写一个试试,链接在这里Morris算法。
1)前序遍历
public void preorder(TreeNode root){
Stack<TreeNode> s=new Stack<>();
TreeNode p=root;
while(p!=null || !s.isEmpty()){
if(p!=null){
s.push(p);
System.out.println(p.val);
p=p.left;
}else{
p=s.pop().right;
}
}
}
2)中序遍历
public void inorder(TreeNode root){
Stack<TreeNode> s=new Stack<>();
TreeNode p=root;
while(p!=null || !s.isEmpty()){
if(p!=null){
s.push(p);
p=p.left;
}else{
p=s.pop();
System.out.println(p.val);
p=p.right;
}
}
}
3) 后序遍历有取巧的方式,可以用我这里是用了一个栈和双向链表实现,通过模拟一个中右左的前序遍历(倒序输出就是左右中),然后将遍历的节点反向存到双向链表中(每次存到0位置,正常的add操作是放到尾部):
public void postorder(TreeNode root){
Stack<TreeNode> s=new Stack<>();
List<Integer> res=new LinkedList<>();
TreeNode p=root;
while(p!=null || !s.isEmpty()){
if(p!=null){
s.push(p);
res.add(0,p.val);
p=p.right;
}else{
p=s.pop().left;
}
}
for(int i=0; i<res.size(); i++){
System.out.println(res.get(i));
}
}
再依次打印这个双向链表即可
4) 层次遍历
这里同样是用一个双向链表即可实现,把它当成一个队列使用,具体步骤是每次先计算当前队列中的元素个数,即为这一层的个数,然后遍历一个节点输出,再将他的子节点添加到这个队列中,每次经过一个节点,就会把这一层元素的个数减一,减到0说明这一层结束。在leetcode第102这道题里面就是当每层结束的时候,把List<>添加到List<List<>>中。具体代码如下:
public void LevelOrder(TreeNode root){
if(root==null) return null;
LinkedList<TreeNode> queue = new LinkedList<>();
TreeNode p = root;
queue.offer(p);
while(!queue.isEmpty()){
int count = queue.size();
while(count > 0){
p = queue.poll();
System.out.print(p.val);
if(p.left != null){
queue.offer(p.left);
}
if(p.right != null){
queue.offer(p.right);
}
count--;
}
System.out.println();
}
}
遍历属于比较基本的面试题目了,要达到可以非常熟练的手写出来并且知道每一步到底是在做什么这样的水平。