二叉树,红黑树,23树,B树,B+树

本文详细介绍了二叉树的基本概念,包括树的术语、结点度、深度等,并讲解了二叉树的遍历、删除操作。接着深入探讨了平衡树,如2-3树的查找和插入,红黑树的定义、平衡化策略以及插入操作。最后,文章对比了B树和B+树的特性和数据存储方式。
摘要由CSDN通过智能技术生成

二叉树

树的相关术语

结点的度: 一个结点含有的子树的个数称为该结点的度;

叶结点: 度为0的结点称为叶结点,也可以叫做终端结点

分支结点: 度不为0的结点称为分支结点,也可以叫做非终端结点

结点的层次: 从根结点开始,根结点的层次为1,根的直接后继层次为2,以此类推

**结点的层序编号:**将树中的结点,按照从上层到下层,同层从左到右的次序排成一个线性序列,把他们编成连续的自然数。

树的度: 树中所有结点的度的最大值

树的高度(深度): 树中结点的最大层次

森林: m(m>=0)个互不相交的树的集合,将一颗非空树的根结点删去,树就变成一个森林;给森林增加一个统一的根 结点,森林就变成一棵树

孩子结点: 一个结点的直接后继结点称为该结点的孩子结点

双亲结点(父结点): 一个结点的直接前驱称为该结点的双亲结点

兄弟结点: 同一双亲结点的孩子结点间互称兄弟结点

删除元素

在这里插入图片描述
在这里插入图片描述

二叉树的基础遍历

前序遍历

先访问根结点,然后再访问左子树,最后访问右子树

中序遍历

先访问左子树,中间访问根节点,最后访问右子树

后序遍历

先访问左子树,再访问右子树,最后访问根节点

在这里插入图片描述

二叉树的层序遍历

在这里插入图片描述
实现步骤:

1.创建队列,存储每一层的结点;

2.使用循环从队列中弹出一个结点:

2.1获取当前结点的key;

2.2如果当前结点的左子结点不为空,则把左子结点放入到队列中

2.3如果当前结点的右子结点不为空,则把右子结点放入到队列中
在这里插入图片描述

二叉树的最大深度问题

实现步骤:

1.如果根结点为空,则最大深度为0;

2.计算左子树的最大深度;

3.计算右子树的最大深度;

4.当前树的最大深度=左子树的最大深度和右子树的最大深度中的较大者+1

二叉树代码设计

import help_api.Queue;

//二叉树代码
public class BinaryTree<Key extends Comparable<Key>, Value> {
   
    //记录根结点
    private Node root ;
    //记录树中元素的个数
    private int N;
    
    public BinaryTree() {
   
        root = null;
        N = 0;
    }

    //获取树中元素的个数
    public int size() {
   
        return N;
    }
    
    //向树中添加元素key-value
    public void put(Key key, Value value) {
   
        root = put(root, key, value);
    }
    
    //向指定的树x中添加key-value,并返回添加元素后新的树
    private Node put(Node x, Key key, Value value) {
   
        if (x == null) {
   
//个数+1
            N++;
            return new Node(key, value, null, null);
        }
        int cmp = key.compareTo(x.key);
        if (cmp > 0) {
   
//新结点的key大于当前结点的key,继续找当前结点的右子结点
            x.right = put(x.right, key, value);
        } else if (cmp < 0) {
   
//新结点的key小于当前结点的key,继续找当前结点的左子结点
            x.left = put(x.left, key, value);
        } else {
   
//新结点的key等于当前结点的key,把当前结点的value进行替换
            x.value = value;
        }
        return x;
    }
    
    //查询树中指定key对应的value
    public Value get(Key key) {
   
        return get(root, key);
    }
    
//从指定的树x中,查找key对应的值
    public Value get(Node x, Key key) {
   
        if (x == null) {
   
            return null;
        }
    int cmp = key.compareTo(x.key);
    if (cmp > 0) {
   
//如果要查询的key大于当前结点的key,则继续找当前结点的右子结点;
        return get(x.right, key);
    } else if (cmp < 0) {
   
//如果要查询的key小于当前结点的key,则继续找当前结点的左子结点;
        return get(x.left, key);
    } else {
   
//如果要查询的key等于当前结点的key,则树中返回当前结点的value。
        return x.value;
    }
}
    
    //删除树中key对应的value
    public void delete(Key key) {
   
        root = delete(root, key);
    }
    
    //删除指定树x中的key对应的value,并返回删除后的新树
    public Node delete(Node x, Key key) {
   
        if (x == null) {
   
            return null;
        }
        int cmp = key.compareTo(x.key);
        if (cmp > 0) {
   
//新结点的key大于当前结点的key,继续找当前结点的右子结点
            x.right = delete(x.right, key);
        } else if (cmp < 0) {
   
//新结点的key小于当前结点的key,继续找当前结点的左子结点
            x.left = delete(x.left, key);
        } else {
   
//个数-1
            N--;
//新结点的key等于当前结点的key,当前x就是要删除的结点
//1.如果当前结点的右子树不存在,则直接返回当前结点的左子结点
            if (x.right == null) {
   
                return x.left;
            }
//2.如果当前结点的左子树不存在,则直接返回当前结点的右子结点
            if (x.left == null) {
   
                return x.right;
            }
//3.当前结点的左右子树都存在
//3.1找到右子树中最小的结点
            Node minNode = x.right;
            while (minNode.left != null) {
   
                minNode = minNode.left;
            }
//3.2删除右子树中最小的结点
            Node n = x.right;
            while (n.left != null) {
   
                if (n.left.left == null) {
   
                    n.left = null;
                } else {
   
                    n = n.left;
                }
            }
//3.3让被删除结点的左子树称为最小结点minNode的左子树,让被删除结点的右子树称为最小结点
//          minNode的右子树
            minNode.left = x.left;
            minNode.right = x.right;
//3.4让被删除结点的父节点指向最小结点minNode
            x = minNode;
        }
        return x;
    }

    //找出整个树中最小
  • 18
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值