二叉搜索树Java实现(增删改查遍历等操作)

是一种特殊结构的二叉树二叉排序树(BinarySortTree),又称二叉查找树、二叉搜索树。二叉搜索树需满足以下四个条件:若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;若任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;任意节点的左、右子树也分别为二叉查找树;没有键值相等的节点。二叉排序树性质按中序遍历二叉排序树,所得到的中序遍历序列是一个递增有序序
摘要由CSDN通过智能技术生成

是一种特殊结构的二叉树

二叉排序树(BinarySortTree),又称二叉查找树、二叉搜索树。

二叉搜索树需满足以下四个条件:

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

二叉排序树性质

按中序遍历二叉排序树,所得到的中序遍历序列是一个递增有序序列。

二叉搜索树就是具备上述四种性质的二叉树。

下面进行的二叉排序树的增删改查操作都是基于节点Node中key的大小构建二叉排序树

二叉排序树的插入

在二叉排序树中插入新结点,要保证插入后的二叉树仍符合二叉排序树的定义。   
插入过程:
- 若二叉排序树为空,则待插入结点*S作为根结点插入到空树中;
- 当非空时,将待插结点关键字S->key和树根关键字t->key进行比较,若s->key = t->key,则无须插入,若s->key< t->key,则插入到根的左子树中,若s->key> t->key,则插入到根的右子树中。而子树中的插入过程和在树中的插入过程相同,如此进行下去,直到把结点*s作为一个新的树叶插入到二叉排序树中,或者直到发现树已有相同关键字的结点为止。
- 插入完成

二叉排序树的查找

假定二叉排序树的根结点指针为 root ,给定的关键字值为 K ,则查找算法可描述为:

  • ① 置初值: q = root ;
  • ② 如果 K = q -> key ,则查找成功,算法结束;
  • ③ 否则,如果 K < q -> key ,而且 q 的左子树非空,则将 q 的左子树根送 q ,转步骤②;否则,查找失败,结束算法;
  • ④ 否则,如果 K > q -> key ,而且 q 的右子树非空,则将 q 的右子树根送 q ,转步骤②;否则,查找失败,算法结束。

二叉排序树的删除

假设被删结点是*p,其双亲是*f,不失一般性,设*p*f的左孩子,下面分三种情况讨论:   
- ⑴ 若结点*p是叶子结点,则只需修改其双亲结点*f的指针即可。  
- ⑵ 若结点*p只有左子树PL或者只有右子树PR,则只要使PL或PR 成为其双亲结点的左子树即可。   
- ⑶ 若结点*p的左、右子树均非空,先找到*p的中序后继(或前驱)节点*s(注意*s*p的右子树中的key最小的结点,它的左子树为空),然后步骤如下:
- 找到 *p 的节点的直接中序后继节点(即其右子树中key值最小的节点 ),并删除此直接中序后继节点。
- 将此后继节点的 key、value 值赋给待删除节点的 key,value值。

例如删除上图一中 key 值为 10 的节点,这时就需要用 key 值为 10 的节点的中序后继节点(节点 11)来代替 key 值为 10 的节点,并删除 key 值为 10 的节点的中序后继节点,由中序遍历相关规则可知, key 值为 10 的节点的直接中序后继节点一定是其右子树中 key 值最小的节点,所以此中序后继节点一定不含子节点或者只含有一个右孩子,删除此中序后继节点就属于上述 1,2 所述情况。图一中 key 值为 10 的节点的直接中序后继节点 为 11,节点 11 含有一个右孩子 12。

步骤:

a、找到 key 值为 10 的节点的直接中序后继节点(即其右子树中值最小的节点 11),并删除此直接中序后继节点。

b、将此后继节点的 key、value 值赋给待删除节点的 key,value值。

实例demo

节点类


package org.vincent.strategy.binarysearch;

class Node {
    int key;
    int value;
    Node leftChild;
    Node rightChild;

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

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

    public Node() {

    }

    @Override
    public String toString() {
        return "Node [key=" + this.key + ", value=" + this.value + ", leftChild=" + this.leftChild + ", rightChild=" + this.rightChild + "]";
    }

    public 
  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值