二叉树特性:
image.png
二叉树 - 图2
前序排列:1、3、6、5、2、4
中序排列:6、3、5、1、2、4
后序排列:6、5、3、4、2、1
层序排列:1、3、2、6、5、4

根据前序和中序还原二叉树(后序中序同理)

  1. //根据前序节点得到root节点
  2. //循环从中序中root节点的下标i找到
  3. //左节点=把中序从0到i,前序从1到i+1放到方法中递归
  4. //右节点=把中序从i+1到中序最后,前序从i+1到前序最后
  5. public static TreeNode reConstruct_PreMid(int[] preOrder, int[] midOrder) {
  6. if (preOrder.length == 0 || midOrder.length == 0) {
  7. return null;
  8. }
  9. // preOrder[0] 必定是root根节点
  10. TreeNode root = new TreeNode(preOrder[0]);
  11. for (int i = 0; i < midOrder.length; i++) {
  12. if (preOrder[0] == midOrder[i]) {
  13. root.leftChild = reConstruct_PreMid(Arrays.copyOfRange(preOrder, 1, i + 1),
  14. Arrays.copyOfRange(midOrder, 0, i));
  15. root.rightChild = reConstruct_PreMid(Arrays.copyOfRange(preOrder, i + 1, preOrder.length),
  16. Arrays.copyOfRange(midOrder, i + 1, midOrder.length));
  17. }
  18. }
  19. return root;
  20. }

根据层序和中序还原二叉树

  1. //根据层序第一个节点是root节点找出mid中root节点的下标i
  2. //如果层序的长度大于2,就进行下一步,否则返回root节点
  3. //判断层序第二个节点是左子树还是右子树()
  4. //如果为左子树,
  5. //左节点=获取层序数列中左子树的层序,再递归执行
  6. //右节点=如果层序len大于等于3,且层序第三个节点为右节点,则获取右节点层序,递归执行
  7. //如果为右子树,则获取右子树的层序,递归执行
  8. //判断左子树:循环中序,如果等于root节点值就返回,如果等于目标节点则标志为左节点
  9. //获取子层序:中序根据root节点,传入左或者右节点序列,再根据原层序一一比对,找出相同的则为子层序
  10. public static TreeNode buildTreeByMidLevel(int[] levelOrder, int[] midOrder, int midBegin, int midEnd) {
  11. if (levelOrder.length == 0 || midOrder.length == 0) {
  12. return null;
  13. }
  14. // levelOrder[0] 必定是root根节点
  15. TreeNode root = new TreeNode(levelOrder[0]);
  16. // rootLocation:(子)序列中根节点的位置
  17. int rootLocation = -1;
  18. for (int i = midBegin; i <= midEnd; i++) {
  19. if (midOrder[i] == levelOrder[0]) {
  20. rootLocation = i;
  21. break;
  22. }
  23. }
  24. // 划分左右子树
  25. // levelOrder.length会影响划分
  26. if (levelOrder.length >= 2) {
  27. if (isLeft(midOrder, levelOrder[0], levelOrder[1])) {
  28. // 左子树
  29. root.leftChild = buildTreeByMidLevel(getLevelStr(midOrder, midBegin, rootLocation - 1, levelOrder),
  30. midOrder, midBegin, rootLocation - 1);
  31. // 处理左子树为空的情况,注意levelOrder.length需>=3
  32. if (levelOrder.length >= 3 && !isLeft(midOrder, levelOrder[0], levelOrder[2])) {
  33. root.rightChild = buildTreeByMidLevel(getLevelStr(midOrder, rootLocation + 1, midEnd, levelOrder),
  34. midOrder, rootLocation + 1, midEnd);
  35. }
  36. } else {
  37. // 右子树
  38. root.rightChild = buildTreeByMidLevel(getLevelStr(midOrder, rootLocation + 1, midEnd, levelOrder),
  39. midOrder, rootLocation + 1, midEnd);
  40. }
  41. }
  42. return root;
  43. }
  44. public static boolean isLeft(int[] order, int root, int child) {
  45. boolean findVal = false;
  46. for (int temp : order) {
  47. if (temp == child) {
  48. findVal = true;
  49. } else if (temp == root) {
  50. return findVal;
  51. }
  52. }
  53. return false;
  54. }
  55. public static int[] getLevelStr(int[] midOrder, int midBegin, int midEnd, int[] levelOrder) {
  56. int[] result = new int[midEnd - midBegin + 1];
  57. int curLoc = 0;
  58. for (int i = 0; i < levelOrder.length; i++) {
  59. if (contains(midOrder, levelOrder[i], midBegin, midEnd)) {
  60. result[curLoc++] = levelOrder[i];
  61. }
  62. }
  63. return result;
  64. }
  65. public static boolean contains(int[] midOrder, int target, int midBegin, int midEnd) {
  66. for (int i = midBegin; i <= midEnd; i++) {
  67. if (midOrder[i] == target) {
  68. return true;
  69. }
  70. }
  71. return false;
  72. }

