二叉排序树(Binary Sort Tree)
1.二叉排序树定义(摘自百度百科)
一棵空树,或者是具有下列性质的二叉树:
(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;
(3)左、右子树也分别为二叉排序树;
简单说,就是这样的二叉树上的值:
右子树>根节点>左子树。
所以在进行二叉树的中序遍历(左->根->右)的时候,输出的值会按照从小到大排列。
2.二叉排序树的图示
一下内容我会按照图和代码一起来说,如果只想看代码,可以跳过,其中今天晚上我突然想明白了二叉排序树的一些操作,所以我感觉有必要把它记录下来
1)构建一个二叉排序树
将数组arr[]={5,4,1,7,8,6},作为实验用例:
class Node{
int val;
Node left;
Node right;
public Node(int val) {
this.val = val;
}
//递归添加节点
public void add(Node node){
if (node==null){
return;
}
if (node.val<this.val){
if (this.left==null){
this.left=node;
}else{
this.left.add(node);
}
}else{
if(this.right==null){
this.right=node;
}else{
this.right.add(node);
}
}
}
}
class BinartSortTree{
private Node root;
public void add(Node node){
if (root==null){
root=node;
}else{
root.add(node);
}
}
}
中序遍历后的结果:
2)节点的删除
这部分应该算是二叉排序树的难点之一了
//找到删除目标节点和其父节点
public Node search(int value){
if (root==null){
return null;
}else{
return root.search(value);
}
}
public Node searchParent(int value){
if (root==null){
return null;
}else{
return root.searchParent(value);
}
}
情况2,如下图
//含有左节点
if(targetNode.left!=null){
if (parent!=null) {//根节点
if (parent.left.val == value) {
parent.left = targetNode.left;
} else {
parent.right = targetNode.left;
}
}else{
root=targetNode.left;
}
}else{
if (parent!=null) {
//含有右节点
if (parent.left.val == value) {
parent.left = targetNode.right;
} else {
parent.right = targetNode.right;
}
}else{
root=targetNode.right;
}
}
情况3,如下图
if (targetNode.left!=null&&targetNode.right!=null){//删除的节点含有两个子节点
int i = delLeftMax(targetNode);
targetNode.val=i;
}
//删除双子叶节点,之左边最大值
public int delLeftMax(Node node){
Node temp=node;
while (temp.right!=null){
temp=temp.right;
}
int a=temp.val;
//找到后删除左边最大节点,且此节点肯定为叶子节点
delNode(temp.val);
return a;
}
3.代码汇总
public class BinartSortTree {
public static void main(String[] args) {
int[] arr={5,4,1,7,8,6};
BinartSortTree binartSortTree = new BinartSortTree();
for (int i = 0; i < arr.length; i++) {
binartSortTree.add(new Node(arr[i]));
}
binartSortTree.infixOrder();
System.out.println("*********************************");
binartSortTree.delNode(5);
binartSortTree.infixOrder();
}
}
class BinartSortTree{
private Node root;
public void add(Node node){
if (root==null){
root=node;
}else{
root.add(node);
}
}
public void infixOrder(){
if (root!=null){
root.infixOrder();
}else{
System.out.println("null");
}
}
/**
*以下为删除节点的操作
*/
//首先要找到删除节点和其父母节点
public Node search(int value){
if (root==null){
return null;
}else{
return root.search(value);
}
}
public Node searchParent(int value){
if (root==null){
return null;
}else{
return root.searchParent(value);
}
}
//删除节点
public void delNode(int value){
if (root==null){
return;
}else{
//找到该节点和它的父节点
Node targetNode=search(value);
if (targetNode==null){
return;
}
Node parent = searchParent(value);
if (targetNode.left==null&&targetNode.right==null){//删除叶子节点
if (parent.right!=null&&parent.right.val==value){//这里如果不判断空,可能会出现空指针异常
parent.right=null;
}else{
parent.left=null;
}
}else if (targetNode.left!=null&&targetNode.right!=null){//删除的节点含有两个子节点
int i = delLeftMax(targetNode);
targetNode.val=i;
}else {//删除的节点含有一个节点
//含有左节点
if(targetNode.left!=null){
if (parent!=null) {//根节点
if (parent.left.val == value) {
parent.left = targetNode.left;
} else {
parent.right = targetNode.left;
}
}else{
root=targetNode.left;
}
}else{
if (parent!=null) {
//含有右节点
if (parent.left.val == value) {
parent.left = targetNode.right;
} else {
parent.right = targetNode.right;
}
}else{
root=targetNode.right;
}
}
}
}
}
//删除双子叶节点,之左边最大值
public int delLeftMax(Node node){
Node temp=node;
while (temp.right!=null){
temp=temp.right;
}
int a=temp.val;
//找到后删除左边最大节点,且此节点肯定为叶子节点
delNode(temp.val);
return a;
}
}
class Node{
int val;
Node left;
Node right;
public Node(int val) {
this.val = val;
}
//递归添加节点
public void add(Node node){
if (node==null){
return;
}
if (node.val<this.val){
if (this.left==null){
this.left=node;
}else{
this.left.add(node);
}
}else{
if(this.right==null){
this.right=node;
}else{
this.right.add(node);
}
}
}
//中序遍历的方法(左根右)
public void infixOrder() {
//左子树
if (this.left != null) {
this.left.infixOrder();
}
//先输出父节点
System.out.println(this);
//右子树
if (this.right != null) {
this.right.infixOrder();
}
}
//查找删除的节点
public Node search(int value){
if (this.val==value){
return this;
}else if(value<this.val){
if (this.left==null){
return null;
}
return this.left.search(value);
}else {
if (this.right==null){
return null;
}
return this.right.search(value);
}
}
//找到删除节点的父节点
public Node searchParent(int value){
if ((this.left!=null&&this.left.val==value)||(this.right!=null&&this.right.val==value)){
return this;
}else{
if (value<this.val&&this.left!=null){
return this.left.searchParent(value);
}else if (value>this.val&&this.right!=null){
return this.right.searchParent(value);
}else{
return null;
}
}
}
@Override
public String toString() {
return "Node{" +
"val=" + val +
'}';
}
}