【2-3-4B树】java代码实现(红黑树实现前置)

之前想实现红黑树来着,发现红黑树在遵循平衡二叉树规则的前提下,更多是2-3-4B树的二叉树形式实现

思路

2-3-4B树构造思路基于B树规则的基础之上,加上了每节点至多三个数值的限制。

插入

其插入规则于二叉查找树类似,小于则向左传递,反之则向右。传递至叶子节点时进行插入操作,若当前叶子节点已经满了,则需要向父节点传递最接近父节点的值的值,若没有父节点则选取第二或第三个节点抽离为父节点,其左右节点变为该父节点的左右子树。

代码实现

参数构造

num1~num4从小到大视为节点的四个值,当4个值都存满时,则向上传递一个节点,或裂解为一组新的树
依据常规下至多三个值的要求,建立左,中左,中右,右四棵子树,和一个父节点

    private int num1=-1;
    private int num2=-1;
    private int num3=-1;
    private int num4=-1;
    //父亲节点
    private Point parent=null;
    private Point right=null;
    private Point midRight=null;
    private Point midLeft=null;
    private Point left=null;

插入方法

插入方法为将值依次与num1~num4比较,小向右,大向左,有子树则传递至子树,无子树则插入自身,满4个则向上传递或裂解

    public void add(int num){
        //空节点
        if(this.num1==-1){
            this.num1 = num;
        }
        //单节点
        if(this.num1!=-1 && this.num2==-1){
            if(this.num1>num){
                toLeftPoint(num);
            }
            if(this.num1<num){
                this.num2 = num;
            }
        }
        //双节点
        if(this.num1!=-1 && this.num2!=-1 && this.num3==-1){
            if(this.num1>num){
                toLeftPoint(num);
            }
            if(this.num1<num && this.num2>num){
                toMidLeft(num);
            }
            if(this.num2<num){
                this.num3 = num;
            }
        }
        //满节点
        if(this.num1!=-1 && this.num2!=-1 && this.num3!=-1){
            if(this.num1>num){
                toLeftPoint(num);
            }
            if(this.num1<num && this.num2>num){
                toMidLeft(num);
            }
            if(this.num2<num && this.num3>num){
                toMidRight(num);
            }
            if(this.num3<num){
                toRight(num);
            }
            if(parent==null){
                divid();//节点裂解
            }
            if(parent!=null){
                sendToParent();//传递至父亲节点
            }
        }
    }
    private void toRight(int num){
        if(this.getRight()!=null){
            this.getRight().add(num);
        }else{
            Point p = new Point();
            p.add(num);
            this.setRight(p);
        }
    }
    private void toMidRight(int num){
        if(this.getMidRight()!=null){
            this.getMidRight().add(num);
        }else{
            Point p = new Point();
            p.add(num);
            this.setMidRight(p);
        }
    }
    private void toMidLeft(int num){
        if(this.getMidLeft()!=null){
            this.getMidLeft().add(num);
        }else{
            Point p = new Point();
            p.add(num);
            this.setMidLeft(p);
        }
    }

    private void toLeftPoint(int num){
        if(this.getLeft()!=null){
            this.getLeft().add(num);
        }else{
            Point p = new Point();
            p.add(num);
            this.setLeft(p);
        }
    }

节点裂解

取当前节点的第二个值为父节点,左和中左子树为新左节点的左右子树,中右和右子树为新右子树的中右和右子树,若没有则为null传递,不用管

    //当当前节点数值达到4个之后,且无父节点时需将该节点裂解为三个
    private void divid(){
        //构造新的父亲节点
        Point newParent = new Point();
        newParent.add(this.num2);
        //构造新的左节点
        Point newLeft = new Point();
        newLeft.add(this.num1);
        newLeft.setLeft(this.left);
        newLeft.setRight(this.midLeft);
        newLeft.parent = newParent;
        newParent.setLeft(newLeft);
        //构造新的右节点
        Point newRight = new Point();
        newRight.add(this.num3);
        newRight.add(this.num4);
        newRight.setRight(this.right);
        newRight.setMidRight(this.midRight);
        newRight.parent = newParent;
        newParent.setRight(newRight);
    }