找出每层最大值

  1. import java.util.ArrayList;
  2. import java.util.LinkedList;
  3. import java.util.Queue;
  4. public class Main {
  5. public static class TreeNode {
  6. public int val;
  7. public TreeNode left;
  8. public TreeNode right;
  9. public TreeNode(int data) {
  10. this.val = data;
  11. }
  12. }
  13. //找出二叉树每层的最大值节点
  14. public static void findMaxNodeInLevel(TreeNode pRoot) {
  15. ArrayList<Integer> resultList = new ArrayList<>();
  16. Queue<TreeNode> layer = new LinkedList<TreeNode>();
  17. ArrayList<Integer> layerList = new ArrayList<Integer>();
  18. layer.add(pRoot);
  19. int start = 0, end = 1;
  20. while (!layer.isEmpty()) {
  21. TreeNode cur = layer.remove();
  22. layerList.add(cur.val);
  23. start++;
  24. if (cur.left != null) {
  25. layer.add(cur.left);
  26. }
  27. if (cur.right != null) {
  28. layer.add(cur.right);
  29. }
  30. if (start == end) {
  31. end = layer.size();
  32. start = 0;
  33. resultList.add(findMaxNode(layerList));
  34. layerList = new ArrayList<Integer>();
  35. }
  36. }
  37. for (Integer i : resultList) {
  38. System.out.println(i);
  39. }
  40. }
  41. public static int findMaxNode(ArrayList<Integer> list) {
  42. int max = Integer.MIN_VALUE;
  43. for (Integer i : list) {
  44. if (max < i) {
  45. max = i;
  46. }
  47. }
  48. return max;
  49. }
  50. public static void main(String[] args) {
  51. TreeNode head = new TreeNode(1);
  52. head.left = new TreeNode(2);
  53. head.right = new TreeNode(3);
  54. head.left.left = new TreeNode(4);
  55. head.left.right = new TreeNode(5);
  56. head.right.left = new TreeNode(6);
  57. head.right.right = new TreeNode(7);
  58. findMaxNodeInLevel(head);
  59. }
  60. }

求最大宽度

  1. public static int getMaxWidth2(Node head) {
  2. if (head == null) {
  3. return 0;
  4. }
  5. //当前层最后一个结点
  6. Node curEnd = head;
  7. //下一层最后一个结点
  8. Node nextEnd = null;
  9. //当前层结点数
  10. int curLevelNodes = 0;
  11. //结点数最多的层的结点数
  12. int max = Integer.MIN_VALUE;
  13. Queue<Node> queue = new LinkedList<>();
  14. queue.add(head);
  15. while (!queue.isEmpty()) {
  16. head = queue.poll();
  17. curLevelNodes++;
  18. if (head.left != null) {
  19. queue.add(head.left);
  20. nextEnd = head.left;
  21. }
  22. if (head.right != null) {
  23. queue.add(head.right);
  24. nextEnd = head.right;
  25. }
  26. if (head == curEnd) {
  27. max = Math.max(max, curLevelNodes);
  28. curLevelNodes = 0;
  29. curEnd = nextEnd;
  30. nextEnd = null;
  31. }
  32. }
  33. return max;
  34. }