美文网首页
二叉查找树

二叉查找树

作者: 水欣 | 来源:发表于2018-02-27 17:53 被阅读0次

简介

二叉查找树(Binary Search Tree),又被成为二叉搜索树。
它是特殊的二叉树:对于二叉树,假设x为二叉树中的任意一个节点,x节点包含关键字key,节点x的key值记为key[x]。如果y是x的左子树中的一个节点,则key[y]<key[x];如果y是x的右子树的一个节点,则key[y]>key[x]。那么,这棵树就是二叉查找树。如图


image.png

在二叉查找树中:

  1. 若任意节点的左子树不空,则左子树上所有节点的值均小于他的根节点的值;
  2. 若任意节点的右子树不空,则右子树上所有节点的值均大于它的根节点的值;
  3. 任意节点的左、右子树也分别为二叉查找树;
  4. 没有键值相等的节点。

遍历

这里讲解前序遍历、中序遍历和后续遍历3中方式。

  1. 前序遍历
    若二叉树非空,则执行以下操作:
  • 访问根节点
  • 先序遍历左子树
  • 先序遍历右子树
  1. 中序遍历
    若二叉树非空,则执行以下操作:
  • 中序遍历左子树
  • 访问根节点
  • 中序遍历右子树
  1. 后序遍历
    若二叉树非空,则执行以下操作:
  • 后序遍历左子树
  • 后序遍历右子树
  • 访问根节点
public class Node {

    public int key;
    public int value;
    public Node leftChild;
    public Node rightChild;

    public Node(int key, int value) {
        this.key = key;
        this.value = value;
    }
}

public class Tree {

    private Node root; //保存树的根

    /**
     * 查找指定节点
     */
    public Node find(int key) {
        Node currentNode = root;
        while (null != currentNode && currentNode.key != key) {
            if (key < currentNode.key) {
                currentNode = currentNode.leftChild;
            } else {
                currentNode = currentNode.rigthChild;
            }
        }
        return currentNode;
    }

    /**
     * 插入节点
     */
    public void insert(int key, int value) {
        if (null == root) {
            root = new Node(key, value);
            return;
        }

        Node currentNode = root;
        Node parentNode = root;
        boolean isLeftChild = true;
        while (currentNode != null) {
            parentNode = currentNode;
            if (key < currentNode.key) {
                currentNode = currentNode.leftChild;
                isLeftChild = true;
            } else {
                currentNode = currentNode.rigthChild;
                isLeftChild = false;
            }
        }

        Node newNode = new Node(key, value);
        if (isLeftChild) {
            parentNode.leftChild = newNode;
        } else {
            parentNode.rigthChild = newNode;
        }
    }

    /**
     * 删除指定节点
     */
    public boolean delete(int key) {
        Node currentNode = root;
        Node parentNode = root;
        boolean isLeftChild = true;
        while (null != currentNode && currentNode.key != key) {
            parentNode = currentNode;
            if (key < currentNode.key) {
                currentNode = currentNode.leftChild;
                isLeftChild = true;
            } else {
                currentNode = currentNode.rigthChild;
                isLeftChild = false;
            }
        }

        if (currentNode == null) {
            return false;
        }

        if (currentNode.leftChild == null && currentNode.rigthChild == null) {
            if (currentNode == root) { //要删除的节点为叶子节点
                root = null;
            } else if (isLeftChild) {
                parentNode.leftChild = null;
            } else {
                parentNode.rigthChild = null;
            }
        } else if (currentNode.rigthChild == null) { //要删除的节点只有左孩子
            if (currentNode == root) {
                root = currentNode.leftChild;
            } else if (isLeftChild) {
                parentNode.leftChild = currentNode.leftChild;
            } else {
                parentNode.rigthChild = currentNode.leftChild;
            }
        } else if (currentNode.leftChild == null) {
            if (currentNode == root) {
                root = currentNode.rigthChild;
            } else if (isLeftChild) {
                parentNode.leftChild = currentNode.rigthChild;
            } else {
                parentNode.rigthChild = currentNode.leftChild;
            }
        } else {
            //要删除的节点既有左孩子又有有孩子
            //思路:用待删除节点右子树中的key值最小的节点的值来替代要删除的节点的值,然后删除右子树中key值最小的节点
            //右子树key最小的节点一定不含左子树,所以删除这个key最小的节点一定是属于叶子节点或者只有右子树的节点
            Node directPostNode = getDirectPostNode(currentNode);
            currentNode.key = directPostNode.key;
            currentNode.value = directPostNode.value;
        }
        return true;
    }

