我正在研究红黑树并写下我在下面显示的完整工作代码。我浏览了泛型教程,并了解到使用单类声明,可以指定一组相关方法。如何将其应用于我的红黑树算法?仿制药案例中会发生什么?如果可能的话,你可以帮帮我吗?这是完整的代码:
import java.util.Scanner;
public class RedBlackTree {
private final int RED = 0;
private final int BLACK = 1;
private class Node {
int key = -1, color = BLACK;
Node left = nil, right = nil, parent = nil;
Node(int key) {
this.key = key;
}
}
private final Node nil = new Node(-1);
private Node root = nil;
public void printTree(Node node)
{
if (node == nil) {
return;
}
printTree(node.left);
System.out.print(((node.color==RED)?"Color: Red ":"Color: Black ")+"Key: "+node.key+" Parent: "+node.parent.key+"\n");
printTree(node.right);
}
private Node findNode(Node findNode, Node node)
{
if (root == nil) {
return null;
}
if (findNode.key < node.key) {
if (node.left != nil) {
return findNode(findNode, node.left);
}
} else if (findNode.key > node.key) {
if (node.right != nil) {
return findNode(findNode, node.right);
}
} else if (findNode.key == node.key) {
return node;
}
return null;
}
private void insert(Node node)
{
Node temp = root;
if (root == nil) {
root = node;
node.color = BLACK;
node.parent = nil;
} else {
node.color = RED;
while (true) {
if (node.key < temp.key) {
if (temp.left == nil) {
temp.left = node;
node.parent = temp;
break;
} else {
temp = temp.left;
}
} else if (node.key >= temp.key) {
if (temp.right == nil) {
temp.right = node;
node.parent = temp;
break;
} else {
temp = temp.right;
}
}
}
fixTree(node);
}
}
private void fixTree(Node node)
{
while (node.parent.color == RED) {
Node uncle = nil;
if (node.parent == node.parent.parent.left) {
uncle = node.parent.parent.right;
if (uncle != nil && uncle.color == RED) {
node.parent.color = BLACK;
uncle.color = BLACK;
node.parent.parent.color = RED;
node = node.parent.parent;
continue;
}
if (node == node.parent.right) {
//Double rotation needed
node = node.parent;
rotateLeft(node);
}
node.parent.color = BLACK;
node.parent.parent.color = RED;
//if the "else if" code hasn't executed, this
//is a case where we only need a single rotation
rotateRight(node.parent.parent);
} else {
uncle = node.parent.parent.left;
if (uncle != nil && uncle.color == RED) {
node.parent.color = BLACK;
uncle.color = BLACK;
node.parent.parent.color = RED;
node = node.parent.parent;
continue;
}
if (node == node.parent.left) {
//Double rotation needed
node = node.parent;
rotateRight(node);
}
node.parent.color = BLACK;
node.parent.parent.color = RED;
rotateLeft(node.parent.parent);
}
}
root.color = BLACK;
}
void rotateLeft(Node node)
{
if (node.parent != nil) {
if (node == node.parent.left) {
node.parent.left = node.right;
} else {
node.parent.right = node.right;
}
node.right.parent = node.parent;
node.parent = node.right;
if (node.right.left != nil) {
node.right.left.parent = node;
}
node.right = node.right.left;
node.parent.left = node;
} else {//Need to rotate root
Node right = root.right;
root.right = right.left;
right.left.parent = root;
root.parent = right;
right.left = root;
right.parent = nil;
root = right;
}
}
void rotateRight(Node node)
{
if (node.parent != nil) {
if (node == node.parent.left) {
node.parent.left = node.left;
} else {
node.parent.right = node.left;
}
node.left.parent = node.parent;
node.parent = node.left;
if (node.left.right != nil) {
node.left.right.parent = node;
}
node.left = node.left.right;
node.parent.right = node;
} else {//Need to rotate root
Node left = root.left;
root.left = root.left.right;
left.right.parent = root;
root.parent = left;
left.right = root;
left.parent = nil;
root = left;
}
}
void replace(Node target, Node with){
if(target.parent == nil){
root = with;
}else if(target == target.parent.left){
target.parent.left = with;
}else
target.parent.right = with;
with.parent = target.parent;
}
boolean delete(Node z){
if((z = findNode(z, root))==null)
return false;
Node x;
Node y = z;
int y_original_color = y.color;
if(z.left == nil){
x = z.right;
replace(z, z.right);
}else if(z.right == nil){
x = z.left;
replace(z, z.left);
}else{
y = treeMinimum(z.right);
y_original_color = y.color;
x = y.right;
if(y.parent == z)
x.parent = y;
else{
replace(y, y.right);
y.right = z.right;
y.right.parent = y;
}
replace(z, y);
y.left = z.left;
y.left.parent = y;
y.color = z.color;
}
if(y_original_color==BLACK)
fixDelColor(x);
return true;
}
void fixDelColor(Node x){
while(x!=root && x.color == BLACK){
if(x == x.parent.left){
Node w = x.parent.right;
if(w.color == RED){
w.color = BLACK;
x.parent.color = RED;
rotateLeft(x.parent);
w = x.parent.right;
}
if(w.left.color == BLACK && w.right.color == BLACK){
w.color = RED;
x = x.parent;
continue;
}
else if(w.right.color == BLACK){
w.left.color = BLACK;
w.color = RED;
rotateRight(w);
w = x.parent.right;
}
if(w.right.color == RED){
w.color = x.parent.color;
x.parent.color = BLACK;
w.right.color = BLACK;
rotateLeft(x.parent);
x = root;
}
}else{
Node w = x.parent.left;
if(w.color == RED){
w.color = BLACK;
x.parent.color = RED;
rotateRight(x.parent);
w = x.parent.left;
}
if(w.right.color == BLACK && w.left.color == BLACK){
w.color = RED;
x = x.parent;
continue;
}
else if(w.left.color == BLACK){
w.right.color = BLACK;
w.color = RED;
rotateLeft(w);
w = x.parent.left;
}
if(w.left.color == RED){
w.color = x.parent.color;
x.parent.color = BLACK;
w.left.color = BLACK;
rotateRight(x.parent);
x = root;
}
}
}
x.color = BLACK;
}
Node treeMinimum(Node subTreeRoot)
{
while(subTreeRoot.left!=nil){
subTreeRoot = subTreeRoot.left;
}
return subTreeRoot;
}
public void consoleUI() {
Scanner scan = new Scanner(System.in);
while (true) {
System.out.println("\n1. Insert () method\n"
+ "2. ToString() method\n"
+ "3. Contains() method\n"
+ "4. Delete() method\n"
+ "5. Exit \n");
int choice = scan.nextInt();
int item;
Node node;
switch (choice) {
case 1:
item = scan.nextInt();
while (item != 001) {
node = new Node(item);
insert(node);
item = scan.nextInt();
}
printTree(root);
break;
case 2:
printTree(root);
break;
case 3:
item = scan.nextInt();
while (item != 001) {
node = new Node(item);
System.out.println((findNode(node, root) != null) ? "found" : "not found");
item = scan.nextInt();
}
break;
case 4:
item = scan.nextInt();
while (item != 001) {
node = new Node(item);
System.out.print("\nDeleting item " + item);
if (delete(node)) {
System.out.print(": deleted!");
} else {
System.out.print(": entered item does not exist!");
}
item = scan.nextInt();
}
System.out.println();
printTree(root);
break;
case 5:
return;
}
}
}
public static void main(String[] args) {
RedBlackTree redblacktree = new RedBlackTree();
redblacktree.consoleUI();
}
}
答案 0 :(得分:0)
通用化的基本步骤:
班级声明:
class RedBlackTree<KeyType extends Comparable<KeyType>, ValueType>
假设每个节点存储两个值 - 一个确定有序树内位置的键和一个不能确定值的可空值。 ValueType
是可选的,但它确实以树的形式提供了有效的地图实现。
(除此之外基于4castle的评论:将Comparable<KeyType>
替换为Comparable<? super KeyType>
是没有意义的,因为不可能将非KeyType
插入树中
类实现(Node
类):将int key
的两种情况替换为KeyType key
;添加实例变量ValueType val
(可选)。如果添加了ValueType,则Node构造函数变为:
Node(KeyValue key, KeyValue val) {
this.key = key;
this.val = val;
}
在consoleUI
声明中,类使用(方法KeyType
),类型实例化ValueType
和Node
,例如:
Node<Integer, String> node;
...
node = new Node(item, val);
或
Node<Integer, Void> node;
...
node = new Node(item, null);
*结果*
import java.util.Scanner;
public class RedBlackTree<KeyType extends Comparable<KeyType>, ValueType> {
private static final int RED = 0;
private static final int BLACK = 1;
private static final Node nil = new Node(-1); ******
private Node root = nil;
private class Node {
KeyType key;
ValueType val;
color = BLACK;
Node left = nil, right = nil, parent = nil;
Node(int key) {
this.key = key;
this.val = val;
}
}
// believe remaining code is unchanged (except for adding val param)
// ...
// ...
public void consoleUI() {
Scanner scan = new Scanner(System.in);
while (true) {
System.out.println("\n1. Insert () method\n"
+ "2. ToString() method\n"
+ "3. Contains() method\n"
+ "4. Delete() method\n"
+ "5. Exit \n");
int choice = scan.nextInt();
int item;
Node<Integer, Void> node;
switch (choice) {
case 1:
item = scan.nextInt();
while (item != 001) {
node = new Node(item, null);
etc
一般建议:将您的班级分解为2.将树使用隐藏在树类本身内是没有意义的。创建课程调用RedBlackTreeTest
并将consoleUI
和main
移入其中。