Java red/black 树节点插入的异常实现
Unusual Java implementation of red/black tree node insertion
我正在为 Java 中的 class 编写关于 red/black 树的程序。我对它们通常的工作方式有很好的了解,并且应该使用递归插入方法。我通常会使用下面的内容来匹配我教授的节点 class。关于颜色,0 为黑色,1 为红色。给我们的节点class根本不处理键
private static void put(int val, int col)
{ root = put(root, val, col); }
private static Node put(Node n, Integer val, int col)
{
if (n == null){
Node t=new Node(val);
t.setColor(1);
return t;
}
int cmp = val.compareTo(n.getValue());
if (cmp < 0) n.setLeft(put(n.getLeft(), val, col));
else if (cmp > 0) n.setRight(put(n.getRight(), val, col));
else n.setColor(col);
if (isRed(n.getRight()) && !isRed(n.getLeft())) n = rotateLeft(n);
if (isRed(n.getLeft()) && isRed(n.getLeft().getLeft())) n = rotateRight(n);
if (isRed(n.getLeft()) && isRed(n.getRight())) flipColors(n);
return n;
}
但是,要注意的是我们应该 return 一个布尔值——如果用户插入一个重复的值,因为树上已经存在,我们 return false 并且不附加节点。否则,我们附加它们并且 return true;为此提供给我们的代码如下,但不是递归的(项目要求的一部分)。虽然我没有正确实现平衡或旋转的方法,但 returned 布尔部分有效。
public boolean insertNode(Node node) {
//Here is just an example of setting colors for a node. So far, it is in green color. But you need to modify the code to dynamically adjust the color to
//either RED or BLACK according to the red-black logic
Node current_node;
// if the root exists
if (root == null) {
root = node; // let the root point to the current node
root.setColor(Node.BLACK);
return true;
} else {
current_node = root;
node.setColor(1);
while (current_node != null) {
int value = current_node.getValue();
if (node.getValue() < value){ // go to the left sub-tree
if (current_node.getLeft() != null) // if the left node is not empty
current_node = current_node.getLeft();
else{ // put node as the left child of current_node
current_node.setLeft(node);
node.setParent(current_node);
current_node = null; }
//System.out.println("Left:"+current_node);
}
else if (node.getValue() > value){ // go to the right
if (current_node.getRight() != null) // if the right node is not empty
current_node = current_node.getRight();
else{ // put node as the right child of current_node
current_node.setRight(node);
node.setParent(current_node);
current_node = null; }
//System.out.println("Right: "+current_node);
}
else{
//System.out.println("Else: "+current_node);
return false; }
//if(current_node!=null&¤t_node.getLeft()!=null&¤t_node.getRight()!=null&¤t_node.getLeft().isRed()&¤t_node.getRight().isRed())
// flipColors(node);
}
}
if(node.getParent()!=null){
node=node.getParent();
System.out.println("Case: node has parent, val="+node.getValue());
}
if(node.getLeft()!=null&&node.getRight()!=null){
if((node.getRight().isRed())&&!node.getLeft().isRed())
node=rotateLeft(node);
if((node.getLeft().isRed())&&(node.getParent()!=null)&&(node.getParent().getLeft().getLeft()!=null)&&(node.getParent().getLeft().getLeft().isRed()))
node=rotateRight(node);
if((node.getLeft().isRed()) && (node.getRight().isRed()))
flipColors(node);
}
return true;
}
我无法在网上找到任何可比较的实现,似乎布尔值对于程序的 gui 正常工作是必需的。如果有人对从哪里开始有好的建议,我将不胜感激!
对于递归 insertNode,我建议您执行以下操作:创建一个函数 insertNode(Node node, Node current_node)
,其中 returns 一个 boolean
值。这个想法是始终为当前调查的节点调用函数 insertNode,从根节点开始。如果无法立即将节点添加到current_node,则递归调用负责节点来处理该节点。我已经根据您的代码为您提供了一个简短的示例(带有一些注释,基本思想是什么,显然缺少一些东西)。希望我正确回答了您的问题,这有助于您理解。
public boolean insertNode(Node node) {
if (root == null) {
root = node;
root.setColor(Node.BLACK);
return true;
} else {
boolean result = insertNode(node, root);
if (result) {
//Some other important stuff to do...
}
return result;
}
}
public boolean insertNode(Node node, Node current_node) {
int value = current_node.getValue();
if (node.getValue() < value) {
if (current_node.getLeft() != null) {
// Investigate left
return insertNode(node, current_node.getLeft());
} else {
// Insert node left
return true;
}
} else if (node.getValue() > value) {
if (current_node.getRight() != null) {
// Investigate right
return insertNode(node, current_node.getRight());
} else {
// Insert node right
return true;
}
} else {
return false;
}
}
我现在的工作函数如下:
public boolean insertNode(Node node) {
if(root==null){
root=node;
root.setColor(Node.BLACK);
return true;
}
else
node.setColor(Node.RED);
return insertNode(node, root);
}
public boolean insertNode(Node node, Node cur){
if(node.getValue()<cur.getValue()){
if(cur.getLeft()!=null)
return insertNode(node, cur.getLeft());
else{
cur.setLeft(node);
node.setParent(cur);
handleInsertion(node);
return true; } }
else if(node.getValue()>cur.getValue()){
if(cur.getRight()!=null)
return insertNode(node, cur.getRight());
else{
cur.setRight(node);
node.setParent(cur);
handleInsertion(node);
return true; } }
else
return false;
}
我正在为 Java 中的 class 编写关于 red/black 树的程序。我对它们通常的工作方式有很好的了解,并且应该使用递归插入方法。我通常会使用下面的内容来匹配我教授的节点 class。关于颜色,0 为黑色,1 为红色。给我们的节点class根本不处理键
private static void put(int val, int col)
{ root = put(root, val, col); }
private static Node put(Node n, Integer val, int col)
{
if (n == null){
Node t=new Node(val);
t.setColor(1);
return t;
}
int cmp = val.compareTo(n.getValue());
if (cmp < 0) n.setLeft(put(n.getLeft(), val, col));
else if (cmp > 0) n.setRight(put(n.getRight(), val, col));
else n.setColor(col);
if (isRed(n.getRight()) && !isRed(n.getLeft())) n = rotateLeft(n);
if (isRed(n.getLeft()) && isRed(n.getLeft().getLeft())) n = rotateRight(n);
if (isRed(n.getLeft()) && isRed(n.getRight())) flipColors(n);
return n;
}
但是,要注意的是我们应该 return 一个布尔值——如果用户插入一个重复的值,因为树上已经存在,我们 return false 并且不附加节点。否则,我们附加它们并且 return true;为此提供给我们的代码如下,但不是递归的(项目要求的一部分)。虽然我没有正确实现平衡或旋转的方法,但 returned 布尔部分有效。
public boolean insertNode(Node node) {
//Here is just an example of setting colors for a node. So far, it is in green color. But you need to modify the code to dynamically adjust the color to
//either RED or BLACK according to the red-black logic
Node current_node;
// if the root exists
if (root == null) {
root = node; // let the root point to the current node
root.setColor(Node.BLACK);
return true;
} else {
current_node = root;
node.setColor(1);
while (current_node != null) {
int value = current_node.getValue();
if (node.getValue() < value){ // go to the left sub-tree
if (current_node.getLeft() != null) // if the left node is not empty
current_node = current_node.getLeft();
else{ // put node as the left child of current_node
current_node.setLeft(node);
node.setParent(current_node);
current_node = null; }
//System.out.println("Left:"+current_node);
}
else if (node.getValue() > value){ // go to the right
if (current_node.getRight() != null) // if the right node is not empty
current_node = current_node.getRight();
else{ // put node as the right child of current_node
current_node.setRight(node);
node.setParent(current_node);
current_node = null; }
//System.out.println("Right: "+current_node);
}
else{
//System.out.println("Else: "+current_node);
return false; }
//if(current_node!=null&¤t_node.getLeft()!=null&¤t_node.getRight()!=null&¤t_node.getLeft().isRed()&¤t_node.getRight().isRed())
// flipColors(node);
}
}
if(node.getParent()!=null){
node=node.getParent();
System.out.println("Case: node has parent, val="+node.getValue());
}
if(node.getLeft()!=null&&node.getRight()!=null){
if((node.getRight().isRed())&&!node.getLeft().isRed())
node=rotateLeft(node);
if((node.getLeft().isRed())&&(node.getParent()!=null)&&(node.getParent().getLeft().getLeft()!=null)&&(node.getParent().getLeft().getLeft().isRed()))
node=rotateRight(node);
if((node.getLeft().isRed()) && (node.getRight().isRed()))
flipColors(node);
}
return true;
}
我无法在网上找到任何可比较的实现,似乎布尔值对于程序的 gui 正常工作是必需的。如果有人对从哪里开始有好的建议,我将不胜感激!
对于递归 insertNode,我建议您执行以下操作:创建一个函数 insertNode(Node node, Node current_node)
,其中 returns 一个 boolean
值。这个想法是始终为当前调查的节点调用函数 insertNode,从根节点开始。如果无法立即将节点添加到current_node,则递归调用负责节点来处理该节点。我已经根据您的代码为您提供了一个简短的示例(带有一些注释,基本思想是什么,显然缺少一些东西)。希望我正确回答了您的问题,这有助于您理解。
public boolean insertNode(Node node) {
if (root == null) {
root = node;
root.setColor(Node.BLACK);
return true;
} else {
boolean result = insertNode(node, root);
if (result) {
//Some other important stuff to do...
}
return result;
}
}
public boolean insertNode(Node node, Node current_node) {
int value = current_node.getValue();
if (node.getValue() < value) {
if (current_node.getLeft() != null) {
// Investigate left
return insertNode(node, current_node.getLeft());
} else {
// Insert node left
return true;
}
} else if (node.getValue() > value) {
if (current_node.getRight() != null) {
// Investigate right
return insertNode(node, current_node.getRight());
} else {
// Insert node right
return true;
}
} else {
return false;
}
}
我现在的工作函数如下:
public boolean insertNode(Node node) {
if(root==null){
root=node;
root.setColor(Node.BLACK);
return true;
}
else
node.setColor(Node.RED);
return insertNode(node, root);
}
public boolean insertNode(Node node, Node cur){
if(node.getValue()<cur.getValue()){
if(cur.getLeft()!=null)
return insertNode(node, cur.getLeft());
else{
cur.setLeft(node);
node.setParent(cur);
handleInsertion(node);
return true; } }
else if(node.getValue()>cur.getValue()){
if(cur.getRight()!=null)
return insertNode(node, cur.getRight());
else{
cur.setRight(node);
node.setParent(cur);
handleInsertion(node);
return true; } }
else
return false;
}