刷题找工作第11篇

剑指offer<树篇>

二叉树的下一个节点
题目描述
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。

重点思路:假设这棵树只有3个节点

在这里插入图片描述
在这里插入图片描述准确的说:应该是:

有三种情况:
1.如果当前结点有右子树,那么下一个结点就是右子树的最左结点。
2.如果当前结点没有右子树,但是是它父结点的左子结点,那么下一个结点就是他的父结点。
3.如果当前结点既没有右子树,并且还是它父结点的右子结点:
那么沿着指向父结点的指针一直向上遍历,直到找到一个是它父结点的左子结点的结点。
如果这样的结点存在,那么这个结点的父结点就是我们要找的下一个结点。

/*
public class TreeLinkNode {
    int val;
    TreeLinkNode left = null;
    TreeLinkNode right = null;
    TreeLinkNode next = null;

    TreeLinkNode(int val) {
        this.val = val;
    }
}
*/
public class Solution {
    public TreeLinkNode GetNext(TreeLinkNode pNode)
    {
        if(pNode==null) return pNode;
        //如果是左节点,并且没有子节点,返回 父节点
        //当前为左节点
        if(pNode.right==null&&pNode.next!=null&&pNode.next.left==pNode) return pNode.next;
        
        //当前为右节点
        if(pNode.right==null) return father(pNode);
        //当前是中节点节点,返回遍历右子树的左节点
        if(pNode.right!=null) return left(pNode.right);
        
        return null;
        
    }
    
    
    private TreeLinkNode left(TreeLinkNode root)
    {
        if(root==null) return root;
        if(root.left!=null)
        {
            root = root.left;
        }
        return root;
    }
    

    /*
    是其父节点的左节点
    
    
    */
    private TreeLinkNode father(TreeLinkNode root)
    {
        if(root==null) return root;
        
        while(root.next!=null)
        {
            if(root.next.left==root)
            {
                break;
            }
            root = root.next;
        }
        return root.next;
    }
    
}




第二题:
对称的二叉树

题目描述
请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的

/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
public class Solution {
    boolean isSymmetrical(TreeNode pRoot)
    {
        if(pRoot==null) return true;
        return isEqual(pRoot.left,pRoot.right);
    }
    
    
    
    
    boolean isEqual(TreeNode left,TreeNode right)
    {
        if(left==null&&right==null) return true;
        if(left==null||right==null) return false;
        if(left.val != right.val) return false;
        return isEqual(left.right,right.left)&&isEqual(left.left,right.right);
    }
    
    
    
    
    
    
    
    
}

第3题:
之字打印二叉树

题目描述
请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。

import java.util.*;
/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/

public class Solution {
    public ArrayList<ArrayList<Integer> > Print(TreeNode root) {
        ArrayList<ArrayList<Integer>> ans = new ArrayList();
        if(root==null) return ans;
    
        LinkedList<TreeNode> q = new LinkedList();
        q.offer(root);
        
        boolean right = true;
        
        while(q.size()>0)
        {
            ArrayList<Integer> cur = new ArrayList(q.size());
            int size = q.size();
            Iterator<TreeNode> iter = null;
            if(right)
            {
                iter = q.iterator();
                while(iter.hasNext())
                {
                    cur.add(iter.next().val);
                }
            }else{
                iter = q.descendingIterator();
                while(iter.hasNext())
                {
                    cur.add(iter.next().val);
                }
            }
            ans.add(cur);
            right = !right;
            
            while(--size>=0)
            {
                TreeNode top = q.poll();
                if(top.left!=null) q.offer(top.left);
                if(top.right!=null) q.offer(top.right);
            }
        }
        return ans;    
    }

}

还有一种是用 null作为分隔符的,也是不错,这里直接用 size记录层数即可
不要忘记迭代器的使用,用惯foreach循环,偶尔也要用用迭代器

第4题:同理
层序遍历二叉树
题目描述
从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。

import java.util.ArrayList;
import java.util.LinkedList;


/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
public class Solution {
    ArrayList<ArrayList<Integer> > Print(TreeNode root) {
        ArrayList<ArrayList<Integer> > ans = new ArrayList();
        if(root==null) return ans;
        
        LinkedList<TreeNode> q = new LinkedList();
        q.offer(root);
        while(q.size()>0)
        {
            ArrayList<Integer> cur = new ArrayList();
            int size = q.size();
            
            while(--size>=0)
            {
                TreeNode top = q.poll();
                cur.add(top.val);
                if(top.left!=null) q.offer(top.left);
                if(top.right!=null) q.offer(top.right);
            }
            
            ans.add(cur);
            
            
        }
        return ans;
        
        
        
    }
    
}






第5题: LeetCode有一样的题哦
序列化二叉树

题目描述
请实现两个函数,分别用来序列化和反序列化二叉树

二叉树的序列化是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过 某种符号表示空节点(#),以 ! 表示一个结点值的结束(value!)。

二叉树的反序列化是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。

import java.lang.StringBuilder;
import java.util.*;
/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
public class Solution {
    
    String Serialize(TreeNode root) {
        StringBuffer sb = new StringBuffer();
        dfs(sb,root);
        return sb.toString();
        
        
   }
 
    private int curIndex = -1;
   TreeNode Deserialize(String str) {
       String[] values = str.split(",");
        
        return preOrder(values);
   }
    public TreeNode preOrder(String[] values)
    {
        this.curIndex++;
        String value = values[curIndex];
        if(value.equals("#"))
         {
            return null;
        }
        TreeNode head = new TreeNode(Integer.valueOf(value));
        head.left = preOrder(values);
        head.right = preOrder(values);
        return head;
    }
    
    public void dfs(StringBuffer sb,TreeNode root)
    {
        if(root==null)
        {
            sb.append("#,");
            return;
        }
        sb.append(root.val+",");
        dfs(sb,root.left);
        dfs(sb,root.right);

    }
    
    
}
    
   








注意 为什么要将 curIndex 设置为成员变量? 因为二叉树的遍历,这个指针是一路向后不回头的,没办法用局部变量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值