我陷入了一项任务,我可以使用一些帮助。基本上,我的工作是设计一个包装礼物的工厂。我们的股票是方形底座(不一定是立方体)。对于每个盒子,我们知道盒子底部的尺寸(我称之为侧面)和高度(高度)。当工厂收到包装礼物的请求时,顾客知道适合当前的最小盒子的侧面和高度值,但是我们将为盒子提供我们目前最小的体积。
我们的想法是规划一个数据结构来管理这些盒子。数据结构必须支持以下方法:
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; }
}
答案 0 :(得分:0)
您是否考虑过使用盒子的音量作为关键?在getBox方法中,您可以获得体积小于或等于side ^ 2 * height的框。然后,检查它是否适合给定的侧面和高度。如果没有,请尝试下一个更大的。这可以很好地执行,具体取决于您的盒子和礼物的大小。
如果您真的喜欢嵌套的红黑树,您可以执行以下操作: 1)找到最小边大于或等于给定边的sideNode。 2)找到最小高度大于或等于给定高度的heightNode。将其保存在名为minVolumeBox的变量中。 3)获取下一个sideNode。继续这样做,直到 a)您检查所有可用的sideNodes或 b)sideNode的边大于(minVolumeBox /给定高度的体积)。
案例3b将为您节省一些时间来检查每个节点。