【C++从入门到入土】第一篇:从C到C++

可能永远不会有 Python 4.0

  返回  

二叉树进阶面试题

2021/8/21 19:42:39 浏览:

1. 二叉树的构建及遍历。

2. 二叉树的分层遍历 。

3. 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先 。

4. 二叉树搜索树转换成排序双向链表。

5. 根据一棵树的前序遍历与中序遍历构造二叉树。

6. 根据一棵树的中序遍历与后序遍历构造二叉树

7. 二叉树创建字符串。

package tree;

import sun.font.CreatedFontTracker;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

class TreeNode {
    public char val;
    public TreeNode left;
    public TreeNode right;

    public TreeNode(char val) {
        this.val = val;
    }
}

public class OfferAdvanceTree {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()) {
            String str = scanner.nextLine();
            TreeNode root = build(str);
            inOrder(root);
            System.out.println();
        }
        System.out.println("下面是build1:");
        TreeNode t = build1();
        inOrder(t);
        System.out.println("--------");
        Solution s = new Solution();
        System.out.println(s.levelOrder(t).toString());
    }

    public static int index = 0;

    public static TreeNode build(String str) {
        index = 0;

        return creatTreePrevOrede(str);
    }

    private static TreeNode creatTreePrevOrede(String str) {
        char c = str.charAt(index);
        if (c == '#') {
            return null;
        }
        TreeNode treeNode = new TreeNode(c);
        index++;
        treeNode.left = creatTreePrevOrede(str);
        index++;
        treeNode.right = creatTreePrevOrede(str);
        return treeNode;
    }

    public static void inOrder(TreeNode root) {
        if (root == null) {
            return;
        }
        inOrder(root.left);
        System.out.print(root.val);
        inOrder(root.right);
    }
    //给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。


    public static TreeNode build1() {
        TreeNode a = new TreeNode('A');
        TreeNode b = new TreeNode('B');
        TreeNode c = new TreeNode('C');
        TreeNode d = new TreeNode('D');
        TreeNode e = new TreeNode('E');
        TreeNode f = new TreeNode('F');
        TreeNode g = new TreeNode('G');
        a.left = b;
        a.right = null;
        b.left = c;
        b.right = d;
        d.left = e;
        d.right = f;
        e.right = g;
        return a;
    }
}

class Solution {
    public List<List<Character>> levelOrder(TreeNode root) {
        if (root == null) {
            return lists;
        }
        int lever = 0;
        return heper(root, 0);
    }

    public List<List<Character>> lists = new ArrayList<>();

    public List<List<Character>> heper(TreeNode root, int lever) {

        if (lever == lists.size()) {
            lists.add(new ArrayList<>());
        }
        lists.get(lever).add(root.val);
        if (root.left != null) {
            heper(root.left, lever + 1);
        }
        if (root.right != null) {
            heper(root.right, lever + 1);
        }
        return lists;
    }

    @Override
    public String toString() {
        return "{" +
                lists +
                '}';
    }
}

/*
* 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,
* 满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
*/
class Solution1 {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null) {
            return null;
        }
        heper(root, p, q);
        return lca;
    }

    private TreeNode lca = null;

    public boolean heper(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null) {
            return false;
        }
        int left = heper(root.left, p, q) ? 1 : 0;
        int right = heper(root.right, p, q) ? 1 : 0;
        int mid = (root == p || root == q) ? 1 : 0;
        if (mid + left + right == 2) {
            lca = root;
        }

        return (mid + left + right) > 0;
    }

    //方法二

    public TreeNode contains(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null) {
            return null;
        }
        heper2(root, p, q);
        return lca2;
    }

    private TreeNode lca2 = null;
    public int index = 0;

    private int heper2(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null) {
            return 0;
        }

        int left = heper2(root.left, p, q);
        if (root.left == q || root.left == p) {
            index++;
        }
        int right = heper2(root.right, p, q);
        if (root.right == q || root.right == p) {
            index++;
        }
        if (root == q || root == p) {
            index++;
        }
        if (index == 2) {
            lca2 = root;
            return 2;
        }
        return index;


    }

    /*
1.要求不能创建任何新的结点,只能调整树中结点指针的指向。当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继
2.返回链表中的第一个节点的指针
3.函数返回的TreeNode,有左右指针,其实可以看成一个双向链表的数据结构
4.你不用输出或者处理,示例中输出里面的英文,比如"From left to right are:"这样的,程序会根据你的返回值自动打印输出
*/
    public TreeNode Convert(TreeNode pRootOfTree) {
        if (pRootOfTree == null) {
            return null;
        }
        return heper3(pRootOfTree);
    }

    private TreeNode heper3(TreeNode pRootOfTree) {
        if (pRootOfTree == null) {
            return null;
        }
        if (pRootOfTree.left == null && pRootOfTree.right == null) {
            return pRootOfTree; 
        }

        TreeNode left = heper3(pRootOfTree.left);
        TreeNode leftTail = left;
        while (leftTail != null && leftTail.right != null) {
            leftTail = leftTail.right;
        }
        if (left != null) {
            leftTail.right = left;
            left.left = leftTail;
        }
        TreeNode right = heper3(pRootOfTree.right);
        if (right != null) {
            pRootOfTree.right = right;
            right.left = pRootOfTree;
        }
        if (left != null) {
            return left;
        }
        return pRootOfTree;
    }

    /*你需要采用前序遍历的方式,将一个二叉树转换成一个由括号和整数组成的字符串。

空节点则用一对空括号 "()" 表示。而且你需要省略所有不影响字符串与原始二叉树之间的一对一映射关系的空括号对。
*/
    public String tree2str(TreeNode root) {
        if (root == null) {
            return "";
        }
        heper4(root);
        sb.deleteCharAt(0);
        sb.deleteCharAt(sb.length() - 1);
        return sb.toString();
    }

    private StringBuilder sb = new StringBuilder();

    public void heper4(TreeNode root) {
        if (root == null) {
            return;
        }
        sb.append("(");
        sb.append(root.val);
        heper4(root.left);
        if (root.left == null && root.right != null) {
            sb.append("()");
        }
        heper4(root.right);
        sb.append(")");
    }

    /*给定一棵树的前序遍历 preorder 与中序遍历  inorder。请构造二叉树并返回其根节点。
     */
    //public int index;
    public TreeNode buildTree(char[] preorder, char[] inorder) {
        index = 0;
        return buildTreeHeper(preorder, inorder, 0, inorder.length);
    }

    private TreeNode buildTreeHeper(char[] preorder, char[] inorder, int left, int right) {
        if (left >= right) {
            return null;
        }
        if (index >=inorder.length) {
            return null;
        }
        TreeNode root = new TreeNode(preorder[index]);
        index++;
        char tofind = root.val;
        int pos=find(inorder, left, right, tofind);
        root.left=buildTreeHeper(preorder,inorder,left,pos);
        root.right=buildTreeHeper(preorder,inorder,pos+1,right);
        return root;
    }

    private int find(char[] inorder, int left, int right, char tofind) {
        for (int i = left; i <right ; i++) {
            if(inorder[i]==tofind){
                return i;
            }
        }
        return -1;
    }

}



