在另一个Red-Black-Trees节点中使用Red-Black-Trees

时间:2015-08-23 22:00:25

标签: java nodes red-black-tree

我陷入了一项任务,我可以使用一些帮助。基本上,我的工作是设计一个包装礼物的工厂。我们的股票是方形底座(不一定是立方体)。对于每个盒子,我们知道盒子底部的尺寸(我称之为侧面)和高度(高度)。当工厂收到包装礼物的请求时,顾客知道适合当前的最小盒子的侧面和高度值,但是我们将为盒子提供我们目前最小的体积。

我们的想法是规划一个数据结构来管理这些盒子。数据结构必须支持以下方法:

INSERTBOX(侧面,高度) - 向具有给定尺寸的数据结构添加一个框

REMOVEBOX(侧面,高度) - 从具有给定尺寸的数据结构中移除一个框

GETBOX(侧面,高度) - 返回适合包裹礼物的最小体积的盒子尺寸(当然,它的尺寸应该等于或大于给定的边和高度......)

CHECKBOX(侧面,高度) - 检查存储器中是否有适合当前的盒子。

整个问题的参数是边值的数量m和高度值的数量n。

我想到了一个红黑树,它以侧面为关键,每个节点还有一棵红黑树,其中所有边都相等,高度现在是关键。

我遇到的是实现GetBox方法,我只是想办法找出一个更好的方法,而不是检查每个节点的最小体积,其中边和高度等于或大于那些由用户。

主程序

