当前位置: 首页 > 图灵资讯 > 技术篇> java 二叉查找树 java实现二叉搜索树

java 二叉查找树 java实现二叉搜索树

来源:图灵教育
时间:2023-05-16 09:32:25

通过改造链表,可以建造一棵二叉树。

本文利用java实现二叉搜索树,实现二叉树的新增、删除、搜索等功能。并测试新的和搜索的时间复杂性。

节点类似于链表节点,将链表前后节点定义逻辑改为左右(儿童)节点:

/** * 二叉搜索树节点 */public class Node{    private int data;//数据域    private Node left;///左节点(左孩子)    private Node right;///右节点(右孩子)    public int getData() {        return data;    }    public void setData(int data) {        this.data = data;    }    public Node getLeft() {        return left;    }    public void setLeft(Node left) {        this.left = left;    }    public Node getRight() {        return right;    }    public void setRight(Node right) {        this.right = right;    }    //构造函数    public Node(int data, Node left, Node right){        this.data = data;        this.left = left;        this.right = right;    }    public Node(int data){        this(data,null,null);    }    public Node(){        this(0,null,null);    }}

实现二叉搜索树:

1 /** 2 * 二叉搜索树 3 * Author:hangwei 4 * Date:2022/11 5 */ 6 public class SearchTree { 7 private Node root; 8 public Node getRoot() { 9 return root;10 }11 public void setRoot(Node root) {12 this.root = root;13 }14 15 ///找出树上是否有一个值16 public Node search(Node root,int val){17 int nums = 0;18 while (root != null && root.getData() != val){19 if(val < root.getData()/位于左子树2000左子树 root = root.getLeft();//缩小范围21 else22 root = root.getRight();23 nums++;24 }25 System.out.println("这次搜索执行:"+nums+"次");26 return root;27 }28 29 int addCount = 0;30 ///给树增加31个节点 public void Add(Node root,int val){32 if(val == 30)33 addCount++;34 if(root == null) {35 setRoot(new Node(val));36 }37 else {38 if(val < root.getData()){39 if(root.getLeft() == null)///左子树新增40棵 root.setLeft(new Node(val));41 else42 Add(root.getLeft(),val);///缩小子树范围,递归43 }44 else {45 if(root.getRight() == null)///右子树空新增46棵 root.setRight(new Node(val));47 else48 Add(root.getRight(), val);49 }50 ///验证插入时间复杂度51 if(root.getRight()!=null && root.getRight().getData() == 30)52 System.out.println(”本次新增节点30实施:"+addCount+" 次");53 }54 55 }56 public Node delete(Node root,int val){57 if(root == null)58 return root;59 if(root.getData() == val){//找到节点60 if(root.getLeft() == null && root.getRight() ==null){//1,左右子节点为空,直接返回空气61 return null;62 } else if (root.getLeft() == null) {//2,左儿童节点为空,右儿童节点63 return root.getRight();64 } else if (root.getRight() == null) {//3,右儿童节点为空,左儿童节点65 return root.getLeft();66 }67 else {//4,孩子节点左右不空68 Node cur = root.getRight();69 while (cur.getLeft() !=null)//如果右节点有孩子节点,左孩子不会空70 cur = cur.getLeft();///找到右节点最小的左孩子71 cur.setLeft(root.getLeft());//因为目标节点被删除的右子树总是比左子树大,所以找到右子树最小的左孩子,左子树72,目标节点是设置最小左子树的左子树 return root.getRight();73 }74 }75 else if(val < root.getData()//处理左子树766 root.setLeft(delete(root.getLeft(),val));77 else/处理右子树78 root.setRight(delete(root.getRight(),val));79 return root;80 }81 }

View Code

测试类:

import java.util.*;public class Main {    public static void main(String[] args) {        /**         * 假设有二叉搜索树,总结点树为n,高度为h,根节点高度为1,假设也是满二叉树,         * n与h的关系:n=2^h - 1;(极端情况n=h暂时不考虑退化到链表)         * 即:h=log2^(n+1)         */        ///二叉搜索树测试        SearchTree st = new SearchTree();        ///插入节点&验证插入时间的复杂性        st.Add(null,25);        st.Add(st.getRoot(),18);        st.Add(st.getRoot(),16);        st.Add(st.getRoot(),19);        st.Add(st.getRoot(),29);        st.Add(st.getRoot(),27);        st.Add(st.getRoot(),30);        //输出树        System.out.println(Arrays.toString(levelOrder(st.getRoot())));        //查找        System.out.println(st.search(st.getRoot(),27).getData());        System.out.println(st.search(st.getRoot(),30).getData());        System.out.println(st.search(st.getRoot(),31));        ////验证搜索时间的复杂性        ///删除节点        st.delete(st.getRoot(),30);        ///再次输出树木        System.out.println(Arrays.toString(levelOrder(st.getRoot())));        ///删除节点        st.delete(st.getRoot(),18);        ///再次输出树木        System.out.println(Arrays.toString(levelOrder(st.getRoot())));    }    /**     * 层序遍历     * @param root     * @return     */    public static int[] levelOrder(Node root) {        if(root == null){            return new int[0];        }        Queue<Node> queue = new LinkedList<Node>();        queue.add(root);        ArrayList<Integer> arr = new ArrayList<>();        while( !queue.isEmpty() ){            Node temp = queue.poll();            arr.add(temp.getData());            if(temp.getLeft() != null){                queue.add(temp.getLeft());            }            if(temp.getRight() != null){                queue.add(temp.getRight());            }        }        int[] res = new int[arr.size()];        for(int i = 0;i < arr.size();i++){            res[i] = arr.get(i);        }        return res;    }}

执行结果:

java 二叉查找树 java实现二叉搜索树_二叉搜索树_03

 

 

*重点:

1.双向链表可转化为二叉树;

二、二叉搜索树定义:左子树小于根节点,右子树大于根节点,左子树和右子树一样符合这一定义;

3.新增、搜索、删除方法中无处不在的递归思路;

4.层序遍历和时间复杂度验证。