Commit bee0dd95 authored by Kair's avatar Kair

RedBlackTree

parents
### IntelliJ IDEA ###
out/
!**/src/main/**/out/
!**/src/test/**/out/
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store
\ No newline at end of file
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="11" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/Console.iml" filepath="$PROJECT_DIR$/Console.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
public enum COLOR {
RED,
BLACK
}
import java.io.*;
public class Main {
public static void main(String[] args) {
RedBlackTree tree = new RedBlackTree();
tree.insert(1);
tree.insert(2);
tree.insert(3);
tree.insert(4);
tree.insert(5);
tree.insert(6);
tree.insert(7);
tree.insert(8);
tree.insert(9);
tree.insert(10);
tree.insert(11);
tree.insert(12);
tree.insert(13);
tree.insert(14);
tree.insert(15);
tree.insert(16);
tree.insert(17);
tree.insert(18);
tree.insert(19);
tree.insert(20);
tree.insert(21);
tree.insert(22);
tree.insert(23);
System.out.println("\\n");
print(System.out, tree.getRoot());
// System.out.println("");
// print(System.out, tree.getRoot());
}
// Tree tree = new Tree();
// tree.insert(1);
// tree.insert(2);
// tree.insert(3);
// tree.insert(4);
// tree.insert(5);
// tree.insert(6);
// tree.insert(7);
// tree.insert(8);
// tree.insert(9);
// tree.insert(10);
// tree.insert(12);
// tree.insert( 13);
// System.out.println("\\n");
// print(System.out, tree.getRoot());
// System.out.println("");
// tree.delete(8);
// print(System.out, tree.getRoot());
public static String traversePreOrder(Node root) {
if (root == null) {
return "";
}
StringBuilder sb = new StringBuilder();
sb.append(root.getData() + root.getColor().toString());
String pointerRight = "└──";
String pointerLeft = (root.getRight() != null) ? "├──" : "└──";
traverseNodes(sb, "", pointerLeft, root.getLeft(), root.getRight() != null);
traverseNodes(sb, "", pointerRight, root.getRight(), false);
return sb.toString();
}
public static void traverseNodes(StringBuilder sb, String padding, String pointer, Node node,
boolean hasRightSibling) {
if (node != null) {
sb.append("\n");
sb.append(padding);
sb.append(pointer);
sb.append(node.getData()+node.getColor().toString());
StringBuilder paddingBuilder = new StringBuilder(padding);
if (hasRightSibling) {
paddingBuilder.append("│ ");
} else {
paddingBuilder.append(" ");
}
String paddingForBoth = paddingBuilder.toString();
String pointerRight = "└──";
String pointerLeft = (node.getRight() != null) ? "├──" : "└──";
traverseNodes(sb, paddingForBoth, pointerLeft, node.getLeft(), node.getRight() != null);
traverseNodes(sb, paddingForBoth, pointerRight, node.getRight(), false);
}
}
public static void print(PrintStream os, Node tree) {
os.print(traversePreOrder(tree));
}
}
\ No newline at end of file
public class Node {
private int data;
private Node left;
private Node right;
private Node parent; // red-black tree
private int height; // AVL tree
private COLOR color; // red-black tree
public Node(int data) {
this.data = data;
}
public int getData() {
return data;
}
public COLOR getColor() {
return color;
}
public void setData(int data) {
this.data = data;
}
public Node getLeft() {
return left;
}
public void setLeft(Node left) {
this.left = left;
}
public Node getRight() {
return right;
}
public void setRight(Node right) {
this.right = right;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public void setColor(COLOR color) {
this.color = color;
}
public Node getParent() {
return parent;
}
public void setParent(Node parent) {
this.parent = parent;
}
}
public class NodeRB {
NodeRB leftNodeRB;
NodeRB rightNodeRB;
private byte color;
private int key;
public NodeRB(int key) {
this(key, null, null);
}
public NodeRB(int key, NodeRB left, NodeRB right) {
this.key = key;
this.leftNodeRB = left;
this.rightNodeRB = right;
}
public NodeRB getLeftNodeRB() {
return leftNodeRB;
}
public void setLeftNodeRB(NodeRB leftNodeRB) {
this.leftNodeRB = leftNodeRB;
}
public NodeRB getRightNodeRB() {
return rightNodeRB;
}
public void setRightNodeRB(NodeRB rightNodeRB) {
this.rightNodeRB = rightNodeRB;
}
public byte getColor() {
return color;
}
public void setColor(byte color) {
this.color = color;
}
public int getKey() {
return key;
}
public void setKey(int key) {
this.key = key;
}
}
\ No newline at end of file
public class RBTree {
private static final NodeRB EMPTY = new NodeRB(0);;
static {
EMPTY.leftNodeRB = EMPTY;
EMPTY.rightNodeRB = EMPTY;
}
protected NodeRB current;
private NodeRB parent;
private NodeRB grand;
private NodeRB ancestor;
private final NodeRB root;
static final byte RED = 0;
static final byte BLACK = 1;
public NodeRB getRoot() {
return root;
}
public RBTree(int rootKey) {
this.root = new NodeRB(rootKey);
this.root.setLeftNodeRB(EMPTY);
this.root.setRightNodeRB(EMPTY);
}
public void insert(int item) {
current = parent = grand = root;
EMPTY.setKey(item);
while (current.getKey() != item) {
ancestor = grand;
grand = parent;
parent = current;
current = item > current.getKey() ? current.getRightNodeRB() : current.getLeftNodeRB();
if (current.getLeftNodeRB().getColor() == RED && current.getRightNodeRB().getColor() == RED) {
rebalance(item);
}
}
if (current != EMPTY) {
return;
}
current = new NodeRB(item, EMPTY, EMPTY);
if (item < parent.getKey()) {
parent.setLeftNodeRB(current);
} else {
parent.setRightNodeRB(current);
}
rebalance(item);
}
private void rebalance(int item) {
current.setColor(RED);
current.getLeftNodeRB().setColor(BLACK);
current.getRightNodeRB().setColor(BLACK);
if (parent.getColor() == RED) {
grand.setColor(RED);
if (item < grand.getKey() != item < parent.getKey()) {
parent = rotate(item, grand);
}
current = rotate(item, ancestor);
current.setColor(BLACK);
}
root.getRightNodeRB().setColor(BLACK);
}
private NodeRB rotate(int item, NodeRB parent) {
if (item < parent.getKey()) {
NodeRB node = parent.getLeftNodeRB();
NodeRB result = item < node.getKey() ? rotateLeft(node) : rotateRight(node);
parent.setLeftNodeRB(result);
return parent.getLeftNodeRB();
} else {
NodeRB node = parent.getRightNodeRB();
NodeRB result = item < node.getKey() ? rotateLeft(node) : rotateRight(node);
parent.setRightNodeRB(result);
return parent.getRightNodeRB();
}
}
private NodeRB rotateLeft(NodeRB node) {
var left = node.getLeftNodeRB();
node.setLeftNodeRB(left.getRightNodeRB());
left.setRightNodeRB(node);
return left;
}
private NodeRB rotateRight(NodeRB node) {
var right = node.getRightNodeRB();
node.setRightNodeRB(right.getLeftNodeRB());
right.setLeftNodeRB(node);
return right;
}
}
\ No newline at end of file
public class RedBlackTree {
static final COLOR RED = COLOR.RED;
static final COLOR BLACK = COLOR.BLACK;
protected Node root;
public Node getRoot() {
return this.root;
}
public void insert(int key) {
Node node = root;
Node parent = null;
// Traverse the tree to the left or right depending on the key
while (node != null) {
parent = node;
if (key < node.getData()) {
node = node.getLeft();
} else if (key > node.getData()) {
node = node.getRight();
} else {
throw new IllegalArgumentException("Duplicated key " + key);
}
}
Node newNode = new Node(key);
newNode.setColor(RED);
if (parent == null) {
root = newNode;
} else if (key < parent.getData()) {
parent.setLeft(newNode);
} else {
parent.setRight(newNode);
}
newNode.setParent(parent);
recolor(newNode);
}
private void recolor(Node node) {
Node parent = node.getParent();
if (parent == null || parent.getColor() == BLACK) {
return;
}
Node grandparent = parent.getParent();
if (grandparent == null) {
parent.setColor(BLACK);
return;
}
Node uncle = getUncle(parent);
if (uncle != null && uncle.getColor() == RED) {
parent.setColor(BLACK);
grandparent.setColor(RED);
uncle.setColor(BLACK);
recolor(grandparent);
}
else if (parent == grandparent.getLeft()) {
if (node == parent.getRight()) {
rotateLeft(parent);
parent = node;
}
rotateRight(grandparent);
parent.setColor(BLACK);
grandparent.setColor(RED);
}
else {
if (node == parent.getLeft()) {
rotateRight(parent);
parent = node;
}
rotateLeft(grandparent);
parent.setColor(BLACK);
grandparent.setColor(RED);
}
}
private Node getUncle(Node parent) {
Node grandparent = parent.getParent();
return grandparent.getLeft() == parent ? grandparent.getRight() : grandparent.getLeft();
}
private void rotateRight(Node node) {
Node parent = node.getParent();
Node leftChild = node.getLeft();
node.setLeft(leftChild.getRight());
if (leftChild.getRight() != null) {
leftChild.getRight().setParent(node);
}
leftChild.setRight(node);
node.setParent(leftChild);
replaceParentsChild(parent, node, leftChild);
}
private void rotateLeft(Node node) {
Node parent = node.getParent();
Node rightChild = node.getRight();
node.setRight(rightChild.getLeft());
if (rightChild.getLeft() != null) {
rightChild.getLeft().setParent(node);
}
rightChild.setLeft(node);
node.setParent(rightChild);
replaceParentsChild(parent, node, rightChild);
}
private void replaceParentsChild(Node parent, Node oldChild, Node newChild) {
if (parent == null) {
root = newChild;
} else if (parent.getLeft() == oldChild) {
parent.setLeft(newChild);
} else if (parent.getRight() == oldChild) {
parent.setRight(newChild);
} else {
throw new IllegalStateException("Узел не является потомком");
}
if (newChild != null) {
newChild.setParent(parent);
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment