Parce que les algorithmes basés sur les classes nécessaires pour atteindre test spécifique et démontrer arbre pas noir.
Source de référence Liens: https://blog.csdn.net/cdnight/article/details/10583177
Tout d'abord, les caractéristiques des arbres rouge-noir
(1) Chaque noeud est noir ou rouge.
(2) la racine est noire.
(3) chaque feuille (NIL) est noire.
(4) Si un nœud est rouge, ses nœuds enfants doivent être noirs.
(5) contiennent le même nombre de noir d'un noeud à tous les descendants du noeud de chemin d' accès de noeud.
Selon ces cinq caractéristiques peut savoir qu'elle a été arbre rouge-noir est équilibré, et la complexité temporelle de l' arbre de recherche est O (log (n))
D'autre part, la structure de l'arbre rouge-noir
1. L'unité de construction de l'arbre rouge-noir
public class TreeUnit {
public String color = "red";
public boolean isRed = true;
public char indexNO = 'A';
public TreeUnit _parent = null;
public TreeUnit _leftChild = null;
public TreeUnit _rightChild = null;
public boolean isNIL = false;
}
2. vérifier, insérer, supprimer
Rechercher
private void recursion_search(TreeUnit _currentNode, char indexNO) {
if (_currentNode == null) {
return;
}
if (indexNO == _currentNode.indexNO) {
this.search_result = true;
return;
}
if (indexNO < _currentNode.indexNO) {
if (_currentNode._leftChild == null) {
return;
}
recursion_search(_currentNode._leftChild, indexNO);
return;
}
if (indexNO > _currentNode.indexNO) {
if (_currentNode._rightChild == null) {
return;
}
recursion_search(_currentNode._rightChild, indexNO);
}
}
augmentation
public boolean insert(char indexNO) {
if (this._rootNode == null) {
this._rootNode = new TreeUnit();
this._rootNode.indexNO = indexNO;
this._rootNode.isRed = false;
return true;
}
TreeUnit parentUnit = recursion_search_fitParentNode(this._rootNode, indexNO);
if (parentUnit == null) {
return false;
}
TreeUnit minNode = new TreeUnit();
minNode.isRed = true;
minNode.indexNO = indexNO;
minNode._parent = parentUnit;
if (indexNO < parentUnit.indexNO) {
parentUnit._leftChild = minNode;
} else if (indexNO > parentUnit.indexNO) {
parentUnit._rightChild = minNode;
} else {
return false;
}
recursion_fixup_after_insert(minNode);
return true;
}
Supprimer
public boolean delete(char indexNO) {
TreeUnit originNode = search_node(indexNO);
TreeUnit rec_node = null;
TreeUnit nilNode = new TreeUnit();
nilNode.isNIL = true;
nilNode.isRed = false;
if (originNode == null) {
return false;
}
TreeUnit realDeletedNode = originNode;
if (originNode._rightChild == null) {
realDeletedNode = originNode;
} else {
realDeletedNode = recursion_search_real_deletedNode(originNode._rightChild);
}
if (realDeletedNode.indexNO == originNode.indexNO) {
TreeUnit parentNode = originNode._parent;
if (parentNode == null) {
if (originNode._leftChild == null) {
this._rootNode = null;
rec_node = null;
return true;
}
this._rootNode = originNode._leftChild;
this._rootNode._parent = null;
this._rootNode.isRed = false;
return true;
}
if (parentNode != null) {
boolean isLeft = false;
if (parentNode._leftChild != null && parentNode._leftChild.indexNO == originNode.indexNO) {
isLeft = true;
}
if (originNode.isRed) {
if (isLeft) {
parentNode._leftChild = null;
} else {
parentNode._rightChild = null;
}
return true;
}
boolean hasLeftChild = false;
if (originNode._leftChild != null) {
hasLeftChild = true;
}
if (isLeft) {
parentNode._leftChild = originNode._leftChild;
if (originNode._leftChild != null) {
originNode._leftChild._parent = parentNode;
}
} else if (!isLeft) {
parentNode._rightChild = originNode._leftChild;
if (originNode._leftChild != null) {
originNode._leftChild._parent = parentNode;
}
}
if (hasLeftChild) {
if (isLeft) {
recursion_fixup_afterDeletion(parentNode._leftChild);
} else {
recursion_fixup_afterDeletion(parentNode._rightChild);
}
return true;
}
nilNode._parent = parentNode;
if (isLeft) {
parentNode._leftChild = nilNode;
recursion_fixup_afterDeletion(parentNode._leftChild);
} else {
parentNode._rightChild = nilNode;
recursion_fixup_afterDeletion(parentNode._rightChild);
}
delNILNode(nilNode);
return true;
}
} else {
originNode.indexNO = realDeletedNode.indexNO;
TreeUnit parentNode = realDeletedNode._parent;
boolean isLeft = true;
if (parentNode._rightChild != null && parentNode._rightChild.indexNO == realDeletedNode.indexNO) {
isLeft = false;
}
if (realDeletedNode.isRed) {
if (isLeft) {
parentNode._leftChild = null;
return true;
}
parentNode._rightChild = null;
return true;
}
if (!realDeletedNode.isRed && realDeletedNode._rightChild != null && !realDeletedNode._rightChild.isNIL) {
if (isLeft) {
parentNode._leftChild = realDeletedNode._rightChild;
realDeletedNode._rightChild._parent = parentNode;
recursion_fixup_afterDeletion(realDeletedNode._leftChild);
return true;
}
System.out.println("【当真实节点为黑色并且拥有红色右子节点时,删除真实节点,将右子节点提升到同样位置,右子节点参与到位置调整】");
parentNode._rightChild = realDeletedNode._rightChild;
realDeletedNode._rightChild._parent = parentNode;
recursion_fixup_afterDeletion(parentNode._rightChild);
return true;
}
if (!realDeletedNode.isRed && (realDeletedNode._rightChild == null || (realDeletedNode._rightChild != null && realDeletedNode._rightChild.isNIL))) {
nilNode._parent = parentNode;
if (isLeft) {
parentNode._leftChild = nilNode;
} else {
parentNode._rightChild = nilNode;
}
recursion_fixup_afterDeletion(nilNode);
delNILNode(nilNode);
return true;
}
}
return true;
}
Trois, balancez Interface Builder
1. L'unité d'affichage
public class GraphNodeViewModel {
public char indexNO = 'A';
public boolean isRed = true;
public int xIndex = 0;
public int yIndex = 0;
public int locX = 0;
public int locY = 0;
public int HSep = 0;
public int VSep = 0;
public Object _cellObject = null;
public GraphNodeViewModel _parent = null;
public GraphNodeViewModel leftChild = null;
public GraphNodeViewModel rightChild = null;
public float leftNO = 0.0F;
public float rightNO = 0.0F;
public int leftChildLocX = 0;
public int rightChildLocX = 0;
}
2. suppressions vérifier la présentation
Par la
suppression
peut également être arbre rouge-noir modifié manuellement, ne pas faire cette démo blog
Le code source sur GitHub