我们在原有的树的数据结构做了一些调整,以便我们构造二叉排序树。(差别请对比我的上个博客)。
因为我们在构造二叉排序树的时候,需要明确根的概念,所以需要新建一个类需要引用我们原有的TreeNode
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
public TreeNode(int x) { val = x; }
public int getVal() {
return val;
}
public TreeNode getLeft() {
return left;
}
public TreeNode getRight() {
return right;
}
public void setVal(int val) {
this.val = val;
}
public void setLeft(TreeNode left) {
this.left = left;
}
public void setRight(TreeNode right) {
this.right = right;
}
}
下面我们借助这个基础的TreeNode,开始写我们的BinaryTree类
public class BinaryTree {
/*
根节点
*/
public static TreeNode root = null;
/*
删除结点的父亲结点
*/
public static TreeNode parentNode = null;
/**
* 构二叉排序树
* @param value
*/
public void insertNode(Integer value){
//指向
TreeNode node = root;
//插入结点
TreeNode pre = null;
while (node!=null){
pre = node;
if(value< node.getVal()){
node = node.getLeft();
}
else if(value>node.getVal()){
node = node.getRight();
}
else {
return;
}
}
if(root==null){
root = new TreeNode(value);
}
else {
if(value<pre.getVal()){
pre.setLeft(new TreeNode(value));
}
else {
pre.setRight(new TreeNode(value));
}
}
}
/**
* 中序输出
* @return 中序的list
*/
public List<Integer> inorderTraversal(){
Stack<TreeNode> treeNodeStack = new Stack<>();
List<Integer> list =new ArrayList<>();
TreeNode node = root;
while (node!=null||!treeNodeStack.isEmpty()){
while (node!=null){
treeNodeStack.push(node);
node = node.getLeft();
}
node = treeNodeStack.pop();
list.add(node.getVal());
node = node.getRight();
}
return list;
}
/**
* 查找特定的值
*/
public boolean search(Integer value){
TreeNode node = root;
while (node!=null){
if(node.getVal() == value){
return true;
}
else if(value<node.getVal()){
node = node.getLeft();
}
else {
node = node.getRight();
}
}
return false;
}
public void delect(Integer value){
delectNode(root,value);
}
public boolean delectNode(TreeNode treeNodeNode, Integer value){
TreeNode node = treeNodeNode;
//null值直接返回
if(node==null) return false;
else {
if(node.getVal()==value){
//找到删除结点
return delectNodeData(node,value);
}
else if(value<node.getVal()){
//记录删除节点的双亲结点
parentNode = node;
//左子树遍历
return delectNode(node.getLeft(),value);
}
else {
//同上
parentNode = node;
return delectNode(node.getRight(),value);
}
}
}
public boolean delectNodeData(TreeNode node,Integer value){
//左子树为空
if(node.getLeft()==null){
if(parentNode!=null){
//删除结点为双亲的左子树
if(value<parentNode.getVal()){
parentNode.setLeft(node.getRight());
}
else {
parentNode.setRight(node.getRight());
}
}
//双亲结点为空,删除的是根节点
else {
root = node.getRight();
}
}
//右子树为null
else if(node.getRight()==null){
if(parentNode!=null){
if(value<parentNode.getVal()){
parentNode.setLeft(node.getLeft());
}
else {
parentNode.setRight(node.getLeft());
}
}
else {
root = node.getLeft();
}
}
//左右子树都不为空 找左子树的最大结点
else {
//找左子树的最大值代替当前节点的值 值替代
//取前驱结点 ,先转左,然后一直到最右
TreeNode pre = node;
TreeNode delectNode = node.getLeft();
while (delectNode.getRight()!=null){
pre = delectNode;
delectNode = delectNode.getRight();
}
//保存最大值结点
TreeNode temp = delectNode;
//父亲结点置空
//删除结点是双亲的左子树还是右子树
if(delectNode.getVal() == pre.getRight().getVal()){
pre.setRight(null);
}
else {
pre.setLeft(null);
}
//设值
node.setVal(temp.getVal());
}
return true;
}
}
这是我写的测试类如下图所示
public static void main(String[] args) {
BinaryTree binaryTree = new BinaryTree();
binaryTree.insertNode(6);
binaryTree.insertNode(1);
binaryTree.insertNode(3);
binaryTree.insertNode(2);
binaryTree.insertNode(4);
binaryTree.insertNode(7);
binaryTree.insertNode(9);
binaryTree.insertNode(8);
System.out.println(binaryTree.search(8));
System.out.println(binaryTree.search(5));
binaryTree.delect(7);
binaryTree.delect(3);
System.out.println(binaryTree.inorderTraversal());
}