树--构建二叉排序树

一、二叉排序树介绍

二叉排序树:对于二叉排序树的任何一个非叶子节点,要求左子节点的值比当前节点的值小,右子节点的值比当前节点的值大。

特别说明:如果有相同的值,可以将该节点放在左子节点或右子节点

二、构建有序二叉树实现思路

  • 如果左子树不为空,那么左子树上的所有值都均小于它的根节点的值
  • 如果右子树不为空,那么右子树上的所有值都均大于或等于它的根节点的值
  • 左,右子树也为二叉排序树

新建TreeNode节点

java 复制代码
public class TreeNode {
	
	private TreeNode leftTreeNode;  //左子树
	private TreeNode rightTreeNode; //右子树
	private Integer value;           //值
	
	public TreeNode(Integer value) {
		super();
		this.value = value;
	}
	
	public TreeNode getLeftTreeNode() {
		return leftTreeNode;
	}
	public void setLeftTreeNode(TreeNode leftTreeNode) {
		this.leftTreeNode = leftTreeNode;
	}
	public TreeNode getRightTreeNode() {
		return rightTreeNode;
	}
	public void setRightTreeNode(TreeNode rightTreeNode) {
		this.rightTreeNode = rightTreeNode;
	}
	public Integer getValue() {
		return value;
	}
	public void setValue(Integer value) {
		this.value = value;
	}
	
	@Override
	public String toString() {
		return "TreeNode [leftTreeNode=" + leftTreeNode + ", rightTreeNode=" + rightTreeNode + ", value=" + value + "]";
	}

}

新建BinaryTree

java 复制代码
public class BinaryTree {

    //新建二叉树
    TreeNode root;

    //获取二叉树的数据
    public TreeNode getRoot() {
        return root;
    }
    
    /**
 *                           f(node,value) --> f(node.right,value)
 * if(node.value > value) :
 *                          node.getRightTreeNode() == null
 *
 *                           f(node,value) --> f(node.left,value)
 * if(node.value < value) :
 *                           node.getRightTreeNode() == null
 *
 * @param value
 * @return
 */
public TreeNode insertdigui(TreeNode node, Integer value){
    //  新建一个节点

    TreeNode newNode = new TreeNode(value);

    if(root == null){
        return root = newNode;
    }

    if(newNode.getValue() > node.getValue()){
        if(node.getRightTreeNode() == null){
            node.setRightTreeNode(newNode);
            return root;
        }
        return insertdigui(node.getRightTreeNode(),value);
    }else {
        if(node.getLeftTreeNode() == null){
            node.setLeftTreeNode(newNode);
            return root;
        }
        return insertdigui(node.getLeftTreeNode(),value);
    }

}


    /**
     * 构建有序二叉树
     * @param value
     */
    public void insert(Integer value) {
        //  新建一个节点
        TreeNode newNode = new TreeNode(value);
        if (root == null) {
            root = newNode;
        } else {
            // 定义一个指针用来遍历二叉树
            TreeNode currentNode = root;
            //定义这个指针的目的是:记录currentNode的前一个位置
            TreeNode parentNode;
            // 有孩子继续循环,一直循环到最后一个节点 和插入的节点比较
            // 大的放到右节点,小于放到左节点
            while (true) {
                //记录currentNode
                parentNode = currentNode;
                // 往右放
                if (newNode.getValue() > currentNode.getValue()) {
                    currentNode = currentNode.getRightTreeNode();
                    if (currentNode == null) {
                        parentNode.setRightTreeNode(newNode);
                        return;
                    }
                } else {
                    // 往左放
                    currentNode = currentNode.getLeftTreeNode();
                    if (currentNode == null) {
                        parentNode.setLeftTreeNode(newNode);
                        return;
                    }
                }
            }
        }
    }
}

测试类

java 复制代码
public class Test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
	    BinaryTree tree = new BinaryTree();
	    tree.insert(5);
	    tree.insert(7);
	    tree.insert(4);
	    tree.insert(8);
	    tree.insert(6);
	    tree.insert(2);
	    tree.insert(3);
	    tree.insert(9);
	    System.out.println(tree.root);
	  
	}
}

三、二叉树的遍历方式

