二叉排序树的创建,添加, 遍历操作的实现(代码实现)
我们要先创建一个Node类(然后再Node类中创建递归的添加和遍历的方法)
//首先我们先来创建一个Node结点类, 我们创建一个Node结点类之后在Node结点类中实现两个递归方法, 一个方法是递归来增加结点的方法, 一个是来递归遍历的方法
class Node{
int value;
Node left;
Node right;
public Node(int value){
this.value = value;
}
//添加结点的方法
//递归的形式添加结点, 注意: 需要满足是二叉排序树的需求
/**
* @param node 这个node是待添加的结点
*/
public void add(Node node){
//这个递归方法我们每次递归的时候是改变的方法的调用者
//1.判断入参
// 注意: 这个时候只是我们对入参的判断 , 并不是递归的结束条件
if(node == null){//如果待添加结点是一个null的时候那么我们就不用添加这个节点了, 直接就退出就可以了
return; //由于此时我们实现的递归方法是没有返回值的, 所以这个时候我们我们直接退出就可以了
}
//如果node的值不为空, 那么就说明这个节点是合法的, 所以我们就要来判断这个节点要添加的位置
if(node.value < this.value) {//如果这个时候node节点的value值要小于我们的this的value的值, 那么我们肯定是要去左子树上继续查找, 所以这个时候我们就要使用左子节点来递归调用此方法
if(this.left != null){
//如果当前节点的左子节点不为空的时候此时我们才继续向左子树去遍历,如果这个时候左子节点为空了, 那么就表明这个位置其实我们是已经找到了
this.left.add(node);
}else{
//如果当前节点的左子节点为空, 那么就证明这个位置就是我们节点要添加的位置, 我们此时就就将我们的节点直接放到当前节点的左子节点的位置即可
this.left = node;
}
}else { //如果node的值(也就是待添加结点的值大于或者是等于我们当前节点的value值的时候我们就要向右子树上进行遍历)
// 这个时候一定要注意: 我们此时如果等于的时候也是向右子树去查找位置了, 就说明最后的时候我们如果两个结点的值是一样大的, 那儿我们将这个节点添加到了右子树上
// 对应的如果执行其他的二叉排序树的操作的时候如果我们要判断两个值相同的情况的时候我们就要去右子树上去看
if(this.right != null) {
//判断当前节点的右子节点是否为null ,如果不为空的时候我们就递归的向右子树进行一个遍历
this.right.add(node);
}else{
//如果此时当前节点的右子节点为空了,那么就表示我们找到了待插入节点的插入位置, 我们直接将我们的待插入节点插入即可
this.right = node;
}
}
}
//中序遍历(注意: 我们的二叉排序树的中序遍历之后的结果是一个有序序列, 如果这个时候我们构建的二叉排序树使用中序遍历之后的结果是一个有序的序列的时候我们就说明我们这个二叉排序树是没有问题的)
// 注意:我们此时的中序遍历只是为了判断我们的当前的二叉排序树的创建和添加元素的方法是否是正确的
//因为此时我们的二叉排序树的中序遍历的方法是编写到了Node结点类中, 所以其实执行递归调用的时候改变的是这个遍历方法的调用者
public void infixOrder(){
//此递归方法中我们并没有将递归终止条件写明, 这个方法时没有返回值的, 所以我们这里采用的方式是如果满足递归条件的时候我们才执行递归操作,
//如果不满足递归条件的时候我们就直接执行完了, 因为这个方法中没有任何是需要执行的
if(this.left != null) {
//递归的向左判断
this.left.infixOrder();
}
//输出当前元素
System.out.println(this.value);
if(this.right != null) {
//递归的向右判断
this.right.infixOrder();
}
}
}
然后我们给出我们编写好的二叉排序树类:
/**
* 创建一个二叉排序树类,在二叉排序树类中向外提供添加元素和遍历的方法
*/
public class BinarySortTree {
//声明当前二叉排序树类的根节点
private Node root;
//创建添加元素的方法
public void add(Node node){
//这个时候我们要使用root引用数据来调用add()方法, 此时我们就要在调用方法之前判断当前的root引用是否为空, 要做一个合法性判断
if(root != null){
root.add(node);
}else{
//如果根节点为空的时候就直接将这值副给根节点即可
root = node;
}
}
//中序遍历方法
public void infixOrder(){
//这个时候同样我们也是要使用root引用数据来调用方法, 所以我们就要判断这个root引用是否为空
if(root != null){
root.infixOrder();
}else{
//如果这个root值不为空的时候就直接退出即可,顺便可以打印一个提示信息
System.out.println("当前链表为空~~~");
return;
}
}
}
最后给出测试方法:
/**
* 测试方法, 测试我们编写的二叉排序树类中的方法是否是正确的
* @param args
*/
public static void main(String[] args) {
//创建一个二叉排序树类
BinarySortTree binarySortTree = new BinarySortTree();
//我们先创建几个结点
Node node1 = new Node(2);
Node node2 = new Node(31);
Node node3 = new Node(42);
Node node4 = new Node(1);
Node node5 = new Node(1);
Node node6 = new Node(24);
Node node7 = new Node(12);
//然后调用我们添加结点的方法将我们节点添加到我们的二叉排序树类中
binarySortTree.add(node1);
binarySortTree.add(node2);
binarySortTree.add(node3);
binarySortTree.add(node4);
binarySortTree.add(node5);
binarySortTree.add(node6);
binarySortTree.add(node7);
//调用中序遍历方法进行一个测试
binarySortTree.infixOrder();
}
补充:
这篇文章中我们都是将递归操作编写到了我们的二叉树结点类中, 编写到了结点类之后由于我们方法的调用者就是结点对象, 所以我们就不需要通过参数来实现递归, 我们直接就使用方法的调用者的变化来完成我们的递归实现