值的向上传递

判断该节点位于父节点的哪一个位置,传递相应值至父节点

    //当当前节点数达到4个之后,且有父节点时需要向上传递数据
    private void sendToParent(int num){
        //判断该节点处于父节点四分分支中的哪一个分支
        if(this.parent.getLeft().equals(this)){
            //处于左节点
            this.parent.setToParent(this.num4);
            this.num4 = -1;
        }else{
            this.parent.sendToParent(this.num1);
            this.num1 = this.num2;
            this.num2 = this.num3;
            this.num3 = this.num4;
            this.num4 = -1;
        }

    }

全部代码

package TTFBTree;

public class Point {

    private int num1=-1;
    private int num2=-1;
    private int num3=-1;
    private int num4=-1;
    //父亲节点
    private Point parent=null;
    private Point right=null;
    private Point midRight=null;
    private Point midLeft=null;
    private Point left=null;

    public void add(int num){
        //空节点
        if(this.num1==-1){
            this.num1 = num;
        }
        //单节点
        if(this.num1!=-1 && this.num2==-1){
            if(this.num1>num){
                toLeftPoint(num);
            }
            if(this.num1<num){
                this.num2 = num;
            }
        }
        //双节点
        if(this.num1!=-1 && this.num2!=-1 && this.num3==-1){
            if(this.num1>num){
                toLeftPoint(num);
            }
            if(this.num1<num && this.num2>num){
                toMidLeft(num);
            }
            if(this.num2<num){
                this.num3 = num;
            }
        }
        //满节点
        if(this.num1!=-1 && this.num2!=-1 && this.num3!=-1){
            if(this.num1>num){
                toLeftPoint(num);
            }
            if(this.num1<num && this.num2>num){
                toMidLeft(num);
            }
            if(this.num2<num && this.num3>num){
                toMidRight(num);
            }
            if(this.num3<num){
                toRight(num);
            }
            if(parent==null){
                divid();//节点裂解
            }
            if(parent!=null){
                sendToParent(this.num1);//传递至父亲节点
            }
        }
    }
    private void toRight(int num){
        if(this.getRight()!=null){
            this.getRight().add(num);
        }else{
            Point p = new Point();
            p.add(num);
            this.setRight(p);
        }
    }
    private void toMidRight(int num){
        if(this.getMidRight()!=null){
            this.getMidRight().add(num);
        }else{
            Point p = new Point();
            p.add(num);
            this.setMidRight(p);
        }
    }
    private void toMidLeft(int num){
        if(this.getMidLeft()!=null){
            this.getMidLeft().add(num);
        }else{
            Point p = new Point();
            p.add(num);
            this.setMidLeft(p);
        }
    }

    private void toLeftPoint(int num){
        if(this.getLeft()!=null){
            this.getLeft().add(num);
        }else{
            Point p = new Point();
            p.add(num);
            this.setLeft(p);
        }
    }
    //当当前节点数达到4个之后,且有父节点时需要向上传递数据
    private void sendToParent(int num){
        //判断该节点处于父节点四分分支中的哪一个分支
        if(this.parent.getLeft().equals(this)){
            //处于左节点
            this.parent.setToParent(this.num4);
            this.num4 = -1;
        }else{
            this.parent.sendToParent(this.num1);
            this.num1 = this.num2;
            this.num2 = this.num3;
            this.num3 = this.num4;
            this.num4 = -1;
        }

    }
    //从子节点抽象数据
    private void setToParent(int num){
        if(num < this.num1){
            this.num4 = this.num3;
            this.num3 = this.num2;
            this.num2 = this.num1;
            this.num1 = num;
        }
        if(this.num1<num && num < this.num2){
            this.num4 = this.num3;
            this.num3 = this.num2;
            this.num2 = num;
        }
        if(this.num2<num && num< this.num3){
            this.num4 = this.num3;
            this.num3 = num;
        }
        if(this.num3<num){
            this.num4 = num;
        }
        if(this.num4!=-1){
            divid();
        }

    }

