二叉排序树

二叉排序树 logn

一、二叉排序树介绍

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

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

要求:一个节点的左子树的值一定小于等于该节点,右子树的值一定大于该节点。

是整个树有序。

如何构建?

链表的构建。

单链表分两个部分: value next

双链表

树在存储的时候肯定是链式存储的方式。

构建有序二叉树实现思路

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

当前必须有一个节点的类,TreeNode

新建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) {
	     TreeNOde  treeNOde5 = new  TreeNOde(5);
         TreeNOde  treeNOde7 = new  TreeNOde(7);
         TreeNOde  treeNOde4 = new  TreeNOde(4);
         TreeNOde  treeNOde2 = new  TreeNOde(2);
         TreeNOde  treeNOde0 = new  TreeNOde(0);
         TreeNOde  treeNOde3 = new  TreeNOde(3);
         TreeNOde  treeNOde1 = new  TreeNOde(1);
         TreeNOde  treeNOde6 = new  TreeNOde(6);
     
     //在构建这样树的过程,树的插入位置由人来判断
     treeNode5.setRightTreeNode(treeNode7);
     treeNode5.setRightTreeNode(treeNode4);
     treeNode4.setRightTreeNode(treeNode2);
     treeNode2.setRightTreeNode(treeNode0);
     treeNode2.setRightTreeNode(treeNode3);
     treeNode0.setRightTreeNode(treeNode1);
     treeNode7.setRightTreeNode(treeNode6);
	  
	}
}

后边再想创建树,不需要再写

public class Test {

	public static void main(String[] args) {
//	     TreeNOde  treeNOde7 = new  TreeNOde(5);
//	     TreeNOde  treeNOde4 = new  TreeNOde(5);
//	     TreeNOde  treeNOde2 = new  TreeNOde(5);
//	     TreeNOde  treeNOde0 = new  TreeNOde(5);
//	     TreeNOde  treeNOde3 = new  TreeNOde(5);
//	     TreeNOde  treeNOde1 = new  TreeNOde(5);
//	     TreeNOde  treeNOde6 = new  TreeNOde(5);
//	     
//	     //在构建这棵树的过程当,树的插入位置是由人来判断的
//	     treeNode5.setRightTreeNode(treeNode7);
//	     treeNode5.setRightTreeNode(treeNode4);
//	     treeNode4.setRightTreeNode(treeNode2);
//	     treeNode2.setRightTreeNode(treeNode0);
//	     treeNode2.setRightTreeNode(treeNode3);
//	     treeNode0.setRightTreeNode(treeNode1);
//	     treeNode7.setRightTreeNode(treeNode6);
		
		 BinaryTree binaryTree = new BinaryTree();
	        binaryTree.insert(5);
	        binaryTree.insert(7);
	        binaryTree.insert(4);
	        binaryTree.insert(2);
	        binaryTree.insert(0);
	        binaryTree.insert(3);
	        binaryTree.insert(1);
	        binaryTree.insert(6);
	        System.out.println();
	}
	  
	}
}
package 二叉树;


/**
 * 有序二叉树的管理类
 */
public class BinaryTree {


    // 新建代表整棵树的节点
    TreeNode root;

    public void insert(Integer value){
        // 新建一个节点
        TreeNode newNode = new TreeNode(value);
        if(root == null){
            root = newNode;
        }else {//10
        	//定义一个指针来遍历这棵树
        	TreeNode currentNode = root;
        	
        	//定义一个指针指向currentNode的上一个位置,目的是方便数据插入
        	TreeNode parentNode;
        	
        	while(true) {
        		parentNode = currentNode;
        		if(newNode.getValue() > currentNode.getValue()) {//向右走
        			currentNode = currentNode.getRightTreeNode();
        			if(currentNode == null) {
        				parentNode.setLeftTreeNode(newNode);
        				return;
        			}else {
        				currentNode = currentNode.getLeftTreeNode();
        				if(currentNode == null) {
        					parentNode.setLeftTreeNode(newNode);
            				return;
        				}
        			}
        		}
        	}
        }
    }


}

解析代码:

画一下内存图 栈内存 堆内存

test的main方法先入栈,按照我们当前的需求,创建了一个叫binaryTree 地址0x1,有一个insert方法,入栈,要先创建节点,

 新建一个NewNode 0x2 ,如果roo==null,指向 0x2

 如何让0x7挂到5的哪边,

 再来一个4,2 ,0

 多了个判断

需要指针,currentNode。

就是尾插法,用一个指针遍历树。

指针往右走,往左走,判断为null的时候就要插入数据,

输出

 

递归方式

构建有序二叉树

递归:方法调用其本身:循环

递归函数:

递归表达式 f(n) = f(n-1) + f(n-2)

递归出口 f(1) = 1,f(2) = 2;

1 1 2 3 5 8 13 21...

public void digui(int n){

if(n==1){

        return 1;

}else if(n==2){

        return 2;

}else{

        return digui(n-1) + digui(n-2);

        }

}

简单回忆一下快速排序:

俩游标移动,

相遇,基准数与相遇的位置的数互换。

重新分成左右两部分,依次进行以上过程。

递归表达式:

递归表达式 f(arr,left,right)

        • f(arr,left,i-1)
        • f(arr,i+1,right)

递归出口 left >= right{

怎么用递归的方式实现一棵树?

递归表达式 function(node)

递归出口 left >= right

之后默写一下快速排序代码 。

有这样一棵树,怎么实现1的插入?

根据递归表达式,判断,要么往左走要么往右走 。

递归表达式:  function(node,value) ---> f(node.right,value)   root代表整个树

                        function(node,value) ---> f(node.left,value)

代码实现:

//当前要对比的子树节点
    public TreeNode insetDigui(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 insetDigui(node.getRightTreeNode(), value);

        } else {
            if (node.getLeftTreeNode() == null) {
                node.setLeftTreeNode(newNode);
                return root;
            }
            return insetDigui(node.getLeftTreeNode(), value);
        }
    }

node最开始指向的节点是5

与node.getValue比较,走else,然后指向4

node不断的指向代表的节点。

继续insert方法,node指向2,还是2大,往左走else,走之前做一个判断,node节点往左边走有没有树,是null的话就不需要走了,往左边一塞就可以。

同理右边也是如此。

递归出口:node.getRightNode() == null

                  node.getLeftNode() == null

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值