0
点赞
收藏
分享

微信扫一扫

剑指 Offer打卡 树


1、二叉树的下一个结点

/**
* 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回 。
* 注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
*
* @author mxz
*/
public class Solution {
public static void main(String[] args) {

}


/**
* 中序遍历的过程:先遍历树的左子树,再遍历根节点,最后再遍历右子树。
* 所以最左节点是中序遍历的第一个节点。
* void traverse(TreeNode root) {
* if (root == null) return;
* traverse(root.left);
* visit(root);
* traverse(root.right);
* }
*
* @param pNode
* @return
*/
public TreeLinkNode GetNext(TreeLinkNode pNode) {
if (pNode.right != null) {
TreeLinkNode node = pNode.right;
while (node.left != null)
node = node.left;
return node;
} else {
while (pNode.next != null) {
TreeLinkNode parent = pNode.next;
if (parent.left == pNode)
return parent;
pNode = pNode.next;
}
}
return null;
}
}

2、二叉树的深度

/**
* 输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,
* 最长路径的长度为树的深度,根节点的深度视为 1 。
*
* @author mxz
*/
public class Solution {
public static void main(String[] args) {

}

public int TreeDepth(TreeNode root) {
return root == null ? 0 : Math.max(TreeDepth(root.left), TreeDepth(root.right)) + 1;
}

public int TreeDepth2(TreeNode root) {
if (root == null) return 0;
Queue<TreeNode> q = new LinkedList<>();
q.add(root);
int level = 0;
while (!q.isEmpty()) {
int size = q.size();
while (size-- > 0) {
TreeNode curr = q.poll();
if (curr.left != null) q.add(curr.left);
if (curr.right != null) q.add(curr.right);
}
level++;
}
return level;
}
}

3、二叉树的镜像

/**
* 操作给定的二叉树,将其变换为源二叉树的镜像。
*
* @author mxz
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param pRoot TreeNode类
* @return TreeNode类
*/
public TreeNode Mirror (TreeNode pRoot) {
if (pRoot == null) {
return pRoot;
}
swap(pRoot);
Mirror(pRoot.left);
Mirror(pRoot.right);
return pRoot;
}

public void swap(TreeNode root) {
TreeNode t = root.left;
root.left = root.right;
root.right = t;
}
}

4、从上往下打印二叉树

public class Solution {
public static void main(String[] args) {

}

/**
* 思路是用arraylist模拟一个队列来存储相应的TreeNode
*
* @param root
* @return
*/
public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
ArrayList<Integer> list = new ArrayList<>();
ArrayList<TreeNode> queue = new ArrayList<>();
if (root == null) {
return list;
}
queue.add(root);
// 8
// 6 10
// 2 1
while (queue.size() != 0) {
TreeNode temp = queue.remove(0);
if (temp.left != null){
queue.add(temp.left);
}
if (temp.right != null) {
queue.add(temp.right);
}
list.add(temp.val);
}
return list;
}
}

5、对称的二叉树

public class Solution {
public static void main(String[] args) {

}

boolean isSymmetrical(TreeNode pRoot) {
if (pRoot == null)
return true;
return isSymmetrical(pRoot.left, pRoot.right);
}

boolean isSymmetrical(TreeNode t1, TreeNode t2) {
if (t1 == null && t2 == null)
return true;
if (t1 == null || t2 == null)
return false;
if (t1.val != t2.val)
return false;
return isSymmetrical(t1.left, t2.right) && isSymmetrical(t1.right, t2.left);
}
}

6、按之字形顺序打印二叉树

public class Solution {
public ArrayList<ArrayList<Integer>> Print(TreeNode pRoot) {
LinkedList<TreeNode> q = new LinkedList<>();
ArrayList<ArrayList<Integer>> res = new ArrayList<>();
boolean rev = true;
q.add(pRoot);
while (!q.isEmpty()) {
int size = q.size();
ArrayList<Integer> list = new ArrayList<>();
for (int i = 0; i < size; i++) {
TreeNode node = q.poll();
if (node == null) {
continue;
}
if (rev) {
list.add(node.val);
} else {
list.add(0, node.val);
}
q.offer(node.left);
q.offer(node.right);
}
if (list.size() != 0) {
res.add(list);
}
rev = !rev;
}
return res;
}
}

7、树的子结构

public class Solution {
public static void main(String[] args) {

}

public boolean HasSubtree(TreeNode root1, TreeNode root2) {
if (root1 == null || root2 == null) {
return false;
}
return isSubtreeWithRoot(root1, root2) || HasSubtree(root1.left, root2) || HasSubtree(root1.right, root2);
}

public boolean isSubtreeWithRoot(TreeNode root1, TreeNode root2) {
if (root2 == null) {
return true;
}
if (root1 == null) {
return false;
}
if (root1.val != root2.val) {
return false;
}
return isSubtreeWithRoot(root1.left, root2.left) && isSubtreeWithRoot(root1.right, root2.right);
}
}