其中前中后序遍历采用了递归的方式进行。

java 复制代码
/**
	 * 中序遍历
	 * 
	 * @param treeNode
	 */
	public void inOrder(TreeNode treeNode) {
	    if (treeNode != null) {
	        inOrder(treeNode.getLeftTreeNode());
	        System.out.print(" " + treeNode.getValue() + " ");
	        inOrder(treeNode.getRightTreeNode());
	    }
	}

	/**
	 * 后序遍历
	 * 
	 * @param treeNode
	 */
	public void afterOrder(TreeNode treeNode) {
	    if (treeNode != null) {
	        afterOrder(treeNode.getLeftTreeNode());
	        afterOrder(treeNode.getRightTreeNode());
	        System.out.print(" " + treeNode.getValue() + " ");
	    }
	}

	/**
	 * 先序遍历
	 * 
	 * @param treeNode
	 */
	public void beforeOrder(TreeNode treeNode) {
	    if (treeNode != null) {
	        System.out.print(" " + treeNode.getValue() + " ");
	        beforeOrder(treeNode.getLeftTreeNode());
	        beforeOrder(treeNode.getRightTreeNode());
	    }
	}
 
 

层序遍历

具体步骤如下:

  1. 首先申请一个新的队列,记为queue;
  2. 将头结点head压入queue中;
  3. 每次从queue中出队,记为node,然后打印node值,如果node左孩子不为空,则将左孩子入队;如果node的右孩子不为空,则将右孩子入队;
  4. 重复步骤3,直到queue为空。
java 复制代码
	/**
	 * 层次遍历
	 */
	public  void levelOrder(){
        LinkedList<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        while(!queue.isEmpty()){
            root = queue.pop();
            System.out.print(root.getValue() + " ");
            if(root.getLeftreeNode() !=null) {
            	queue.add(root.getLeftreeNode());
            }
            if (root.getRigthTreeNode() !=null) {
            	 queue.add(root.getRigthTreeNode());
			}
        }
    }

四、二叉树的查找

1.定义一个指针指向根节点,如果指针指向的节点不等于我们的值,那么我们就一直循环去寻找。

2.指针指向的数据和我们要查找的值进行比较,如果我们查找的数据比当前值小,指针指向当前节点的左孩子

如果我们查找的数据比当前值大,指针指向当前节点的右孩子

3.如果没有找打那么就返回 null。

java 复制代码
	/**
	 *  数据查找
	 * @param value
	 * @return
	 */
	public TreeNode find(int value) {
		//定义一个指针指向根节点
		TreeNode currentNode = root;
		
		while (currentNode.getValue() != value) {
			if(value < currentNode.getValue()) {
				currentNode = currentNode.getLeftreeNode();
			}else {
				currentNode = currentNode.getRigthTreeNode();
			}
			 if( currentNode == null ) {
				 return null;
			 }
		}
		return currentNode;
		
	}
相关推荐
JAVA面经实录91731 分钟前
MyBatis学习体系
java·mybatis
java1234_小锋34 分钟前
在 Spring AI 中如何实现函数调用(Function Calling)?请说明其基本原理和应用场景。
java·人工智能·spring
小马爱打代码1 小时前
Spring源码 第九篇:Spring 5 源码深度拆解 - Spring 事件驱动模型
java·后端·spring
ForgeAI码匠2 小时前
ForgeAdmin|Spring Boot 3 后台框架的自动配置设计:少写配置,多做组合
java·spring boot·后端
tongluowan0072 小时前
Redisson的参数及工作原理
java·redis·lua·分布式锁
仙俊红2 小时前
Integer\int对比,equals()\hashcode面试
java·面试·职场和发展
WiChP3 小时前
【V0.1B10】从零开始的2D游戏引擎开发之路
java·数据库·游戏引擎
云烟成雨TD3 小时前
Spring AI Alibaba 1.x 系列【60】检查点机制原理与全流程剖析
java·人工智能·spring
ForgeAI码匠3 小时前
Maven 多模块项目如何避免越写越乱?Forge Admin 的模块边界实践
java·人工智能·开源·maven
z落落3 小时前
C# 数组 最终完整版全套笔记(一维+多维+交错+引用类型+对象数组)
java·笔记·c#