【BST树(二叉排序树)】
二叉排序树的本质就是:满足左子节点小于父节点,右子节点大于父节点的树(若有等于情况,我是按添加至右子节点处理的)
这样的树有个优点:中序遍历时输出的数据是按升序排序的。比如上图中序遍历结果:{1,6,9,12,10,16,17,18,25}
核心代码实现:(基础的比如Node类,infixOrder方法等,在这里就不列出了,这里只列举核心功能实现)
【1】Node类中创建add方法,该方法符合BST树建立规则
/**
* 符合BST树建立规则,左子节点小于父节点,右子节点大于父节点
* @param newNode 要添加的结点
*/
public void add(Node newNode){
if (newNode.getData()<this.getData()){//小了往左放
if (this.getLeft()==null){
this.setLeft(newNode);
}else {
this.getLeft().add(newNode);
}
}else {//大了往右放
if (this.getRight()==null){
this.setRight(newNode);
}else {
this.getRight().add(newNode);
}
}
}
【2】Node类创建search方法,该方法按照输入的value,查找拥有相同值的结点,并返回该节点
/**
* 按照输入的value,查找拥有相同值的结点
* @param value 匹配的值
* @return 找到返回结点,否则返回空
*/
public Node search(int value){
if (this.getData()==value){
return this;
}
if (value<this.getData() && this.getLeft()!=null){
return this.getLeft().search(value);
}else if (value>=this.getData() && this.getRight()!=null){
return this.getRight().search(value);
}else {
return null;
}
}
【3】Node类创建searchParent方法,用于返回要查找的结点的父节点。该方法将被delete方法调用
/**
* 按照value,查找到拥有相同值结点的父节点
* @param value 匹配的值
* @return 找到返回父节点,否则返回空
*/
public Node searchParent(int value){
if ((this.left != null && this.left.getData() == value) || (this.right != null && this.right.getData() == value)){
return this;
}
if (value<this.getData() && this.getLeft()!=null){
return this.getLeft().searchParent(value);
}else if (value>=this.getData() && this.getRight()!=null){
return this.getRight().searchParent(value);
}else {
return null;
}
}
【4】BinarySortTree类,创建delete方法与delRightMin方法,用于删除结点。
删除结点有多种情况:
1,树中只有一个结点:root置空
2,删除叶子结点:父节点对左或右子节点置空
3,删除含有左右子树的节点:利用delRightMin方法找到节点右子树中的最小值结点,将其删除,并将其值覆盖到节点中
4,删除只含有一个子树的结点:父节点对其重新设置为该节点的对应非空子节点
public void delete(int value){
if (this.root==null){
System.out.println("空树");
return;
}
Node result=search(value);
if (result==null){
System.out.println("未搜索到");
return;
}
//0.只有一个节点
if (this.root.getLeft()==null && this.root.getRight()==null){
this.root=null;
return;
}
Node parent=searchParent(value);
if (result.getRight()==null && result.getLeft()==null){//1.是叶子结点
if (parent.getRight().getData()==value){
parent.setRight(null);
}else {
parent.setLeft(null);
}
}else if (result.getLeft()!=null && result.getRight()!=null){//2.含有左右子树的结点
int minValue=delRightMin(result.getRight());
result.setData(minValue);
}else {//3.只含有一个子树的结点
if (parent==null){//若是根节点加一个子节点的情况(父节点为空)
if (result.getLeft()!=null){
this.root=result.getLeft();
}else {
this.root=result.getRight();
}
return;
}if (result.getLeft()!=null){//含有左子树
if (parent.getLeft().getData()==value){//目标结点是父节点的左节点
parent.setLeft(result.getLeft());
}else {//目标结点是父节点的右结点
parent.setRight(result.getLeft());
}
}else {//含有右子树
if (parent.getLeft().getData()==value){
parent.setLeft(result.getRight());
}else {
parent.setRight(result.getRight());
}
}
}
}
public int delRightMin(Node node){
Node target = node;
while (target.getLeft()!=null){
target=target.getLeft();
}
delete(target.getData());
return target.getData();
}
完整代码实现:
package cn.dataStructureAndAlgorithm.demo.tree.binarySortTree;
class Node{
private int data;
private Node left;
private Node right;
public Node(int data) {
this.data = data;
}
public void setData(int data) {
this.data = data;
}
public int getData() {
return data;
}
public Node getLeft() {
return left;
}
public Node getRight() {
return right;
}
public void setLeft(Node left) {
this.left = left;
}
public void setRight(Node right) {
this.right = right;
}
@Override
public String toString() {
return "Node{" +
"data=" + data +
'}';
}
/**
* 符合BST树建立规则,左子节点小于父节点,右子节点大于父节点
* @param newNode 要添加的结点
*/
public void add(Node newNode){
if (newNode.getData()<this.getData()){//小了往左放
if (this.getLeft()==null){
this.setLeft(newNode);
}else {
this.getLeft().add(newNode);
}
}else {//大了往右放
if (this.getRight()==null){
this.setRight(newNode);
}else {
this.getRight().add(newNode);
}
}
}
public void infixOrder(){
if (this.left!=null){
this.left.infixOrder();
}
System.out.print(this+" ");
if (this.right!=null){
this.right.infixOrder();
}
}
/**
* 按照输入的value,查找拥有相同值的结点
* @param value 匹配的值
* @return 找到返回结点,否则返回空
*/
public Node search(int value){
if (this.getData()==value){
return this;
}
if (value<this.getData() && this.getLeft()!=null){
return this.getLeft().search(value);
}else if (value>=this.getData() && this.getRight()!=null){
return this.getRight().search(value);
}else {
return null;
}
}
/**
* 按照value,查找到拥有相同值结点的父节点
* @param value 匹配的值
* @return 找到返回父节点,否则返回空
*/
public Node searchParent(int value){
if ((this.left != null && this.left.getData() == value) || (this.right != null && this.right.getData() == value)){
return this;
}
if (value<this.getData() && this.getLeft()!=null){
return this.getLeft().searchParent(value);
}else if (value>=this.getData() && this.getRight()!=null){
return this.getRight().searchParent(value);
}else {
return null;
}
}
}
class BinarySortTree{
private Node root;
public void add(Node node){
if (node==null){
System.out.println("结点为空");
return;
}
if (this.root==null){
this.root=node;
}else{
this.root.add(node);
}
}
public void infixOrder(){
if (this.root==null){
System.out.println("根节点为空");
return;
}
this.root.infixOrder();
}
public Node search(int value){
if (root==null){
System.out.println("空树");
return null;
}
return this.root.search(value);
}
public Node searchParent(int value){
if (this.root==null){
System.out.println("空树");
return null;
}
return this.root.searchParent(value);
}
public void delete(int value){
if (this.root==null){
System.out.println("空树");
return;
}
Node result=search(value);
if (result==null){
System.out.println("未搜索到");
return;
}
//0.只有一个节点
if (this.root.getLeft()==null && this.root.getRight()==null){
this.root=null;
return;
}
Node parent=searchParent(value);
if (result.getRight()==null && result.getLeft()==null){//1.是叶子结点
if (parent.getRight().getData()==value){
parent.setRight(null);
}else {
parent.setLeft(null);
}
}else if (result.getLeft()!=null && result.getRight()!=null){//2.含有左右子树的结点
int minValue=delRightMin(result.getRight());
result.setData(minValue);
}else {//3.只含有一个子树的结点
if (parent==null){//若是根节点加一个子节点的情况(父节点为空)
if (result.getLeft()!=null){
this.root=result.getLeft();
}else {
this.root=result.getRight();
}
return;
}if (result.getLeft()!=null){//含有左子树
if (parent.getLeft().getData()==value){//目标结点是父节点的左节点
parent.setLeft(result.getLeft());
}else {//目标结点是父节点的右结点
parent.setRight(result.getLeft());
}
}else {//含有右子树
if (parent.getLeft().getData()==value){
parent.setLeft(result.getRight());
}else {
parent.setRight(result.getRight());
}
}
}
}
public int delRightMin(Node node){
Node target = node;
while (target.getLeft()!=null){
target=target.getLeft();
}
delete(target.getData());
return target.getData();
}
}
public class 二叉排序树_binarySortTree {
public static void main(String[] args) {
BinarySortTree binarySortTree=new BinarySortTree();
int[] data=new int[]{10,1};//7,3,10,12,5,1,9,0
for (int temp:data){
binarySortTree.add(new Node(temp));
}
binarySortTree.infixOrder();
binarySortTree.delete(10);
System.out.println();
binarySortTree.infixOrder();
}
}
Node{data=0} Node{data=1} Node{data=3} Node{data=5} Node{data=7} Node{data=9} Node{data=10} Node{data=12}
Node{data=0} Node{data=1} Node{data=3} Node{data=5} Node{data=7} Node{data=9} Node{data=12}
有关树结构的其他内容,见下各链接
【数据结构与算法整理总结目录 :>】<-- 宝藏在此(doge)