import java.util.Scanner;

 class ProgramBody
    {
        public static BoxesRedBlackTree sideTree = new BoxesRedBlackTree();
        public static void Main()
        {
            final int INSERTBOX = 1;
            final int REMOVEBOX = 2;
            final int GETBOX = 3;
            final int CHECKBOX = 4;
            final int EXIT = 5;

            System.out.println("Welcome to the factory! What would you like to do?");
            System.out.println("Insert a box - " + INSERTBOX);
            System.out.println("Remove a box - " + REMOVEBOX);
            System.out.println("Get a box - " + GETBOX);
            System.out.println("Check if a box exists - " + CHECKBOX);
            System.out.println("Exit - " + EXIT);
            System.out.println("Please enter your choice: ");

            Scanner in = new Scanner(System.in);
            int Choise = in.nextInt();

            // While the user doesn't exit the program
            while (Choise != EXIT)
            {
                switch (Choise)
                {
                    case (INSERTBOX):
                        {
                            System.out.println("Enter the size of the side");
                            int side = in.nextInt();
                            System.out.println("Enter the size of the height");
                            int height = in.nextInt();

                            InsertBox(side, height);

                            break;
                        }
                    case (REMOVEBOX):
                        {
                            System.out.println("Enter the size of the side");
                            int side = in.nextInt();
                            System.out.println("Enter the size of the height");
                            int height = in.nextInt();

                            RemoveBox(side, height);

                            break;
                        }
                    case (GETBOX):
                        {
                            System.out.println("Enter the size of the side");
                            int side = in.nextInt();
                            System.out.println("Enter the size of the height");
                            int height = in.nextInt();

                            GetBox(side, height);

                            break;
                        }
                    case (CHECKBOX):
                        {
                            System.out.println("Enter the size of the side");
                            int side = in.nextInt();
                            System.out.println("Enter the size of the height");
                            int height = in.nextInt();
                            boolean boxExists;

                            if (CheckBox(side, height))
                            { System.out.println("The box exists."); }
                            else
                            { System.out.println("The box doesn't exist."); }

                            break;
                        }
                        default:
                            { System.out.println("You have entered an unfamiliar choice. Please try again."); }
                    } 
                System.out.println("\nWhat would you like to do now?");
                System.out.println("Insert a box - " + INSERTBOX);
                System.out.println("Remove a box - " + REMOVEBOX);
                System.out.println("Get a box - " + GETBOX);
                System.out.println("Check if a box exists - " + CHECKBOX);
                System.out.println("Exit - " + EXIT);
                System.out.println("Please enter your choice: ");

                Choise = in.nextInt();
            }
        }
        private static void InsertBox(int side, int height) {
            if (sideTree.sideExist(side))
            {
               //Check if There is same box
               if(sideTree.searchBySide(side).getTree().heightExist(height))
               { sideTree.searchBySide(side).getTree().searchByHeight(height).setCounter(sideTree.searchBySide(side).getTree().searchByHeight(height).getCounter()+1); }
               else
               { 
                BoxNode temp = new BoxNode(side, height, 1);
                sideTree.searchBySide(side).getTree().insert(temp);
               }

            }
            else 
            {
                BoxNode heightTempNode = new BoxNode(side, height, 1);
                BoxesRedBlackTree tempTree = new BoxesRedBlackTree();
                tempTree.insert(heightTempNode);
                BoxNode sideTempNode = new BoxNode(side, height, tempTree);
                sideTree.insert(sideTempNode);
            }
            System.out.println("The box with side " + side + " and height " + height + " has been added.");
        }
        private static void RemoveBox(int side, int height) {
            if(sideTree.sideExist(side) && sideTree.searchBySide(side).getTree().heightExist(height)) {
            if (sideTree.searchBySide(side).getTree().searchByHeight(height).getCounter() > 1)
            {
                sideTree.searchBySide(side).getTree().searchByHeight(height).setCounter(sideTree.searchBySide(side).getTree().searchByHeight(height).getCounter()-1);
                System.out.println("The box with side " + side + " and height " + height + " has been removed.");
            }
            else
            {
                sideTree.searchBySide(side).getTree().delete(sideTree.searchBySide(side).getTree().searchByHeight(height));
                System.out.println("The box with side " + side + " and height " + height + " has been removed.");
            }
            if (!sideTree.searchBySide(side).getTree().sideExist(side))
            {
                sideTree.delete(sideTree.searchBySide(side));
            } }
            else
            { System.out.println("There isn't a box with the requested size!"); }
        }
        private static BoxNode GetBox(int side, int height) { 
            BoxNode currentNode = sideTree.getMin(sideTree.getRoot());
            BoxNode minimalBox = sideTree.getRoot();
            // Check all The Tree
            while (currentNode != null)
                { if(currentNode.getSide() >= side && currentNode.getHeight() >= height && currentNode.getVolume() < minimalBox.getVolume()) { minimalBox = currentNode; }}
                    currentNode = sideTree.getSuccessor(currentNode);
            if (minimalBox != null)
                    { System.out.println("The box with side " + minimalBox.getSide() + " and height " + minimalBox.getSide() + " has returned."); }
                    else
                    { System.out.println("No box was found."); }
            return (minimalBox); 
        }
        private static boolean CheckBox(int side, int height) {
            if ((GetBox(side,height)) != null)
            { return true; }
            return false;  }
 }

RED BLACK TREE

public class BoxesRedBlackTree
{
    private BoxNode _root;

    /**
     * Constructor
     */
    public BoxesRedBlackTree ()
    {
        _root = null;
    }

    /**
     * Reset root
     */
    public BoxesRedBlackTree(BoxNode box)
    {
        _root = new BoxNode(box);
    }

    /**
     * get -root method
     */
    public BoxNode getRoot()
    {
        return _root;
    }

    /**
     * LEFT-ROTATE algorithm
     */
    public void leftRotate(BoxNode x)
    { 
        BoxNode y = x.getRightSon();
        x.setRightSon(y.getLeftSon());
        if(y.getLeftSon() != null)
        {
            y.getLeftSon().setParent(x);
        }
        y.setParent(x.getParent());
        if(x.getParent() == null)
        {
            _root = y;
        }
        else if( x == x.getParent().getLeftSon())
        {
            x.getParent().setLeftSon(y);
        }
        else
        {
            x.getParent().setRightSon(y);
        }
        y.setLeftSon(x);
        x.setParent(y);
    }

