数据结构入门-6-二分搜索树

前几天帮学妹做了封面,可惜我喜欢图一而学妹喜欢图二
在这里插入图片描述
在这里插入图片描述

树结构

二分搜索树

在这里插入图片描述

为什么要用树结构?

在这里插入图片描述
将数据使用树结构存储后,出奇的高效

  • 二分搜索树(Binary Search Tree)
  • 平衡二叉树:AVL;红黑树
  • 堆;并查集
  • 线段数;Trie(字典数,前缀树)

二分搜索树

  • 和链表一样 ,动态数据结构

二叉树(多叉树)

在这里插入图片描述

class Node { 
	E e;
	Node left;
	Node right;
}
  • 二叉树具有唯一的根节点
  • 左孩子 右孩子
  • 二叉树中每个节点最多有两个孩子
  • 叶子节点:没有孩子的节点
  • 二叉树每个节点最多只有一个父亲节点

========================================================

  • 二叉树具有天然的递归结构
    • 左子树 每个节点的左子树也是二叉树
    • 右子树 每个节点的右子树也是二叉树
  • 二叉树不一定是满的
    • 一个节点也可以是二叉树
    • NULL也可以是二叉树

二分搜索树

在这里插入图片描述

  • 二分搜索树是二叉树
  • 二分搜索树的每个节点的值:
    • 大于左子树的所有节点的值
    • 小于右子树所有节点的值
  • 每一颗子树也是二分搜索树

条件

  • 存储的元素具有可比较性
public class BST<E extends Comparable<E>> {

    private class Node {
        public E e;
        public Node left, right;

        public Node(E e) {
            this.e = e;
            left = null;
            right = null;
        }
    }

    private Node root;
    private int size;

    public BST(){
        root = null;
        size = 0;
    }

    public int size(){
        return size;
    }

    public boolean isEmpty(){
        return size == 0;
    }
}

集合

  • 二分搜索树
  • 不能盛放重复的元素
  • 非常好的实现"集合"的底层数据结构
Set<E>
  • void add(E) ---------------->不能添加重复的元素
  • void remove(E)
  • boolean contains(E)
  • int getSize()
  • boolean isEmpty()
public class BST<E extends Comparable<E>> {

    private class Node {
        public E e;
        public Node left, right;

        public Node(E e) {
            this.e = e;
            left = null;
            right = null;
        }
    }

    private Node root;
    private int size;

    public BST(){
        root = null;
        size = 0;
    }

    public int size(){
        return size;
    }

    public boolean isEmpty(){
        return size == 0;
    }

    // 向二分搜索树中添加新的元素e
    public void add(E e){

        if(root == null){
            root = new Node(e);
            size ++;
        }
        else
            add(root, e);
    }

    // 向以node为根的二分搜索树中插入元素e,递归算法
    private void add(Node node, E e){
        if(e.equals(node.e))
            return;
        else if(e.compareTo(node.e) < 0 && node.left == null){
            node.left = new Node(e);
            size ++;
            return;
        }
        else if(e.compareTo(node.e) > 0 && node.right == null){
            node.right = new Node(e);
            size ++;
            return;
        }

        if(e.compareTo(node.e) < 0)
            add(node.left, e);
        else //e.compareTo(node.e) > 0
            add(node.right, e);
    }
}

改进添加操作 深入理解递归

向以node为根的二分搜索树中插入元素e,递归算法

//返回插入新节点后二分搜索树的根
    private Node add(Node node, E e){
        if(node == null){
            size ++;
            return new Node(e);
        }

        if(e.compareTo(node.e) < 0)
            node.left = add(node.left, e);
        else if(e.compareTo(node.e) > 0)
            node.right = add(node.right, e);
            
        return node;

// 看以node为根的二分搜索树中是否包含元素e, 递归算法

    // 看以node为根的二分搜索树中是否包含元素e, 递归算法
    private boolean contains(Node node, E e){

        if(node == null)
            return false;

        if(e.compareTo(node.e) == 0)
            return true;
        else if(e.compareTo(node.e) < 0)
            return contains(node.left, e);
        else // e.compareTo(node.e) > 0
            return contains(node.right, e);
    }

二分搜索树的前序遍历

    // 二分搜索树的前序遍历
    public void preOrder(){
        preOrder(root);
    }

    // 前序遍历以node为根的二分搜索树, 递归算法
    private void preOrder(Node node){
        if(node == null)
            return;

        System.out.println(node.e);
        preOrder(node.left);
        preOrder(node.right);
    }

    @Override
    public String toString(){
        StringBuilder res = new StringBuilder();
        generateBSTString(root, 0, res);
        return res.toString();
    }

    // 生成以node为根节点,深度为depth的描述二叉树的字符串
    private void generateBSTString(Node node, int depth, StringBuilder res){

        if(node == null){
            res.append(generateDepthString(depth) + "null\n");
            return;
        }

        res.append(generateDepthString(depth) + node.e + "\n");
        generateBSTString(node.left, depth + 1, res);
        generateBSTString(node.right, depth + 1, res);
    }

    private String generateDepthString(int depth){
        StringBuilder res = new StringBuilder();
        for(int i = 0 ; i < depth ; i ++)
            res.append("--");
        return res.toString();
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_39381833/article/details/89444635