8、遍历

/**
* 树的遍历
*
* @author inke219223m
*/
public class Solution {

public static void main(String[] args) {
// 层序遍历测试 SRART
System.out.println("==========层序遍历测试 SRART==========");
TreeNode root = new TreeNode();
root.val = 1;
TreeNode root_left = new TreeNode();
root_left.val = 3;
TreeNode root_right = new TreeNode();
root_right.val = 2;

root.left = root_left;
root.right = root_right;


TreeNode root_left_left = new TreeNode();
root_left_left.val = 4;
root_left.left = root_left_left;

new Solution().levelOrder(root).forEach(System.out::println);
// 层序遍历测试 END
System.out.println();
// 前序遍历 START
System.out.println("==========前序遍历 START==========");

new Solution().preOrderTraverse(root);
System.out.println();
// 前序遍历 END
System.out.println();
// 中序遍历 START
System.out.println("==========中序遍历 START==========");

new Solution().inOrderTraverse(root);
System.out.println();
// 中序遍历 END
System.out.println();

// 后序遍历 START
System.out.println("==========后序遍历 START==========");

new Solution().postOrderTraverse(root);
System.out.println();
// 后序遍历 END

}

/**
* 层序遍历(BFS思想)
*
* @param root
* @return
*/
public ArrayList<ArrayList<Integer>> levelOrder(TreeNode root) {
// write code here
ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();
//根节点为空,直接返回res
if (root == null) return res;
if (root != null) {
// 用先进先出的队列
Queue<TreeNode> queue = new LinkedList<>();
// 在容量已满的情况下,add() 方法会抛出IllegalStateException异常,offer() 方法只会返回 false。
queue.offer(root);
while (!queue.isEmpty()) {
int size = queue.size();
ArrayList<Integer> level = new ArrayList<Integer>();
while (size-- > 0) {
// 在队列元素为空的情况下,remove() 方法会抛出NoSuchElementException异常,poll() 方法只会返回 null 。
TreeNode temp = queue.poll();
level.add(temp.val);
if (temp.left != null) queue.offer(temp.left);
if (temp.right != null) queue.offer(temp.right);
}
res.add(level);
}
}
return res;
}

/**
* 前序列遍历
*
* @param node
*/
public void preOrderTraverse(TreeNode node) {
if (node == null) return;
System.out.print(node.val + "\t");
preOrderTraverse(node.left);
preOrderTraverse(node.right);
}

/**
* 中序遍历
*
* @param node
*/
private void inOrderTraverse(TreeNode node) {
if (node == null) return;
inOrderTraverse(node.left);
System.out.print(node.val + "\t");
inOrderTraverse(node.right);
}

/**
* 后序遍历
*
* @param node
*/
private void postOrderTraverse(TreeNode node) {
if (node == null) return;
postOrderTraverse(node.left);
postOrderTraverse(node.right);
System.out.print(node.val + "\t");
}

}

9、重建二叉树

public class Solution {
public static void main(String[] args) {
System.out.println(new Solution().reConstructBinaryTree(
new int[]{1, 2, 4, 7, 3, 5, 6, 8},
new int[]{4, 7, 2, 1, 5, 3, 8, 6}));

}

// 缓存中序遍历数组每个值对应的索引
private Map<Integer, Integer> indexForInOrders = new HashMap<>();


/**
* @param pre 先根遍历
* @param in 中根遍历
* @return
*/
public TreeNode reConstructBinaryTree(int[] pre, int[] in) {
for (int i = 0; i < in.length; i++)
// 4 0 | 7 1 | 2 3 | ...
indexForInOrders.put(in[i], i);
return reConstructBinaryTree(pre, 0, pre.length - 1, 0);
}

/**
* @param pre 先根遍历
* @param preL
* @param preR
* @param inL
* @return
*/
private TreeNode reConstructBinaryTree(int[] pre, int preL, int preR, int inL) {
if (preL > preR) return null;
TreeNode root = new TreeNode(pre[preL]);
int inIndex = indexForInOrders.get(root.val);
int leftTreeSize = inIndex - inL;
root.left = reConstructBinaryTree(pre, preL + 1, preL + leftTreeSize, inL);
root.right = reConstructBinaryTree(pre, preL + leftTreeSize + 1, preR, inL + leftTreeSize + 1);
return root;
}
}

数据结构

public class TreeLinkNode {

public int val;
public TreeLinkNode left = null;
public TreeLinkNode right = null;
public TreeLinkNode next = null; // 指向父结点的指针

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


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

public TreeNode(int x) {
val = x;
}

public TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public TreeNode() {
}
}

代码仓库:https://gitee.com/codingce/codingce-leetcode


举报

相关推荐

0 条评论