    /**
     * RIGHT-ROTATE algorithm
     * Assumes right son of x is not null.
     */
    public void rightRotate(BoxNode x)
    { //assumes left son is not null
        BoxNode y = x.getLeftSon();
        x.setLeftSon(y.getRightSon());
        if(y.getRightSon() != null)
        {
            y.getRightSon().setParent(x);
        }
        y.setParent(x.getParent());
        if(x.getParent() == null)
        {
            _root = y;
        }
        else if( x == x.getParent().getRightSon())
        {
            x.getParent().setRightSon(y);
        }
        else
        {
            x.getParent().setLeftSon(y);
        }
        y.setRightSon(x);
        x.setParent(y);
    }

    /**
     * RB-INSERT algorithm
     */
    public void insert(BoxNode toInsert)
    { 
        BoxNode x = _root;
        BoxNode y = null;
        while(x != null){
            y = x;
            if(toInsert.isBigger(x))
            {
                x = x.getLeftSon();
            }
            else
            {
                x = x.getRightSon();
            }
        }
        toInsert.setParent(y);
        if(y == null)
        {
            _root = toInsert;
        }
        else if(toInsert.isBigger(y))
        {
            y.setLeftSon(toInsert);
        }
        else
        {
            y.setRightSon(toInsert);
        }

        toInsert.setLeftSon(null);
        toInsert.setRightSon(null);
        toInsert.setColor(1); // red
        insertFixUp(toInsert);

    }

    /**
     * RB-INSERT-FIXUP algorithm
     */
    private void insertFixUp(BoxNode z)
    {
        BoxNode y = null;
        while (z != _root && z.getParent().getColor() == 1)
        {
            if(z.getParent() == z.getParent().getParent().getLeftSon())
            {
                y = z.getParent().getParent().getRightSon();
                if(y != null && y.getColor()== 1)
                {
                    z.getParent().setColor(0);
                    y.setColor(0);
                    z = z.getParent().getParent();
                }
                else 
                {
                    if (z == z.getParent().getRightSon())
                    {
                        z = z.getParent();
                        this.leftRotate(z);
                    }
                    z.getParent().setColor(0);
                    z.getParent().getParent().setColor(1);
                    rightRotate(z.getParent().getParent());
                }
            }
            else 
            {
                y = z.getParent().getParent().getLeftSon();
                if(y != null && y.getColor() == 1)
                {
                    z.getParent().setColor(0);
                    y.setColor(0);
                    z = z.getParent().getParent();
                }
                else 
                {
                    if (z == z.getParent().getLeftSon()){
                        z = z.getParent();
                        this.rightRotate(z);
                    }
                    z.getParent().setColor(0);
                    z.getParent().getParent().setColor(1);
                    this.leftRotate(z.getParent().getParent());
                }
            }

        }
        _root.setColor(0);
    }

    /**
     * RB-DELETE algorithm
     */
    public void delete(BoxNode z)
    {
        BoxNode y = null;
        BoxNode x = null;
        if(z.getLeftSon() == null || z.getRightSon() == null)
        {
            y = z;
        }
        else
        {
            y = getSuccessor(z);
        }

        if(y.getLeftSon() != null)
        {
            x = y.getLeftSon();
        }
        else
        {
            x=y.getRightSon();
        }

        if (x != null && y != null)
        {
            x.setParent(y.getParent());
        }

        if(y.getParent() == null)
        {
            _root = x;
        }
        else if(y == y.getParent().getLeftSon())
        {
            y.getParent().setLeftSon(x);
        }
        else
        {
            y.getParent().setRightSon(x);
        }

        if(y != z)
        {
            z.setSide(y.getSide());
        }
        if(y.isBlack())
        {
            deleteFixUp(x);
        }
    }

