剑指offer中 与树、二叉树有关的编程练习题 Java编码

(1)二叉树镜像

两字:递归
这里写图片描述
代码为


    public  static void main(String[] arg) {
        Node a = new Node('A');
        a.left=new Node('B');
        a.rigth=new Node('C');
        a.left.left=new Node('D');
        a.left.rigth=new Node('E');
        a.rigth.left=new Node('F');
        a.rigth.rigth=new Node('G');
        System.out.print("原二叉树为");
        levelRecur.levelRecur(a);
        Mirror(a);
        System.out.print("\n"+"二叉树镜像为");
        levelRecur.levelRecur(a);
    }

    private static void Mirror(Node a) {
        if(a==null) {
            return ;
        }
        if(a.left!=null||a.rigth!=null) {
            Node temp=a.left;
            a.left=a.rigth;
            a.rigth=temp;
        }
        if(a.left!=null) {
            Mirror(a.left);
        }
        if(a.rigth!=null) {
            Mirror(a.rigth);
        }

    }

这里写图片描述

(2)树的子结构

这里写图片描述


     public  static void main(String[] arg) {
            Node a = new Node('A');
            a.left=new Node('B');
            a.rigth=new Node('C');
            a.left.left=new Node('D');
            a.left.rigth=new Node('E');
            a.rigth.left=new Node('F');
            a.rigth.rigth=new Node('G');
            Node b = new Node('C');
            b.left=new Node('F');
            b.rigth=new Node('G');
            System.out.print("是否为子结构");
            boolean result=HasSubtree(a,b);
            System.out.print(result);
        }

    private static boolean HasSubtree(Node root1, Node root2) {
        boolean result=false;
        if(root1!=null&&root2!=null) {
            if(root1.val==root2.val) {
                result=isSubTree(root1,root2);
            }
            if(!result) {
                result=isSubTree(root1.left,root2);
                result=isSubTree(root1.rigth,root2);
            }
        }

        return result;
    }

    private static boolean isSubTree(Node root1, Node root2) {
        if(root2==null) {
            return true;
        }
        if(root1==null&&root2!=null) {
            return false;
        }
        if(root1.val!=root2.val) {
            return false;
        }
        return isSubTree(root1.left,root2.left)&&isSubTree(root1.rigth,root2.rigth);
    }

这里写图片描述

(3)从上往下打印二叉树

四字:层序遍历
这里写图片描述


     public  static void main(String[] arg) {
            Node a = new Node('A');
            a.left=new Node('B');
            a.rigth=new Node('C');
            a.left.left=new Node('D');
            a.left.rigth=new Node('E');
            a.rigth.left=new Node('F');
            a.rigth.rigth=new Node('G');
            System.out.print("从上往下打印二叉树节点为:");
            PrintFromTopToBottom(a);
        }

    private static void PrintFromTopToBottom(Node a) {
        if(a==null) {
            return ;
        }
        Queue<Node> queue=new LinkedList<Node>();
        queue.offer(a);
        while(!queue.isEmpty()) {
            Node nd=queue.poll();
            System.out.print(nd.val+" ");
            if(nd.left!=null) {
                queue.offer(nd.left);
            }
            if(nd.rigth!=null) {
                queue.offer(nd.rigth);
            }
        }
    }

这里写图片描述

(4)二叉搜索树的后序遍历序列

题目描述

输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出true,否则输出false。假设输入的数组的任意两个数字都互不相同。
思路:二叉树后序遍历的特点、递归


     public  static void main(String[] arg) {
         int a[] = { 51, 46, 20, 18, 65, 97, 82, 30, 77, 50 };
            System.out.println("是否为二叉搜索树的后序遍历:");
            System.out.print(VerifySquenceOfBST(a));;
        }

    private static boolean VerifySquenceOfBST(int[] a) {
        if(a==null||a.length==0) {
            return false;
        }
        return vsofBST(a,0,a.length-1);
    }

    private static boolean vsofBST(int[] a, int start, int end) {
        int count=end;
        while(count>0&&a[count]>=a[end]) {
            count--;
        }
        for(int i=start;i<count;i++) {
            if(a[i]>a[count]) {
                return false;
            }
        }
        return vsofBST(a,start,count)&&vsofBST(a,count+1,end-1);
    }

这里写图片描述

(5)二叉树的深度

题目描述
输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度
思路:层次遍历思想、递归写法为后序遍历


    public static void main(String[] arg) {
        Node a = new Node('A');
        a.left=new Node('B');
        a.rigth=new Node('C');
        a.left.left=new Node('D');
        a.left.rigth=new Node('E');
        a.rigth.left=new Node('F');
        a.rigth.rigth=new Node('G');
        System.out.println("递归求树的高度为:");
        int heigth=TreeDepth(a);
        System.out.print(heigth);
        System.out.println("\n"+"非递归求树的高度为:");
        int heigths=TreeDepths(a);
        System.out.print(heigths);
    }

    private static int TreeDepths(Node a) {
        if(a==null) {
            return 0;
        }
        int count=0,nextcount=1,depth=0;
        Queue<Node> queue=new LinkedList<Node>();
        queue.offer(a);
        while(!queue.isEmpty()) {
            Node nd=queue.poll();
            count++;
            if(nd.left!=null) {
                queue.offer(nd.left);
            }
            if(nd.rigth!=null) {
                queue.offer(nd.rigth);
            }
            if(count==nextcount) {
                depth++;
                count=0;
                nextcount=queue.size();
            }
        }
        return depth;
    }

    private static int TreeDepth(Node a) {
        if(a==null) {
            return 0;
        }
        int left=TreeDepth(a.left);
        int rigth=TreeDepth(a.rigth);
        return Math.max(left,rigth)+1;
    }