前中后序的非递归实现:

1.前序遍历 void preOrderTraversal(Node root);

2.中序遍历 void inOrderTraversal(Node root);

3. 后序遍历 void postOrderTraversal(Node root);

package tree;

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;

class TreeNode1 {
    public int val;
    public TreeNode1 left;
    public TreeNode1 right;

    public TreeNode1(int val) {
        this.val = val;
    }
}

public class OfferAdvanceTree2 {
    public static void main(String[] args) {
        TreeNode1 t = buildTree();
        preOrder(t);
        System.out.println();
        inOrder(t);
        System.out.println();

        postOrderTraversal(t);
    }

    //非递归完成二叉树前序遍历
    //需要一个辅助栈
    public static void preOrder(TreeNode1 root) {
        Stack<TreeNode1> s = new Stack<>();
        if (root == null) {
            return;
        }
        s.push(root);
        while (!s.isEmpty()) {
            TreeNode1 t = s.pop();
            System.out.print(t.val);
            if (t.right != null) {
                s.push(t.right);
            }
            if (t.left != null) {
                s.push(t.left);
            }
        }
    }

    //非递归完成二叉树中序遍历
    //需要一个辅助栈
    public static void inOrder(TreeNode1 root) {
        if (root == null) {
            return;
        }
        Stack<TreeNode1> s = new Stack<>();
        TreeNode1 cur = root;
        while (true) {
            while (cur != null) {
                s.push(cur);
                cur = cur.left;
            }
            if (s.isEmpty()) {
                break;
            }
            TreeNode1 tmp = s.pop();
            System.out.print(tmp.val);

            cur = tmp.right;
        }
    }

    //非递归完成二叉树后序遍历
    //需要一个辅助栈
    public static void postOrderTraversal(TreeNode1 root) {
        if (root == null) {
            return;
        }
        Stack<TreeNode1> s = new Stack<>();

        TreeNode1 tmp = root;
        TreeNode1 prv = null;

        while (true) {
            while (tmp != null) {
                s.push(tmp);
                tmp = tmp.left;
            }
            if (s.isEmpty()) {
                break;
            }
            TreeNode1 top = s.peek();
            if (top.right == null || top.right.val == prv.val) {
                System.out.print(top.val);
                s.pop();
                prv = top;
            } else {
                tmp = top.right;
            }
        }

    }

    public static TreeNode1 buildTree() {
        TreeNode1 a = new TreeNode1(1);
        TreeNode1 b = new TreeNode1(2);
        TreeNode1 c = new TreeNode1(3);
        TreeNode1 d = new TreeNode1(4);
        TreeNode1 e = new TreeNode1(5);
        TreeNode1 f = new TreeNode1(6);
        TreeNode1 g = new TreeNode1(7);
        a.left = b;
        a.right = c;
        b.left = d;
        b.right = e;
        c.left = f;
        c.right = g;
        return a;

    }
}

联系我们

如果您对我们的服务有兴趣,请及时和我们联系!

服务热线:18288888888
座机:18288888888
传真:
邮箱:888888@qq.com
地址:郑州市文化路红专路93号