    /**
     * RB-DELETE-FIXUP algorithm 
     */
    private void deleteFixUp(BoxNode x)
    {
        BoxNode temp = null;
        while (x != null && x != _root && x.isBlack())
        {
            if (x == x.getParent().getLeftSon())
            {
                temp = x.getParent().getRightSon();
                if (!temp.isBlack())
                {
                    temp.setColor(0); 
                    x.getParent().setColor(1);
                    leftRotate(x.getParent()); 
                    temp = x.getParent().getRightSon(); 
                }

                if (temp.getLeftSon().isBlack()  && temp.getRightSon().isBlack() )
                {
                    temp.setColor(1);
                    x = x.getParent(); 
                }
                else
                {
                    if (temp.getRightSon().isBlack())
                    {
                        temp.getLeftSon().setColor(0); 
                        temp.setColor(1); 
                        rightRotate (temp); 
                        temp = x.getParent().getRightSon(); 
                    }

                    temp.setColor(x.getParent().getColor()); 
                    x.getParent().setColor(0); 
                    temp.getRightSon().setColor(0); 
                    leftRotate (x.getParent()); 
                    x = _root; 
                }
            }
            else
            {
                temp = x.getParent().getLeftSon();
                if (!temp.isBlack())
                {
                    temp.setColor(0); 
                    x.getParent().setColor(1); 
                    rightRotate(x.getParent()); 
                    temp = x.getParent().getLeftSon(); 
                }

                if (temp.getRightSon().isBlack() && temp.getLeftSon().isBlack())
                {
                    temp.setColor(1); 
                    x = x.getParent(); 
                }

                else 
                {
                    if (temp.getLeftSon().isBlack())
                    {
                        temp.getRightSon().setColor(0); 
                        temp.setColor(1); 
                        leftRotate (temp); 
                        temp = x.getParent().getLeftSon(); 
                    }

                    temp.setColor(x.getParent().getColor()); 
                    x.getParent().setColor(0); 
                    temp.getLeftSon().setColor(0); 
                    rightRotate (x.getParent()); 
                    x = _root; 
                }
            }
            x.setColor(0);
        } 
    }

    /**
     * returns the successor BoxNode of a certain BoxNodeFrom.
     */
    public BoxNode getSuccessor(BoxNode BoxNodeFrom)
    {
        if(BoxNodeFrom.getRightSon() != null)
        {
            return getMin(BoxNodeFrom.getRightSon());
        }
        BoxNode temp = BoxNodeFrom.getParent();
        while ((temp != null) && (BoxNodeFrom == temp.getRightSon()))
        {
            BoxNodeFrom = temp;
            temp = temp.getParent();
        }
        return temp;
    }

    /**
     * Get the minimum Valued BoxNode from a given subtree
     */
    public BoxNode getMin(BoxNode BoxNodeFrom)
    {
        while (BoxNodeFrom.getLeftSon() != null)
        {
            BoxNodeFrom = BoxNodeFrom.getLeftSon();
        }
        return BoxNodeFrom;
    }

    /**
     * Get the maximum Valued BoxNode from a given subtree
     */
    public BoxNode getMax(BoxNode BoxNodeFrom)
    {
        while (BoxNodeFrom.getRightSon() != null)
        {
            BoxNodeFrom = BoxNodeFrom.getRightSon();
        }
        return BoxNodeFrom;
    }

    /**
     * search height in the Tree 
     * return the BoxNode Node if it exict, and NULL otherwise
     */
    public BoxNode searchByHeight(int boxCode)
    {
        BoxNode temp = _root;
        while (temp != null)
        {
            if (temp.getHeight() > boxCode)
            {
                temp = temp.getRightSon();
            }
            else if (temp.getHeight() < boxCode)
            {
                temp = temp.getLeftSon();
            }
            else
            {
                return temp;
            }
        }
        return null;
    }

    /**
     * check if there is a height
     */
    public boolean heightExist(int height)
    {
        BoxNode temp = searchByHeight(height);
        if(temp == null)
        { return false; }
        return true;        
    }