这里写图片描述

(6)平衡二叉树

题目描述

输入一棵二叉树,判断该二叉树是否是平衡二叉树。
思路:后序遍历

public class Solution {
   public boolean IsBalanced_Solution(TreeNode root) {
        if (root == null)
            return true;

        if (Math.abs(getHeight(root.left) - getHeight(root.right)) > 1)
            return false;


        return IsBalanced_Solution(root.left) && IsBalanced_Solution(root.right);

    }

    public int getHeight(TreeNode root) {
        if (root == null)
            return 0;
        return max(getHeight(root.left), getHeight(root.right)) + 1;
    }

    private int max(int a, int b) {
        return (a > b) ? a : b;
    }
}

(7)二叉树的下一个结点

题目描述

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


    public static void main(String[] arg) {
        Node a = new Node('A');
        a.left=new Node('B');
        a.rigth=new Node('C');
        a.left.left=new Node('D');
        a.left.rigth=new Node('E');
        a.rigth.left=new Node('F');
        a.rigth.rigth=new Node('G');
        System.out.println("二叉树的下一个结点:");
        System.out.print(GetNext(a).val);
    }
    public static Node GetNext(Node pNode)
    {
        if(pNode==null){
            return  null;
        }
        if(pNode.rigth!=null){
            pNode=pNode.rigth;
            while(pNode!=null&&pNode.left!=null){
                pNode=pNode.left;
            }
            return pNode;
        }
        while(pNode.next!=null){
            if(pNode==pNode.next.left){
                return pNode.next;
            }else{
                pNode=pNode.next;
            }
        }
        return null;
    }

这里写图片描述

(8)对称的二叉树

题目描述
请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。
思路:递归判断左右子树是否相同


    public  static void main(String[] arg) {
        Node a = new Node('A');
        a.left=new Node('B');
        a.rigth=new Node('C');
        a.left.left=new Node('D');
        a.left.rigth=new Node('E');
        a.rigth.left=new Node('F');
        a.rigth.rigth=new Node('G');
        System.out.println("是否为对称二叉树:");
        System.out.print(isSymmetrical(a));
    }

    private static boolean isSymmetrical(Node a) {
        if(a==null) {
            return false;
        }
        return isSymmet(a.left,a.rigth);
    }

    private static boolean isSymmet(Node left, Node rigth) {
        if(left==null&&rigth==null) {
            return true;
        }
        return left.val==rigth.val&&isSymmet(left.left, rigth.rigth)&&isSymmet(left.rigth, rigth.left);
    }

这里写图片描述

(8)按之字形顺序打印二叉树

题目描述

请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。
思路:层序非递归遍历思想


    public  static void main(String[] arg) {
        Node a = new Node('A');
        a.left=new Node('B');
        a.rigth=new Node('C');
        a.left.left=new Node('D');
        a.left.rigth=new Node('E');
        a.rigth.left=new Node('F');
        a.rigth.rigth=new Node('G');
        System.out.println("二叉树按之字形打印节点:");
        Print(a);
        for(int i=0;i<Print(a).size();i++) {
            System.out.print(Print(a).get(i)+" ");
        }
    }

    private static ArrayList<ArrayList<Integer>> Print(Node a) {
        if(a==null) {
            return null;
        }
        ArrayList<ArrayList<Integer>> listall=new ArrayList<ArrayList<Integer>>();
        ArrayList<Integer> list=new ArrayList<Integer>();
        Queue<Node> queue=new LinkedList<>();
        queue.offer(a);
        int start=0,end=1;
        boolean lefttoright=true;
        while(!queue.isEmpty()) {
            Node nd=queue.poll();
            list.add(nd.val);
            start++;
            if(nd.left!=null) {
                queue.offer(nd.left);
            }
            if(nd.rigth!=null) {
                queue.offer(nd.rigth);
            }
            if(start==end) {
                start=0;
                end=queue.size();
                if(lefttoright) {
                    listall.add(list);
                }else {
                    listall.add(revesor(list));
                }
                lefttoright=!lefttoright;
                list=new ArrayList<Integer>();
            }

        }
        return listall;

    }

    private static ArrayList<Integer> revesor(ArrayList<Integer> list) {
        if(list==null||list.size()==0) {
            return null;
        }
        ArrayList<Integer> revesorlist=new ArrayList<Integer>();
        for(int i=list.size()-1;i>=0;i--) {
            revesorlist.add(list.get(i));
        }
        return revesorlist;
    }

这里写图片描述

(9)二叉搜索树的第k个结点

题目描述

给定一颗二叉搜索树,请找出其中的第k大的结点。例如, 5 / \ 3 7 /\ /\ 2 4 6 8 中,按结点数值大小顺序第三个结点的值为4。
思路:中序非递归排序


    public  static void main(String[] arg) {
        Node a = new Node(5);
        a.left=new Node(3);
        a.rigth=new Node(7);
        a.left.left=new Node(2);
        a.left.rigth=new Node(4);
        a.rigth.left=new Node(6);
        a.rigth.rigth=new Node(8);
        System.out.println("二叉树第k大节点为:");
        KthNode(a,4);
    }

    private static void KthNode(Node a, int i) {
        if(a==null||i<1) {
            return ;
        }
        Stack<Node> stack=new Stack<Node>();
        ArrayList<Integer> list=new ArrayList<Integer>();
        while(!stack.isEmpty()||a!=null) {
            if(a!=null) {
                stack.push(a);
                a=a.left;
            }else {
                Node nd=stack.pop();
                list.add(nd.val);
                a=nd.rigth;
            }
        }
        System.out.print(list.get(i-1));
    }

这里写图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值