    //当当前节点数值达到4个之后,且无父节点时需将该节点裂解为三个
    private void divid(){
        //构造新的父亲节点
        Point newParent = new Point();
        newParent.add(this.num2);
        //构造新的左节点
        Point newLeft = new Point();
        newLeft.add(this.num1);
        newLeft.setLeft(this.left);
        newLeft.setRight(this.midLeft);
        newLeft.parent = newParent;
        newParent.setLeft(newLeft);
        //构造新的右节点
        Point newRight = new Point();
        newRight.add(this.num3);
        newRight.add(this.num4);
        newRight.setRight(this.right);
        newRight.setMidRight(this.midRight);
        newRight.parent = newParent;
        newParent.setRight(newRight);
    }
    public int getMax(){
        if(this.num3!=-1){
            return this.getNum3();
        }
        if(this.num2!=-1){
            return this.getNum2();
        }
        if(this.num1!=-1){
            return this.getNum1();
        }
        return -1;
    }
    public int getMin(){
        return this.num1;
    }

    public int getNum1() {
        return num1;
    }

    public void setNum1(int num1) {
        this.num1 = num1;
    }

    public int getNum2() {
        return num2;
    }

    public void setNum2(int num2) {
        this.num2 = num2;
    }

    public int getNum3() {
        return num3;
    }

    public void setNum3(int num3) {
        this.num3 = num3;
    }

    public int getNum4() {
        return num4;
    }

    public void setNum4(int num4) {
        this.num4 = num4;
    }

    public Point getRight() {
        return right;
    }

    public void setRight(Point right) {
        this.right = right;
    }

    public Point getMidRight() {
        return midRight;
    }

    public void setMidRight(Point midRight) {
        this.midRight = midRight;
    }

    public Point getMidLeft() {
        return midLeft;
    }

    public void setMidLeft(Point midLeft) {
        this.midLeft = midLeft;
    }

    public Point getLeft() {
        return left;
    }

    public void setLeft(Point left) {
        this.left = left;
    }

    public Point getParent() {
        return parent;
    }

    public void setParent(Point parent) {
        this.parent = parent;
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
4B3T编码是一种常用的数字信号调制方式,它将4个数据位编码成3个传输位。这种编码方式在串行通信中应用非常广泛。 Verilog是一种硬件描述语言,可以用于设计数字电路和系统。在实现4B3T编码时,可以使用Verilog语言进行代码实现。 4B3T编码实现的基本思路是将4个输入位映射到3个输出位上,通过编码和解码实现数据的传输。具体实现过程如下: - 将4个输入位分成两组,每组2位; - 对于每组输入位,进行编码映射,生成3个输出位; - 将2组编码后的输出位拼接成一个6位的序列; - 根据6位序列,生成传输时所需的波形。 下面是4B3T Verilog代码的一个简单实现: ``` module fourbthreet(verilog_input, verilog_output); input [3:0] verilog_input; output [2:0] verilog_output; assign verilog_output = ~(verilog_input & verilog_input & verilog_input & verilog_input); assign verilog_output = ~(verilog_input & verilog_input & ~verilog_input & verilog_input); assign verilog_output = ~(verilog_input & ~verilog_input & verilog_input & verilog_input); endmodule ``` 这段代码定义了一个名为“fourbthreet”的模块,它有两个端口:输入端口“verilog_input”和输出端口“verilog_output”。在这个模块中,输入端口是一个4位宽度的向量,输出端口是一个3位宽度的向量。 在这个模块中,使用了assign语句将输入位映射为输出位。具体来说,第一个输出位由四个输入位的逻辑与非运算得到,第二个输出位由两个输入位的逻辑与非运算和两个输入位的逻辑与运算得到,第三个输出位由两个输入位的逻辑与非运算和两个输入位的逻辑与运算得到。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值