/**
* 树节点
*/
public class Node {
private int num;
private Node left;
private Node right;
public Node(int num) {
this.num = num;
this.left = null;
this.right = null;
}
public int getNum() {
return num;
}
public Node getLeft() {
return left;
}
public Node getRight() {
return right;
}
public void setNum(int num) {
this.num = num;
}
public void setLeft(Node left) {
this.left = left;
}
public void setRight(Node right) {
this.right = right;
}
}
/**
* 二叉搜索树
*/
public class TreeNode implements Tree {
private Node root;
public TreeNode() {
this.root = null;
}
public Node getRoot() {
return root;
}
@Override
/**
* 插入操作
*/
public boolean insert(int num) {
Node node = new Node(num);
if(root == null) {
root = node;
return true;
}
Node curNode = root;
Node preNode = root; // 记录前一个节点
while(curNode != null){
if(curNode.getNum() > num){
// 插入值小于当前值, 则找左子树
preNode = curNode;
curNode = curNode.getLeft();
}else if(curNode.getNum() < num){
// 插入值大于当前置, 则找右子树
preNode = curNode;
curNode = curNode.getRight();
}
}
// 循环结束, preNode则为要插入节点的父节点
if(preNode.getNum() > num){
preNode.setLeft(node);
}else if(preNode.getNum() < num){
preNode.setRight(node);
}
return true;
}
@Override
/**
* 删除操作
* 三种情况: 1. 删除没有子节点的节点
* 2. 删除有一个子节点的节点
* 3. 删除有两个子节点的节点
*/
public boolean delete(int num) {
if(root == null){
return false;
}
Node curNode = root;
Node preNode = root;
boolean isLeft = true;
// 寻找要删除的节点
while(curNode.getNum() != num){
preNode = curNode;
if(curNode.getNum() > num){
// 找左子树
curNode = curNode.getLeft();
isLeft = true;
}else if(curNode.getNum() < num){
// 找右子树
curNode = curNode.getRight();
isLeft = false;
}
if(curNode == null){
// 没有找到
return false;
}
}
// 删除节点无子节点
if(curNode.getLeft() == null && curNode.getRight() == null){
if(curNode == root){
root = null;
}else if(isLeft){
preNode.setLeft(null);
}else {
preNode.setRight(null);
}
return true;
}
if(curNode.getLeft() != null && curNode.getRight() == null){
// 删除节点有一个左子节点
if(curNode == root){
root = curNode.getLeft();
}else if(isLeft){
// 当前节点是父节点的左子节点
preNode.setLeft(curNode.getLeft());
}else {
// 当前节点是父节点的右子节点
preNode.setRight(curNode.getLeft());
}
return true;
}else if(curNode.getLeft() == null && curNode.getRight() != null){
// 删除节点有一个右子节点
if(curNode == root){
root = curNode.getRight();
}else if(isLeft){
// 当前节点是父节点的左子节点
preNode.setLeft(curNode.getRight());
}else {
// 当前节点是父节点的右子节点
preNode.setRight(curNode.getRight());
}
return true;
}else {
// 存在两个节点
Node successor = getSuccess(curNode);
if(curNode == root){
root= successor;
}else if(isLeft){
preNode.setLeft(successor);
}else{
preNode.setRight(successor);
}
successor.setLeft(curNode.getLeft());
return true;
}
}
public Node getSuccess(Node delNode){
Node successorParent = delNode;
Node successor = delNode;
Node current = delNode.getRight();
while(current != null){
successorParent = successor;
successor = current;
current = current.getLeft();
}
// 后继节点不是删除节点的右子节点,将后继节点替换删除节点
if(successor != delNode.getRight()){
successorParent.setLeft(successor.getRight());
successor.setRight(delNode.getRight());
}
return successor;
}
@Override
/**
* 查找操作
*/
public Node find(int num) {
Node curNode = root;
while(curNode != null){
if(curNode.getNum() > num){
// 查找值比当前节点值小,查找左子树
curNode = curNode.getLeft();
}else if(curNode.getNum() < num){
// 查找值大于当前节点值,查找右子树
curNode = curNode.getRight();
}else{
// 相等则返回当前节点
return curNode;
}
}
// 遍历后没有找到则返回null
return null;
}
/**
* 删除操作 改
* @param
* @return
*/
public boolean delete2(int num){
Node curNode = root; // 要删除节点,初始化指向根节点
Node preNode = null; // 要删除节点的父节点
while(curNode != null && curNode.getNum() != num){
preNode = curNode;
if(num > curNode.getNum()) curNode = curNode.getRight();
else curNode = curNode.getLeft();
}
// 如果没有找到
if(curNode == null) return false;
// 要删除节点有两个子节点
if(curNode.getLeft() != null && curNode.getRight() != null){
// 找到右子树中最小节点
Node curTemp = curNode.getRight();
Node preTemp = curNode; // 表示curTemp父节点
while(curTemp.getLeft() != null){
preTemp = curTemp;
curTemp = curTemp.getLeft();
}
curNode.setNum(curTemp.getNum());
curNode = curTemp;
preNode = preTemp;
}
// 删除节点是叶子节点
Node child; // p的子节点
if(curNode.getLeft() != null) child = curNode.getLeft();
else if(curNode.getRight() != null) child = curNode.getRight();
else child = null;
if(preNode == null) root = child; // 删除的是根节点
else if(preNode.getLeft() == curNode) preNode.setLeft(child); // 删除节点为其父节 点的左子节点
else preNode.setRight(child); // 删除节点为其父节点的右子节点
return true;
}
@Override
/**
* 中序遍历(从小到大): 左子节点-->当前节点-->右子节点 O(n)
*/
public void inOrder(Node node) {
if(node == null){
return;
}
inOrder(node.getLeft());
System.out.print(node.getNum()+" ");
inOrder(node.getRight());
}
/**
* 最大值
*/
public Node findMax(){
if(root == null) return null;
Node preNode = root;
Node curNode = root;
while(curNode != null){
preNode = curNode;
curNode = curNode.getRight();
}
return preNode;
}
/**
* 最小值
*/
public Node findMin(){
if(root == null){
return null;
}
Node curNode = root;
Node preNode = root;
while(curNode != null){
preNode = curNode;
curNode = curNode.getLeft();
}
return preNode;
}
}