package BST;
import java.util.*;
public class BST {
/*
* 重建二叉树
* 先找到root,再递归构建root的左子树root.left和右子树root.right
* */
public TreeNode reConstructBinaryTree(int[] pre, int[] in) {
if (pre == null || in == null) {
return null;
}
if (pre.length == 0 || in.length == 0) {
return null;
}
TreeNode root = new TreeNode(pre[0]);
for (int i = 0; i < in.length; i++) {
if (in[i] == pre[0]) {
root.left = reConstructBinaryTree(Arrays.copyOfRange(pre, 1, i + 1), Arrays.copyOfRange(in, 0, i));
root.right = reConstructBinaryTree(Arrays.copyOfRange(pre, i + 1, pre.length), Arrays.copyOfRange(in, i + 1, in.length));
}
}
return root;
}
/*
* 判断给定数组是否是二分搜索树的后续遍历
* 1.如果数组为空/长度为零,返回false
* 2.二分搜索树的根不断变化,递归调用,需要start,end参数指定二分搜索树的根节点
* 3.私有函数:判断从start到end范围的数组是否为后续遍历,判断方法是找到第一个大于根节点的节点,
* 再判断右子树的节点值是否都大于根节点,如果不是,返回false
* 4.递归调用确定左右子树的根节点所在范围
*
* */
public boolean VerifySquenceOfBST(int[] sequence) {
if (sequence == null || sequence.length == 0) {
return false;
}
return VerifySquenceOfBST(sequence, 0, sequence.length - 1);
}
private boolean VerifySquenceOfBST(int[] sequence, int start, int end) {
if (start >= end) {
return true;
}
int i = start;
while (sequence[i] < sequence[end]) {
i++;
}
for (int j = i; j < end; j++) {
if (sequence[j] < sequence[end]) {
return false;
}
}
return VerifySquenceOfBST(sequence, start, i - 1) && VerifySquenceOfBST(sequence, i, end - 1);
}
/*
* 判断给定数组是否是二分搜索树的后续遍历 (没有用私有函数的写法)
* 1.如果数组为空/长度为零,返回false
* 2.二分搜索树的根不断变化,递归调用,需要start,end参数指定二分搜索树的根节点
* 3.私有函数:判断从start到end范围的数组是否为后续遍历,判断方法是找到第一个大于根节点的节点,
* 再判断右子树的节点值是否都大于根节点,如果不是,返回false
* 4.递归调用确定左右子树的根节点所在范围
*
* */
public boolean VerifySquenceOfBST1(int[] sequence) {
int len = sequence.length;
if (len == 0) return false;
int root = sequence[len - 1];
int i = 0;
for (; i < len - 1; i++) {
if (sequence[i] > root) break;
}
int j = i;
for (; j < len - 1; j++) {
if (sequence[j] < root) return false;
}
boolean left = true, right = true;
if (i > 0) left = VerifySquenceOfBST1(Arrays.copyOfRange(sequence, 0, i));
if (i < len - 1) right = VerifySquenceOfBST1(Arrays.copyOfRange(sequence, i, len - 1));
return left && right;
}
/*
*二叉树的下一个节点
* 若果X有右孩子,下一个节点是右孩子最左边节点
* 如果X没有右孩子,找到X的parent,若p的左孩子是X,下一个节点就是p,否则p往上找(p = p.p,x = p)
* */
public class Node{
private int val;
private Node left;
private Node right;
private Node parent;
}
public Node getSuccessorNode(Node node) {
if (node == null) {
return null;
}
if (node.right != null) {
return getLeftMost(node.right);
} else {
Node parent = node.parent;
while (parent != null && parent.left != node) {
node = parent;
parent = node.parent;
}
return parent;
}
}
public Node getLeftMost(Node node) {
if (node == null) {
return node;
}
while (node.left != null) {
node = node.left;
}
return node;
}
/*
* 二叉树层序遍历
* */
public void levelOrder(TreeNode head){
ArrayList<ArrayList<TreeNode>> results=new ArrayList<>();
ArrayList<TreeNode> levelList = new ArrayList<>();
TreeNode last = head;//初始化当前层最后节点
TreeNode nlast = null;//记录下次要更换的最后节点
Queue<TreeNode> q = new LinkedList<>();
q.add(head);
while(!q.isEmpty()){
TreeNode cur = q.remove();
//System.out.println(cur.value);
levelList.add(cur);
if(cur.left != null) {
q.add(cur.left);
nlast = cur.left;
}
if(cur.right != null) {
q.add(cur.right);
nlast = cur.right;
}
if (cur == last) {//当前访问节点为该层的最后一个节点
results.add(levelList);
levelList = new ArrayList<TreeNode>();
last = nlast;
}
}
}
/*
* 树的子结构
*判断root2是否是root1的子树
*分为两步:第一步遍历root1这棵树,寻找和root2根节点相同的结点
* */
public boolean HasSubtree(TreeNode root1, TreeNode root2) {
boolean res = false;
if (root1 != null && root2 != null) {
if (root1.val == root2.val) {
res = tree1HasTree2(root1, root2);
}
if (!res) {
res = HasSubtree(root1.left, root2);
}
if (!res) {
res = HasSubtree(root1.right, root2);
}
}
return res;
}
//root1.val = root2.val的情况下,判断其左右子树的值是否相同
private boolean tree1HasTree2(TreeNode root1, TreeNode root2) {
if (root1 == null && root2 != null) {
return false;
}
if (root2 == null) {
return true;
}
if (root1.val != root2.val) {
return false;
}
return tree1HasTree2(root1.left, root2.left) && tree1HasTree2(root1.right, root2.right);
}
/*
* 二叉树的镜像
*
* */
public void Mirror(TreeNode root) {
if (root == null) {
return;
}
if (root.left != null || root.right != null) {
TreeNode temp = root.left;
root.left = root.right;
root.right = temp;
Mirror(root.left);
Mirror(root.right);
}
}
/*
* 二叉搜索树的中序非递归遍历
* 当前节点不为空,入栈,一直往左窜;当前节点不为空访问该节点,往右
* */
public void inOrder(TreeNode head) {
if (head != null) {
Stack<TreeNode> stack = new Stack<>();
while (head != null || !stack.isEmpty()) {
if (head != null) {
stack.push(head);
head = head.left;
} else {
head = stack.pop();
System.out.println(head.val);//
head = head.right;
}
}
}
}
/*
* 二叉搜索树与双向链表
* 当前节点不为空,入栈,一直往左窜;当前节点不为空出栈访问该节点,往右
* */
public TreeNode Convert(TreeNode root) {
if (root == null) {
return null;
}
Stack<TreeNode> stack = new Stack<>();
TreeNode pre = null;
TreeNode cur = root;
boolean flag = true;
while (cur != null || !stack.isEmpty()) {
if (cur!=null){
stack.push(cur);
cur = cur.left;
}else {
cur = stack.pop();
if (flag){//第一次,cur为root
root = cur;
pre = root;
flag = false;
}else {
pre.right = cur;
cur.left = pre;
pre = cur;
}
cur = cur.right;
}
}
return root;
}
/*判断是否为对称二叉树
* 对称的树的左子树和右子树满足以下条件:都为空,一个空,都不空
* 1.如果左子树或右子树均为空,则该树对称;
* 2.如果左子树或右子树只有一个为空,则该树不对称;
* 3.如果左子树和右子树均不为空,当左子树的左子树和右子树的右子树镜像对称,
* 且左子树的右子树和右子树的左子树 镜像对称时,该树对称。
* */
/*
判断两颗树是否相同
两棵二叉树均为空,则相等;
两棵二叉树其中一棵为空,另一棵不为空,则不相等;
两棵二叉树均不为空,如果根节点的值相等,左子树相等和右子树相等,则这两棵二叉树相等,否则不相等。
*/
boolean isSymmetrical(TreeNode pRoot) {
if (pRoot == null) {
return true;
}
return isCommon(pRoot.left, pRoot.right);
}
public boolean isCommon(TreeNode left, TreeNode right) {
if (left == null && right == null) {
return true;
}
if (left != null && right != null) {
return left.val == right.val && isCommon(left.left,right.right )&&isCommon(left.right,right.left );
}
return false;
}
/*
* 二叉搜索树第k个节点
* */
int count = 0;
TreeNode KthNode(TreeNode pRoot, int k) {
if (pRoot != null) {
TreeNode left = KthNode(pRoot.left, k);
if (left != null) {
return left;
}
count++;
if (count==k){
return pRoot;
}
TreeNode right = KthNode(pRoot.right,k );
if (right!=null){
return right;
}
}
return null;
}
/*
* 二叉搜索树第k个节点(方法二)
* */
ArrayList<TreeNode> list = new ArrayList<>(); // (1)
TreeNode KthNode1(TreeNode pRoot, int k)
{
addNode(pRoot);
if(k>=1 && list.size()>=k) {
return list.get(k-1);
}
return null;
}
// 中序遍历
void addNode(TreeNode cur) { // (2)
if(cur != null) {
addNode(cur.left);
list.add(cur);
addNode(cur.right);
}
}
}
/*
* 序列化和反序列化
* */
String Serialize(TreeNode root) {
if (root == null) {
return "#!";
}
String s = root.val + "!";
s = s + Serialize(root.left);
s = s + Serialize(root.right);
return s;
}
TreeNode Deserialize(String str) {
String[] values = str.split("!");
Queue<String> queue = new LinkedList<>();
for (int i = 0;i<values.length;i++){
queue.offer(values[i]);
}
return reConpre(queue);
}
private TreeNode reConpre(Queue<String> queue) {
String value = queue.poll();
if (value.equals("#")){
return null;
}
TreeNode head = new TreeNode(Integer.valueOf(value));
head.left = reConpre(queue);
head.right = reConpre(queue);
return head;
}
剑指offer:二叉树、二叉树搜索树
猜你喜欢
转载自www.cnblogs.com/susanhe/p/11919033.html
今日推荐
周排行