二叉树的基本操作:
import java.util.LinkedList;
import java.util.Queue;
class Node {
public char val;
public Node left;
public Node right;
public Node(char val) {
this.val = val;
}
}
public class BinaryTree {
public Node creatTree() {
Node A = new Node('A');
Node B = new Node('B');
Node C = new Node('C');
Node D = new Node('D');
Node E = new Node('E');
Node F = new Node('F');
Node G = new Node('G');
Node H = new Node('H');
A.left = B;
A.right = C;
B.left = D;
B.right = E;
E.right = H;
C.left = F;
C.right = G;
return A;
}
// 前序遍历
public void preOrderTraversal(Node root) {
if (root == null) return;
System.out.print(root.val + " ");
preOrderTraversal(root.left);
preOrderTraversal(root.right);
}
// 中序遍历
public void inOrderTraversal(Node root) {
if (root == null) return;
inOrderTraversal(root.left);
System.out.print(root.val + " ");
inOrderTraversal(root.right);
}
// 后序遍历
public void postOrderTraversal(Node root) {
if (root == null) return;
postOrderTraversal(root.left);
postOrderTraversal(root.right);
System.out.print(root.val + " ");
}
// 遍历思路-求结点个数
static int size = 0;
public void getSize1(Node root) {
if (root == null) return;
size++;
getSize1(root.left);
getSize1(root.right);
}
// 子问题思路-求结点个数
public int getSize2(Node root) {
if (root == null) return 0;
int left = getSize2(root.left);
int right = getSize2(root.right);
return left + right + 1;
}
// 遍历思路-求叶子结点个数
static int leafSize = 0;
public void getLeafSize1(Node root) {
if (root == null) return;
if (root.left == null && root.right == null) {
leafSize++;
}
getLeafSize1(root.left);
getLeafSize1(root.right);
}
// 子问题思路-求叶子结点个数
public int getLeafSize2(Node root) {
if (root == null) return 0;
if (root.left == null && root.right == null) return 1;
return getLeafSize2(root.left) + getLeafSize2(root.right);
}
// 子问题思路-求第 k 层结点个数
public int getKLevelSize(Node root, int k) {
if (root == null) return 0;
if (k == 1) return 1;
return getKLevelSize(root.left, k - 1) + getKLevelSize(root.right, k - 1);
}
// 获取二叉树的高度
public int getHeight(Node root) {
if (root == null) return 0;
int leftHeight = getHeight(root.left);
int rightHeight = getHeight(root.right);
return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
}
// 查找 val 所在结点,没有找到返回 null
// 按照 根 -> 左子树 -> 右子树的顺序进行查找
// 一旦找到,立即返回,不需要继续在其他位置查找
public Node find(Node root, int val) {
if (root == null) {
return null;
}
if (root.val == val) {
return root;
}
Node ret1 = find(root.left, val);
if (ret1 != null) {
return ret1;
}
Node ret2 = find(root.right, val);
if (ret2 != null) {
return ret2;
}
return null;
}
// 层序遍历
public void levelOrderTraversal(Node root) {
if (root == null) return;
Queue<Node> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
Node cur = queue.poll();
System.out.print(cur.val+" ");
if (cur.left != null) {
queue.offer(cur.left);
}
if (cur.right != null) {
queue.offer(cur.right);
}
}
}
// 判断一棵树是不是完全二叉树
public boolean isCompleteTree(Node root) {
if (root == null) return true;
Queue<Node> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
Node cur = queue.poll();
if (cur != null) {
queue.offer(cur.left);
queue.offer(cur.right);
} else {
break;
}
}
while (!queue.isEmpty()) {
Node cur = queue.peek();
if (cur != null) {
return false;
} else {
queue.poll();
}
}
return true;
}
判断两棵树是否相同:
public boolean isSameTree(Node p, Node q) {
if (p == null && q != null || p != null && q == null) {
return false;
}
if (p == null && q == null) {
return true;
}
if (p.val != q.val) {
return false;
}
return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
}
另一棵树的子树:
public boolean isSameTree(Node p, Node q) {
if (p == null && q != null || p != null && q == null) {
return false;
}
if (p == null && q == null) {
return true;
}
if (p.val != q.val) {
return false;
}
return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
}
//另一个树的子树
public boolean isSubtree(Node s, Node t) {
if (s == null || t == null) return false;
if (isSameTree(s,t)) return true;
if (isSubtree(s.left,t)) return true;
if (isSubtree(s.right,t)) return true;
return false;
}
判断二叉树的完全性:
public boolean isCompleteTree(Node root) {
if (root == null) return true;
Queue<Node> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
Node cur = queue.poll();
if (cur != null) {
queue.offer(cur.left);
queue.offer(cur.right);
} else {
break;
}
}
while (!queue.isEmpty()) {
Node cur = queue.peek();
if (cur != null) {
return false;
} else {
queue.poll();
}
}
return true;
}
合并二叉树:
public Node mergeTrees(Node t1, Node t2) {
if (t1 == null||t2 == null) return null;
if (t1 != null) return t1;
if (t2 != null) return t2;
Node ret = new Node(t1.val + t2.val);
ret.left = mergeTrees(t1.left, t2.left);
ret.right = mergeTrees(t1.right, t2.right);
return ret;
}
平衡二叉树:
public boolean isBalanced(TreeNode root) {
if(root == null) return true;
return Math.abs(getHeight(root.left) - getHeight(root.right))<=1&&isBalanced(root.left)&&isBalanced(root.right);
}
public int getHeight(TreeNode root){
if(root == null) return 0;
int left = getHeight(root.left);
int right = getHeight(root.right);
return left>right?left+1:right+1;
}
对称二叉树:
public boolean isSymmetric(TreeNode root) {
if(root == null) return true;
return isSymmetricChild(root.left,root.right);
}
public boolean isSymmetricChild(TreeNode leftTree,TreeNode rightTree){
if(leftTree == null&&rightTree!=null||leftTree!=null&&rightTree == null){
return false;
}
if(leftTree == null&&rightTree == null){
return true;
}
if(leftTree.val!=rightTree.val){
return false;
}
return isSymmetricChild(leftTree.left,rightTree.right)&&isSymmetricChild(leftTree.right,rightTree.left);
}
二叉树的构建及遍历:
class Node {
public char val;
public Node left;
public Node right;
public Node(char val) {
this.val = val;
}
public class Main{
public int i = 0;
public Node creatTreeByString(String str) {
Node root = null;
if (str.charAt(i) != '#') {
root = new Node(str.charAt(i));
i++;
root.left = creatTreeByString(str);
root.right = creatTreeByString(str);
} else {
i++;
}
return root;
}
}
}
二叉树的分层遍历:
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> ret = new ArrayList<>();
if(root == null) return ret;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
List<Integer> rowList = new ArrayList<>();
int count = queue.size();
while(count!=0){
TreeNode cur = queue.poll();
if(cur!=null){
rowList.add(cur.val);
if(cur.left!=null){
queue.offer(cur.left);
}
if(cur.right!=null){
queue.offer(cur.right);
}
}
count--;
}
ret.add(rowList);
}
return ret;
}
二叉树的最近公共祖先:
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null) return null;
if (root == p || root == q) {
return root;
}
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
if (left != null && right != null) {
return root;
}
return left == null ? right : left;
}
二叉搜索树与双向链表:
public TreeNode Convert(TreeNode pRootOfTree) {
if(pRootOfTree==null) return null;
ConvertChild(pRootOfTree);
TreeNode head = pRootOfTree;
while(head.left!=null){
head = head.left;
}
return head;
}
public TreeNode prev = null;
public void ConvertChild(TreeNode root){
if(root==null)return;
ConvertChild(root.left);
root.left = prev;
if(prev!=null){
prev.right = root;
}
prev = root;
ConvertChild(root.right);
}
根据二叉树创建字符串:
public void tree2strChild(TreeNode t, StringBuilder sb) {
if (t == null) return;
sb.append(t.val);
if (t.left == null) {
if (t.right == null) {
return;
} else {
sb.append("(");
sb.append(")");
}
} else {
sb.append("(");
tree2strChild(t.left,sb);
sb.append(")");
}
if (t.right == null) {
return;
} else {
sb.append("(");
tree2strChild(t.right,sb);
sb.append(")");
}
}
// 根据二叉树创建字符串
public String tree2str(TreeNode t) {
if (t == null) return "";
StringBuilder sb = new StringBuilder();
tree2strChild(t,sb);
return sb.toString();
}
前序和中序遍历构建二叉树:
public TreeNode buildTree(int[] preorder, int[] inorder) {
if(preorder == null||inorder == null) return null;
if(preorder.length == 0|| inorder.length == 0) return null;
return buildTreeChild(preorder,inorder,0,inorder.length - 1);
}
public int preIndex = 0;
public TreeNode buildTreeChild(int[] preorder,int[] inorder,int inbegin,int inend){
if(inbegin>inend){
return null;
}
TreeNode root = new TreeNode(preorder[preIndex]);
int inorderIndex = findInorderIndexOfRoot(inorder,inbegin,inend,preorder[preIndex]);
preIndex++;
root.left = buildTreeChild(preorder,inorder,inbegin,inorderIndex-1);
root.right = buildTreeChild(preorder,inorder,inorderIndex+1,inend);
return root;
}
public int findInorderIndexOfRoot(int[] inorder,int inbegin,int inend,int val){
for(int i = inbegin;i<=inend;i++){
if(inorder[i] == val){
return i;
}
}
return -1;
}
中序和后序遍历构建二叉树:
public int preIndex = 0;
public TreeNode buildTree(int[] inorder, int[] postorder) {
if(inorder == null||postorder == null) return null;
if(inorder.length == 0||postorder.length == 0) return null;
preIndex = postorder.length-1;
return buildTreeChild(inorder,postorder,0,postorder.length - 1);
}
public TreeNode buildTreeChild(int[] inorder,int[] postorder,int inbegin,int inend){
if(inbegin>inend){
return null;
}
TreeNode root = new TreeNode(postorder[preIndex]);
int inorderIndex = findInorderIndexOfRoot(inorder,inbegin,inend,postorder[preIndex]);
preIndex--;
root.right = buildTreeChild(inorder,postorder,inorderIndex+1,inend);
root.left = buildTreeChild(inorder,postorder,inbegin,inorderIndex-1);
return root;
}
public int findInorderIndexOfRoot(int[] inorder,int inbegin,int inend,int val){
for(int i = inbegin;i<=inend;i++){
if(inorder[i] == val){
return i;
}
}
return -1;
}
二叉树前序遍历非递归:
public void preOrderTree(Node root) {
Stack<Node> stack = new Stack<>();
Node cur = root;
while (cur != null || !stack.isEmpty()) {
while (cur != null) {
System.out.print(cur.val+" ");
stack.push(cur);
cur = cur.left;
}
Node top = stack.pop();
cur = top.right;
}
}
中序遍历非递归:
public void inOrderTree(Node root) {
if (root == null) return;
Stack<Node> stack = new Stack<>();
Node cur = root;
while (cur != null || !stack.isEmpty()) {
while (cur != null) {
stack.push(cur);
cur = cur.left;
}
Node top = stack.pop();
System.out.print(top.val+" ");
cur = top.right;
}
}
后序遍历非递归:
public void postOrderTree(Node root) {
if (root == null) return;
Stack<Node> stack = new Stack<>();
Node cur = root;
Node prev = null;
while (cur != null || !stack.isEmpty()) {
while (cur != null) {
stack.push(cur);
cur = cur.left;
}
cur = stack.peek();
if (cur.right == null || cur.right == prev) {
stack.pop();
System.out.print(cur.val + " ");
prev = cur;
cur = null;
} else {
cur = cur.right;
}
}
}