    /**
     * 得到待删除节点的直接后继节点
     */
    private Node getDirectPostNode(Node delNode) {
        Node parentNode = delNode;//用来保存待删除节点的直接后继节点的父亲节点
        Node directPostNode = delNode; //用来保存待删除节点的直接后继节点
        Node currentNode = delNode.rigthChild;
        while (currentNode != null) {
            parentNode = directPostNode;
            directPostNode = currentNode;
            currentNode = currentNode.leftChild;
        }

        if (directPostNode != delNode.rigthChild) { //从树中删除此直接后继节点
            parentNode.leftChild = directPostNode.rigthChild;
            directPostNode.rigthChild = null;
        }
        return directPostNode;
    }

    /**
     * 先序遍历树
     */
    public void preOrder(Node rootNode) {
        if (null != rootNode) {
            System.out.println(rootNode.key + " " + rootNode.value);
            preOrder(rootNode.leftChild);
            preOrder(rootNode.rigthChild);
        }
    }

    /**
     * 中序遍历树
     */
    public void inOrder(Node rootNode) {
        if (null != rootNode) {
            inOrder(rootNode.leftChild);
            System.out.println(rootNode.key + " " + rootNode.value);
            inOrder(rootNode.rigthChild);
        }
    }

    /**
     * 后序遍历树
     */
    public void postOrder(Node rootNode) {
        if (null != rootNode) {
            postOrder(rootNode.leftChild);
            postOrder(rootNode.rigthChild);
            System.out.println(rootNode.key + " " + rootNode.value);
        }
    }
}

相关文章

  • 极客时间数据结构与算法之美笔记25~26

    二叉树到二叉查找树,是为了查找数据的效率接近logN。 二叉查找树到平衡二叉查找树,是为了防止二叉查找树沦为链表。...

  • 二叉查找树

    1)二叉查找树是什么?2)二叉查找树的插入、删除、查找?3)Go代码实现 一、二叉查找树是什么?二叉查找树(BST...

  • 红黑树

    红黑树的本质就是一棵二叉查找树,所以先从二叉查找树来了解起。 二叉查找树 二叉查找树又称有序二叉树,具有以下特性:...

  • 二叉查找树

    二叉查找树,又称二叉搜索树 二叉查找树也称为有序二叉查找树,满足二叉查找树的一般性质,是指一棵空树具有如下性质: ...

  • 99-数据结构和算法

    难点:二叉树的遍历 红黑树 图的遍历 二叉查找树二叉查找树(binary search tree),二叉查找树在二...

  • 11-二叉查找树

    二叉查找树 1.什么是二叉查找树? 二叉查找树是一种支持数据动态的插入,删除,查找的数据结构。 2.二叉查找树的设...

  • 17张图带你解析红黑树的原理!保证你能看懂!

    二叉查找树 由于红黑树本质上就是一棵二叉查找树,所以在了解红黑树之前,咱们先来看下二叉查找树。 二叉查找树(Bin...

  • 二叉树 堆 2019-04-17

    二叉树 实现一个二叉查找树,并且支持插入、删除、查找操作 实现查找二叉查找树中某个节点的后继、前驱节点 实现二叉树...

  • 6. 二叉树创建-查找

    1. 递归方式实现二叉树的构建2. 树、二叉树、二叉查找树3. 二叉树排序树的理解4. 二叉查找树5. 二叉树的查找

  • 数据结构中的各种树

    一、二叉树 二、二叉查找树(又称二叉排序树,二叉搜索树) 二叉查找树(Binary Search Tree)它或者...

网友评论

      本文标题:二叉查找树

      本文链接:https://www.haomeiwen.com/subject/xslmxftx.html