红黑树算法(JAVA)的实现(包含swing界面演示程序)

因为算法课设需要,要实现红黑树的实验及具体演示步骤。
源码参考链接:https://blog.csdn.net/cdnight/article/details/10583177

一、红黑树特点

(1)每个节点或者是黑色,或者是红色。
(2)根节点是黑色。
(3)每个叶子节点(NIL)是黑色。
(4)如果一个节点是红色的,则它的子节点必须是黑色的。
(5)从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点。
根据这五条特性可以知道红黑树一直是平衡的,且该查找树时间复杂度为 O(log(n))

二、红黑树构造

1.构造红黑树单元

public class TreeUnit {
    public String color = "red";
    public boolean isRed = true;
    public char indexNO = 'A';
    public TreeUnit _parent = null;

    public TreeUnit _leftChild = null;
    public TreeUnit _rightChild = null;
    public boolean isNIL = false;
}

2.查,插,删

private void recursion_search(TreeUnit _currentNode, char indexNO) {
        if (_currentNode == null) {
            return;
        }
        if (indexNO == _currentNode.indexNO) {
            this.search_result = true;
            return;
        }
        if (indexNO < _currentNode.indexNO) {
            if (_currentNode._leftChild == null) {
                return;
            }
            recursion_search(_currentNode._leftChild, indexNO);
            return;
        }
        if (indexNO > _currentNode.indexNO) {
            if (_currentNode._rightChild == null) {
                return;
            }
            recursion_search(_currentNode._rightChild, indexNO);
        }
    }

public boolean insert(char indexNO) {
        if (this._rootNode == null) {
            this._rootNode = new TreeUnit();
            this._rootNode.indexNO = indexNO;
            this._rootNode.isRed = false;
            return true;
        }
        TreeUnit parentUnit = recursion_search_fitParentNode(this._rootNode, indexNO);
        if (parentUnit == null) {
            return false;
        }

        TreeUnit minNode = new TreeUnit();
        minNode.isRed = true;
        minNode.indexNO = indexNO;
        minNode._parent = parentUnit;
        if (indexNO < parentUnit.indexNO) {
            parentUnit._leftChild = minNode;

        } else if (indexNO > parentUnit.indexNO) {
            parentUnit._rightChild = minNode;
        } else {

            return false;
        }
        recursion_fixup_after_insert(minNode);
        return true;
    }

    public boolean delete(char indexNO) {
        TreeUnit originNode = search_node(indexNO);
        TreeUnit rec_node = null;
        TreeUnit nilNode = new TreeUnit();
        nilNode.isNIL = true;
        nilNode.isRed = false;
        if (originNode == null) {
            return false;
        }

        TreeUnit realDeletedNode = originNode;
        if (originNode._rightChild == null) {
            realDeletedNode = originNode;
        } else {

            realDeletedNode = recursion_search_real_deletedNode(originNode._rightChild);
        }

        if (realDeletedNode.indexNO == originNode.indexNO) {
            TreeUnit parentNode = originNode._parent;
            if (parentNode == null) {

                if (originNode._leftChild == null) {
                    this._rootNode = null;
                    rec_node = null;
                    return true;
                }
                this._rootNode = originNode._leftChild;
                this._rootNode._parent = null;
                this._rootNode.isRed = false;
                return true;
            }

            if (parentNode != null) {
                boolean isLeft = false;
                if (parentNode._leftChild != null && parentNode._leftChild.indexNO == originNode.indexNO) {
                    isLeft = true;
                }
                if (originNode.isRed) {
                    if (isLeft) {
                        parentNode._leftChild = null;
                    } else {

                        parentNode._rightChild = null;
                    }
                    return true;
                }
                boolean hasLeftChild = false;
                if (originNode._leftChild != null) {
                    hasLeftChild = true;
                }

                if (isLeft) {
                    parentNode._leftChild = originNode._leftChild;
                    if (originNode._leftChild != null) {
                        originNode._leftChild._parent = parentNode;
                    }
                } else if (!isLeft) {
                    parentNode._rightChild = originNode._leftChild;
                    if (originNode._leftChild != null) {
                        originNode._leftChild._parent = parentNode;
                    }
                }
                if (hasLeftChild) {
                    if (isLeft) {
                        recursion_fixup_afterDeletion(parentNode._leftChild);
                    } else {

                        recursion_fixup_afterDeletion(parentNode._rightChild);
                    }


                    return true;
                }
                nilNode._parent = parentNode;
                if (isLeft) {
                    parentNode._leftChild = nilNode;
                    recursion_fixup_afterDeletion(parentNode._leftChild);
                } else {

                    parentNode._rightChild = nilNode;
                    recursion_fixup_afterDeletion(parentNode._rightChild);
                }
                delNILNode(nilNode);
                return true;
            }
        } else {
            originNode.indexNO = realDeletedNode.indexNO;
            TreeUnit parentNode = realDeletedNode._parent;
            boolean isLeft = true;
            if (parentNode._rightChild != null && parentNode._rightChild.indexNO == realDeletedNode.indexNO) {
                isLeft = false;
            }

            if (realDeletedNode.isRed) {
                if (isLeft) {
                    parentNode._leftChild = null;
                    return true;
                }

                parentNode._rightChild = null;
                return true;
            }

            if (!realDeletedNode.isRed && realDeletedNode._rightChild != null && !realDeletedNode._rightChild.isNIL) {
                if (isLeft) {
                    parentNode._leftChild = realDeletedNode._rightChild;
                    realDeletedNode._rightChild._parent = parentNode;
                    recursion_fixup_afterDeletion(realDeletedNode._leftChild);
                    return true;
                }

                System.out.println("【当真实节点为黑色并且拥有红色右子节点时,删除真实节点,将右子节点提升到同样位置,右子节点参与到位置调整】");
                parentNode._rightChild = realDeletedNode._rightChild;
                realDeletedNode._rightChild._parent = parentNode;
                recursion_fixup_afterDeletion(parentNode._rightChild);
                return true;
            }


            if (!realDeletedNode.isRed && (realDeletedNode._rightChild == null || (realDeletedNode._rightChild != null && realDeletedNode._rightChild.isNIL))) {

                nilNode._parent = parentNode;
                if (isLeft) {
                    parentNode._leftChild = nilNode;
                } else {

                    parentNode._rightChild = nilNode;
                }


                recursion_fixup_afterDeletion(nilNode);
                delNILNode(nilNode);
                return true;
            }
        }

        return true;
    }

三、swing界面构造

1.显示单元

public class GraphNodeViewModel {
    public char indexNO = 'A';
    public boolean isRed = true;
    public int xIndex = 0;
    public int yIndex = 0;

    public int locX = 0;
    public int locY = 0;
    public int HSep = 0;
    public int VSep = 0;

    public Object _cellObject = null;
    public GraphNodeViewModel _parent = null;
    public GraphNodeViewModel leftChild = null;
    public GraphNodeViewModel rightChild = null;

    public float leftNO = 0.0F;
    public float rightNO = 0.0F;

    public int leftChildLocX = 0;
    public int rightChildLocX = 0;
}

2.增删查演示


在这里插入图片描述

在这里插入图片描述
还可以进行红黑树手动修改,本博客不做演示

源码在github中

https://github.com/NH4L/RBTree

发布了19 篇原创文章 · 获赞 30 · 访问量 2万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 1024 设计师: 上身试试

分享到微信朋友圈

×

扫一扫,手机浏览