一、二叉排序树介绍
二叉排序树:对于二叉排序树的任何一个非叶子节点,要求左子节点的值比当前节点的值小,右子节点的值比当前节点的值大。
特别说明:如果有相同的值,可以将该节点放在左子节点或右子节点
二、构建有序二叉树实现思路
- 如果左子树不为空,那么左子树上的所有值都均小于它的根节点的值
- 如果右子树不为空,那么右子树上的所有值都均大于或等于它的根节点的值
- 左,右子树也为二叉排序树
新建TreeNode节点
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
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;
}
}
}
}
}
}
测试类
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);
}
}
三、二叉树的遍历方式
其中前中后序遍历采用了递归的方式进行。
/**
* 中序遍历
*
* @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());
}
}
层序遍历
具体步骤如下:
- 首先申请一个新的队列,记为queue;
- 将头结点head压入queue中;
- 每次从queue中出队,记为node,然后打印node值,如果node左孩子不为空,则将左孩子入队;如果node的右孩子不为空,则将右孩子入队;
- 重复步骤3,直到queue为空。
/**
* 层次遍历
*/
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。
/**
* 数据查找
* @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;
}