二叉搜索树
get方法实现
public class BSTTree{
BSTNode root; // 根节点
static class BSTNode{
int key;
object value;
BSTNode left;
BSTNode right;
public BSTNode(int key, object value) {
this.key = key;
this.vlaue = value;
}
public BSTNode(int key, object value, BSTNode left, BSTNode right) {
this.key = key;
this.vlaue = value;
this.left = left;
this.right = right;
}
}
// 查找关键字对应的值
public Object get(int key) {
return doGet(root, key);
}
private Object doGet(BSTNode node, int key) {
if (node == null) {
return null;
}
if (node.key > key) {
doGet(node.left, key); // 向左找
} else if (node.key < key) {
doGet(node.right, key); // 向右找
} else {
return node.value; // 找到
}
}
// 非递归方式实现get方法
public Object get(int key) {
BSTNode node = root;
while (node != null) {
if (node.key < key) {
node = node.right;
} else if(node.key > key) {
node = node.left;
} else {
return node.value;
}
}
return null;
}
}
二叉搜索树,泛型版本
public class BSTTree<T extends Comparable<T>>{
BSTNode<T> root; // 根节点
static class BSTNode<T>{
T key;
object value;
BSTNode<T> left;
BSTNode<T> right;
public BSTNode<T>(T key, object value) {
this.key = key;
this.vlaue = value;
}
public BSTNode<T>(T key, object value, BSTNode<T> left, BSTNode<T> right) {
this.key = key;
this.vlaue = value;
this.left = left;
this.right = right;
}
}
// 非递归方式实现get方法
public Object get(T key) {
BSTNode<T> node = root;
while (node != null) {
int res = key.compareTo(node.key);
if (res > 0) {
node = node.left;
} else if (res < 0) {
node = node.right;
} else {
return node.value;
}
}
return null;
}
}
查找最小关键字对应值
public class BSTTree{
BSTNode root; // 根节点
static class BSTNode{
int key;
object value;
BSTNode left;
BSTNode right;
public BSTNode(int key, object value) {
this.key = key;
this.vlaue = value;
}
public BSTNode(int key, object value, BSTNode left, BSTNode right) {
this.key = key;
this.vlaue = value;
this.left = left;
this.right = right;
}
}
// 查找关键字对应的值
public Object min() {
return doMin(root);
}
private Object doMin(BSTNode node) {
if (node == null) return null;
if (node.left == null) {
return node.value;
}
return doMin(BSTNode node.left);
}
// 非递归方式实现min方法
public Object min() {
BSTNode node = root;
if (node == null) return null;
while (node.left != null) {
node = node.left;
}
return node.value;
}
}
put方法实现
public class BSTTree{
BSTNode root; // 根节点
static class BSTNode{
int key;
object value;
BSTNode left;
BSTNode right;
public BSTNode(int key, object value) {
this.key = key;
this.vlaue = value;
}
public BSTNode(int key, object value, BSTNode left, BSTNode right) {
this.key = key;
this.vlaue = value;
this.left = left;
this.right = right;
}
}
// 实现put方法,未找到则新增,找到则修改
public void put(int key, Object value) {
BSTNode node = root;
BSTNode pre = null;
if (node == null) return null;
while (node != null) {
pre = node;
if (key < node.key) {
node = node.left;
} else if (key > node.key) {
node = node.right;
} else {
node.value = value;
return;
}
}
if (pre == null) {
root = new BSTNode(key, value);
return;
}
if (pre.key > key) {
pre.left = new BSTNode(key, value);
} else {
pre.right = new BSTNode(key, value);
}
}
}
前任和后任
找前任
public class BSTTree{
BSTNode root; // 根节点
static class BSTNode{
int key;
object value;
BSTNode left;
BSTNode right;
public BSTNode(int key, object value) {
this.key = key;
this.vlaue = value;
}
public BSTNode(int key, object value, BSTNode left, BSTNode right) {
this.key = key;
this.vlaue = value;
this.left = left;
this.right = right;
}
}
public Object predecessor(int key) {
// 1.节点有左子树,此时左子树中最大值为前任
// 2.节点无左子树,此时离节点最近、且从左而来的祖先为前任
BSTNode node = root;
BSTNode ancestorFromLeft = null;
while (node != null) {
if (key < node.key) {
node = node.left;
} else if (key > node.key) {
ancestorFromLeft = node;
node = node.right;
} else {
// 找到该节点
break;
}
}
// 无节点则返回null
if (node == null) {
return null;
}
// 1.节点有左子树,此时左子树中最大值为前任
if(node.left != null) {
return max(node.left);
}
// 2.节点无左子树,此时离节点最近、且从左而来的祖先为前任
return ancestorFromLeft != null ? ancestorFromLeft.value : null;
}
public Object max() {
return max(root);
}
// 寻找任意节点的最大值
private Object max(BSTNode node) {
if (node == null) return null;
while (node.right != null) {
node = node.right;
}
return node.value;
}
}
找后任(后继)
public class BSTTree{
BSTNode root; // 根节点
static class BSTNode{
int key;
object value;
BSTNode left;
BSTNode right;
public BSTNode(int key, object value) {
this.key = key;
this.vlaue = value;
}
public BSTNode(int key, object value, BSTNode left, BSTNode right) {
this.key = key;
this.vlaue = value;
this.left = left;
this.right = right;
}
}
public Object successor(int key) {
// 寻找该节点是否存在
BSTNode p = root;
BSTNode ancestorFromRight = null;
while (p != null) {
if (key < p.key) {
ancestorFromRight = p;
p = p.left;
} else if (key > p.key) {
p = p.right;
} else {
break;
}
}
if (p == null) {
return null;
}
// 节点有右子树
if (p.right != null) {
return min(p.right);
}
// 节点无右子树
return ancestorFromRight != null ? ancestorFromRight : null;
}
public Object min() {
return min(root);
}
public Object min(BSTNode node) {
if (node == null) {
return null;
}
BSTNode p = node;
while (p.left != null) {
p = p.left;
}
return p.value;
}
}
删除操作
非递归版本
public class BSTTree{
BSTNode root; // 根节点
static class BSTNode{
int key;
object value;
BSTNode left;
BSTNode right;
public BSTNode(int key, object value) {
this.key = key;
this.vlaue = value;
}
public BSTNode(int key, object value, BSTNode left, BSTNode right) {
this.key = key;
this.vlaue = value;
this.left = left;
this.right = right;
}
}
// 根据关键字删除节点
public Object delete(int key) {
// 寻找该节点是否存在
BSTNode p = root;
BSTNode pre = null;
while (p != null) {
if (key < p.key) {
pre = p;
p = p.left;
} else if (key > p.key) {
pre = p;
p = p.right;
} else {
break;
}
}
if(p == null) {
return null;
}
// 删除操作
if (p.left == null) {
// 情况1
shift(pre, p, p.right);
} else if (p.right == null) {
// 情况2
shift(pre, p, p.left);
} else {
// 情况4
// 4.1 被删除节点找后继
BSTNode node = p.right;
BSTNode nodeParent = p; // 后继节点父亲
while (node.left != null) {
nodeParent = node;
node = node.left;
}
//
if (nodeParent != p) {
// 删除和后继节点不相邻,处理后继节点后事
shift(nodeParent, node, node.right);
node.right = p.right;
}
shift(parent, p, node);
node.left = p.left;
}
return p.value;
}
private void shift(BSTNode parent, BSTNode deleted, BSTNode child) {
if (parent == null) {
root = child;
} else if (parent.left == deleted) {
parent.left = child;
} else {
parent.right = child;
}
}
}
递归版本
public class BSTTree{
BSTNode root; // 根节点
static class BSTNode{
int key;
object value;
BSTNode left;
BSTNode right;
public BSTNode(int key, object value) {
this.key = key;
this.vlaue = value;
}
public BSTNode(int key, object value, BSTNode left, BSTNode right) {
this.key = key;
this.vlaue = value;
this.left = left;
this.right = right;
}
}
public Object delete(int key) {
ArrayList<Object> result = new ArrayList<>();
root = doDelete(root, key, result);
return result.isEmpty() ? null : result.get(0);
}
// 根据关键字删除节点
public BSTNode doDelete(BSTNode node, int key, ArrayList<Object> result) {
if (node == null) {
return null;
}
if (key < node.key) {
node.left = doDelete(node.left, key, result);
}
if (key > node.key) {
node.right = doDelete(node.right, key, result);
}
// 找到被删除节点
result.add(node.value);
// 情况1,只有右孩子
if (node.left == null) {
return node.right;
}
// 情况2,只有左孩子
if (node.right == null) {
return node.left;
}
// 情况3-- 有两个孩子
BSTNode s = node.right;
while (s.left != null) {
s = s.left;
}
s.right = doDelete(node.right, s.key, new ArrayList<Object>);
s.left = node.left;
return s;
}
}
范围查询
public class BSTTree{
BSTNode root; // 根节点
static class BSTNode{
int key;
object value;
BSTNode left;
BSTNode right;
public BSTNode(int key, object value) {
this.key = key;
this.vlaue = value;
}
public BSTNode(int key, object value, BSTNode left, BSTNode right) {
this.key = key;
this.vlaue = value;
this.left = left;
this.right = right;
}
}
// 找<key的所有value
public List<Object> less(int key) {
ArrayList<Object> list = new ArrayList<>();
Stack<BSTNode> stack = new Stack<>();
BSTNode p = root;
while (p != null || !stack.isEmpty()) {
if (p != null) {
stack.push(p);
p = p.left;
} else {
BSTNode pop = stack.pop();
// 处理值
if (pop.value < key) {
list.add(pop.value);
} else {
break;
}
p = pop.right;
}
}
return list;
}
// 找>key的所有value
public List<Object> greater(int key) {
ArrayList<Object> list = new ArrayList<>();
Stack<BSTNode> stack = new Stack<>();
BSTNode p = root;
while (p != null || !stack.isEmpty()) {
if (p != null) {
stack.push(p);
p = p.left;
} else {
BSTNode pop = stack.pop();
// 处理值
if (pop.value > key) {
list.add(pop.value);
}
p = pop.right;
}
}
return list;
}
// 找>=key1, && <= key2的所有value
public List<Object> between(int key1, int key2) {
ArrayList<Object> list = new ArrayList<>();
Stack<BSTNode> stack = new Stack<>();
BSTNode p = root;
while (p != null || !stack.isEmpty()) {
if (p != null) {
stack.push(p);
p = p.left;
} else {
BSTNode pop = stack.pop();
// 处理值
if (pop.value < key2 && pop.value > key1) {
list.add(pop.value);
}
if (pop.value > key2) break;
p = pop.right;
}
}
return list;
}
}
Leetcode
Leetcode701
public class Leetcode701{
public TreeNode insertIntoBST(TreeNode node, int value) {
if (node == null) {
return new TreeNode(value);
}
if (value < node.value) {
node.left = insertIntoBST(node.left, int value);
}
if (value > node.right) {
node.right = insertIntoBST(node.right, int value);
}
return node;
}
}
Leetcode98
判断二叉搜索树是否合法
方法一
采用中序遍历
public class Leetcode98{
public boolean isValidBST(TreeNode node) {
Stack<TreeNode> stack = new Stack<>();
TreeNode p = node;
while (p != null || !stack.isEmpty()) {
if (p != null) {
stack.push(p);
p = p.left;
} else {
TreeNode pop = stack.pop();
//
if (pop.val >= stack.peek()) {
return false;
}
p = pop.right;
}
}
return true;
}
}
方法二
中序遍历递归版实现
public class Leetcode98{
long pre = Long.MIN_VALUE;
public boolean isValidBST(TreeNode node) {
if (node == null) {
return true;
}
boolean a = isValidBST(node.left);
if(!a) {
return false;
}
// 值
if (pre >= node.val) {
return false;
}
pre = node.val;
boolean b = isValidBST(node.right);
return b;
}
}
方法三
上下限递归实现
public class Leetcode98 {
public boolean isValidBST(TreeNode root) {
return doValid(root, Long.MIN_VALUE, Long.MAX_VALUE);
}
pubic boolean doValid(TreeNode node, Long min, Long max) {
if (node == null) {
return true;
}
if (node.val < min || node.val > max) {
return false;
}
return doValid(node.left, min, node.val) && doValid(node.right, node.val, max);
}
}
Leetcode938
方法一
使用中序遍历
publc class Leetcode938{
public int rangeSumBST(TreeNode root, int low, int high) {
TreeNode p = root;
LinkedList<TreeNode> stack = new LinkedList<>();
int sum = 0;
while (p!=null || !stack.isEmpty()) {
if (p!=null) {
stack.push(p);
p = p.left;
}else {
TreeNode pop = stack.pop();
if (pop.val > high) {
break;
}
if (pop.val >= low && pop.val <= high) {
sum += pop.val;
}
p = pop.right;
}
}
return sum;
}
}
方法二
使用上下限递归
public class Leetcode938{
public int rangeSumBST(TreeNode root, int low, int high) {
return rangeSum(root, low, high);
}
public int rangeSum(TreeNode node, int low, int high) {
if (node == null) {
return 0;
}
if (node.val < low) {
return rangeSum(node.right, low, high);
}
if (node.val > high) {
return rangeSum(node.left, low, high);
}
return rangeSumBST(node.left, low, high); + rangeSumBST(node.right, low, high);
}
}
Leetcode1008
方法一
非递归版本
public class Leetcode1008{
public TreeNode bstFromPreorder(int[] nums) {
TreeNode root = new TreeNode(nums[0]);
for(int i = 1; i < nums.length; i++) {
put(root, nums[i]);
}
return root;
}
public void put(TreeNode node, int val) {
TreeNode pre = null;
while (node != null) {
pre = node;
if (val < node.val) {
node = node.left;
} else {
node = node.right;
}
}
if (pre == null) {
node = new TreeNode(val);
}
if (pre.val > val) {
pre.left = new TreeNode(val);
} else {
pre.right = new TreeNode(val);
}
}
}
方法二
递归版本
public class Leetcode1008{
public TreeNode bstFromPreorder(int[] nums) {
TreeNode root = new TreeNode(nums[0]);
for(int i = 1; i < nums.length; i++) {
put(root, nums[i]);
}
return root;
}
public TreeNode put(TreeNode node, int val) {
if (node == null) {
return new TreeNode(val);
}
if (key < node.val) {
node.left = put(node.left, val);
} else if (key > node.val) {
node.right = put(node.right, val);
}
return node;
}
}
方法三
上下限递归
public class Leetcode1008{
public TreeNode bstFromPreorder(int[] nums) {
return insert(nums, Integer.MAX_VALUE);
}
int i = 0;
public TreeNode insert(int[] nums, int max) {
if (i == nums.length) {
return null;
}
int val = nums[i];
if (val > max) {
return null;
}
TreeNode node = new TreeNode(val);
i++;
node.left = insert(nums, val);
node.right = insert(nums, max);
return node;
}
}
方法四
public class Leetcode1008{
public TreeNode bstFromPreorder(int[] nums) {
partition(nums, 0, nums.length - 1);
}
public TreeNode partition(int[] nums, int start, int end) {
if (start > end) {
return null;
}
TreeNode root = new TreeNode(nums[start]);
int index = start + 1;
while (index <= end) {
if (nums[index] > nums[start]) {
break;
}
index++;
}
root.left = partition(nums, start + 1, index - 1);
root.right = partition(nums, index, end);
return root;
}
}
Leetcode235
二叉树最近公共祖先
public class Leetcode235 {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
TreeNode a = root;
while ((a.val < p.val && a.val < q.val) || (a.val > p.val && a.val > q.val)) {
if (a.val < p.val) {
a = a.left;
} else {
a = a.right;
}
}
return a;
}
}
(start > end) {
return null;
}
TreeNode root = new TreeNode(nums[start]);
int index = start + 1;
while (index <= end) {
if (nums[index] > nums[start]) {
break;
}
index++;
}
root.left = partition(nums, start + 1, index - 1);
root.right = partition(nums, index, end);
return root;
}
}
### Leetcode235
二叉树最近公共祖先
```java
public class Leetcode235 {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
TreeNode a = root;
while ((a.val < p.val && a.val < q.val) || (a.val > p.val && a.val > q.val)) {
if (a.val < p.val) {
a = a.left;
} else {
a = a.right;
}
}
return a;
}
}