     /**
     * search side in the Tree 
     * return the BoxNode Node if it exict, and NULL otherwise
     */
    public BoxNode searchBySide(int boxCode)
    {
        BoxNode temp = _root;
        while (temp != null)
        {
            if (temp.getSide() > boxCode)
            {
                temp = temp.getRightSon();
            }
            else if (temp.getSide() < boxCode)
            {
                temp = temp.getLeftSon();
            }
            else
            {
                return temp;
            }
        }
        return null;
    }

    /**
     * check if there is a side
     */
    public boolean sideExist(int side)
    {
        BoxNode temp = searchBySide(side);
        if(temp == null)
        { return false; }
        return true;        
    }
}

NODE

public class BoxNode
{
    private int color=0; // black is 0 red is 1.
    private BoxNode rightSon, leftSon, parent; 

    private int _side;
    private int _height;
    private int _counter;
    private BoxesRedBlackTree _pointer;

    /**
     * Constructor
     */
    public BoxNode(int side,int height)
    {
        _side = side;
        _height = height;
    }

    public BoxNode(int side,int height,int counter)
    {
        _side = side;
        _height = height;
        _counter = counter;
    }

    public BoxNode(int side,int height, BoxesRedBlackTree pointer)
    {
        _side = side;
        _height = height;
        _pointer = pointer;
    }

    /**
     * Copy Constructor
     */    
    public BoxNode(BoxNode box)
    {
        _side = box._side;
        _height = box._height;
    }

    //get Method

    /**
     * get the height of the node
     */        
    public int getHeight()
    { 
        return _height; 
    }

    /**
     * get the side of the box
     */        
    public int getSide()
    { 
        return _side; 
    }

    public int getCounter()
    { 
        return _counter; 
    }

    public BoxesRedBlackTree getTree()
    { 
        return _pointer; 
    }

    /**
     * get the volume of the box
     */        
    public int getVolume()
    { 
        return (_side)*(_side)*(_height); 
    }

     public BoxNode getRightSon()
    {
        return rightSon;
    }

    public BoxNode getLeftSon()
    {
        return leftSon;
    }

    public BoxNode getParent()
    {
        return parent;
    }
    public int getColor()
    {
        return color;
    }

    //set Method

    /**
     * set the side
     */    
    public void setSide(int side)
    { 
        _side = side; 
    }

    /**
     * set the height
     */    
    public void setHeight(int height)
    { 
        _height = height; 
    }

    public void setCounter(int counter)
    { 
        _counter = counter; 
    }

    public void setTree(BoxesRedBlackTree pointer)
    { 
        _pointer = pointer; 
    }

    public void setRightSon(BoxNode toSet)
    {
        rightSon = toSet;
    }

    public void setLeftSon(BoxNode toSet)
    {
        leftSon = toSet;
    }

    public void setParent(BoxNode toSet )
    {
        parent = toSet;
    }

    public void setColor(int toSet)
    {
        if(toSet == 1 || toSet == 0)
        {
            color = toSet;
        }
    }


    public boolean isBigger(BoxNode other)
    {
        if(_side > other._side)
        {
            return true;
        }
        return false;
    }

    public boolean isBlack()
    { return true; }
}

1 个答案:

答案 0 :(得分:0)

您是否考虑过使用盒子的音量作为关键?在getBox方法中,您可以获得体积小于或等于side ^ 2 * height的框。然后,检查它是否适合给定的侧面和高度。如果没有,请尝试下一个更大的。这可以很好地执行,具体取决于您的盒子和礼物的大小。

如果您真的喜欢嵌套的红黑树,您可以执行以下操作: 1)找到最小边大于或等于给定边的sideNode。 2)找到最小高度大于或等于给定高度的heightNode。将其保存在名为minVolumeBox的变量中。 3)获取下一个sideNode。继续这样做,直到   a)您检查所有可用的sideNodes或   b)sideNode的边大于(minVolumeBox /给定高度的体积)。

案例3b将为您节省一些时间来检查每个节点。