In Nomine Patris
Hic articulus est de arboribus quaesitis binariis. Ego nuper feci super articulum
Lignum est structura data nodorum constans marginibus connexis. Dici possumus arborem specialem graphi casum esse. Exemplum est hic arbor;
Hoc lignum non binarium quaesitum est! Omnia abscinduntur!
terminology
radix
Arbor radix β Haec summa nodi est. In exemplo, haec est nodi A. In arbore, una tantum via ab radice in aliam nodi potest ducere! Revera, quaevis nodi considerari potest ut radix subtidis huic nodi correspondens.
Parentibus / posteris
Omnes nodi praeter radicem unam prorsus habent partem nodi ad alteram ducens. Nodus supra hodiernam sita appellatur parent hac nodo. Nodus infra currenti sito et ei conexus appellatur progenies hac nodo. Utamur exemplo. Sit nodi B, parens node A, et filii eius nodes D, E, F erunt.
sheet
Node quae liberos non habet, folium arboris vocabitur. In exemplo, folia erunt nodes D, E, F, G, I, J, K.
Haec est fundamentalis vox. Aliae notiones ulterius dicentur. Binaria ergo arbor est in qua quilibet nodus non plus quam duos filios habebit. Ut tu suspicabaris, arbor ab exemplo non erit binaria, quia nodi B, H plures quam duo filii habent. Exemplum est arboris binariae;
Nodorum arbor aliqua indicia continere potest. Lignum quaesitum binarium est arbor binaria quae sequentes proprietates habet;
- Tam dextra laevaque subtree sunt arbores quaesitae binariae.
- Omnes nodi sinistrae subtree nodi X arbitrarii clavem datam habent minus quam valorem clavis nodi X ipsius notitiae.
- Omnes nodi in dextra parte nodi arbitrarii X habent valorem clavem datam maiorem quam vel aequalem valore ipsius datae clavis nodi X.
clavem β quaelibet nodi proprietas (exempli gratia, numerus). Clavis necessaria est ut elementum ligni invenire possis cui haec clavis correspondet. Exemplum arboris binariae inquisitionis:
Visum lignum
Dum progredimur, nonnulla codicis fragmenta (fortasse incompleta) praebebo ut intelligentiam tuam corrigant. Codex plenus erit in fine articuli.
Lignum nodis constat. Nodi compages;
public class Node<T> {
private T data;
private int key;
private Node<T> leftChild;
private Node<T> rightChild;
public Node(T data, int key) {
this.data = data;
this.key = key;
}
public Node<T> getLeftChild() {
return leftChild;
}
public Node<T> getRightChild() {
return rightChild;
}
//...ΠΎΡΡΠ°Π»ΡΠ½ΡΠ΅ ΠΌΠ΅ΡΠΎΠ΄Ρ ΡΠ·Π»Π°
}
Uterque nodi duos filios habet (fate enim fieri potest ut filii sinistri et/vel dextrae infantes nullum valorem contineant). Probabiliter intellexistis numerum notitiarum in hoc casu esse notas in nodo conditas esse; clavis β nodi clavis.
Nodum digesti sumus, nunc de arboribus instantibus quaestionibus loquimur. Postmodum verbo "arboris" conceptum ligni binarii quaesiti designabo. Structura ligni binarii;
public class BinaryTree<T> {
private Node<T> root;
//ΠΌΠ΅ΡΠΎΠ΄Ρ Π΄Π΅ΡΠ΅Π²Π°
}
Tantum radicem arboris ut genus agri egent, quia ab radice, utendo getLeftChild() et modos get, ad quamlibet nodi in arbore licebit pervenire.
Algorithms in arbore
ΠΠΎΠΈΡΠΊ
Dicamus te arborem constructam habere. Quomodo elementum clavem invenire? Opus gradatim ex radice de arbore moveri et valorem clavis cum nodo proximae clavibus compara: si clavis minor est quam clavis nodi proximi, tum ad sinistram nodi prolem, si est. major, dextrorsum, si claves sunt aequales, nodi desideratus invenitur! Relevant codicem:
public Node<T> find(int key) {
Node<T> current = root;
while (current.getKey() != key) {
if (key < current.getKey())
current = current.getLeftChild();
else
current = current.getRightChild();
if (current == null)
return null;
}
return current;
}
Si vena nulla fit, quaesitio ad finem arboris (in gradu rationis, in loco non existente in arbore es - ortus folii).
Consideremus efficaciam investigationis algorithmus in arbore librata (arbor in qua nodi plus minus aequaliter distribuuntur). Tunc efficientiae inquisitionis erit O(log(n)), et logarithmus est basis 2. Vide: si elementa n sunt in arbore librata, hoc significat quod log(n) erit ad bases 2 gradus. Arbor. Et quaerens in uno gradu cycli descendis uno gradu.
inserere
Si essentiam inquisitionis comprehendis, tunc insertionem intelligendi difficile tibi non erit. Vos iustus postulo ut descendat ad folium arboris (secundum regulas descensus in inquisitione descriptos) et fiet eius descendens - laeva sive dextera secundum clavem. Exsecutio:
public void insert(T insertData, int key) {
Node<T> current = root;
Node<T> parent;
Node<T> newNode = new Node<>(insertData, key);
if (root == null)
root = newNode;
else {
while (true) {
parent = current;
if (key < current.getKey()) {
current = current.getLeftChild();
if (current == null) {
parent.setLeftChild(newNode);
return;
}
}
else {
current = current.getRightChild();
if (current == null) {
parent.setRightChild(newNode);
return;
}
}
}
}
}
In hoc casu, praeter nodi hodiernae, informationem de parente nodi hodiernae condere necesse est. Cum vena nulla aequalis fit, parens variabilis schedam quae nobis necessaria est continebit.
Insertionis efficientia eadem plane erit ac inquisitionis - O (log(n)).
removal
Remotio est operatio difficillima quae in ligno confici debet. Perspicuum est primum elementum quod deleturi sumus invenire debebimus. Sed quid tum? Si tantum referat ad nullum, amittemus informationes de subtilitate cuius radix hic nodi est. Arbor remotionis methodi in tres casus dividuntur.
Casus primus. Nodus deletus liberos non habet
Si nodi deletae liberos non habent, id significat quod folium est. Unde simpliciter potes collocare agros sinistrae fili vel dexterae parentis ad nullum.
Secundus casus. Nodus delendus habet unum puerum
Hoc etiam non admodum perplexum est. Redeamus ad exemplum nostrum. Dicamus nos elementum clavis delere necesse est 14. Esto consentiens, cum id sit ius nodi cum clavibus 10 descendens, deinde quaelibet posteris (in hoc casu dextra) clavem maiorem quam 10, sic habebis. facile potest eam ex arbore secare et parentem ad prolem nodi deletam directe coniungere, i.e. nodi connectere cum clavis 10 ad nodi 13. Similis res esset si nodi deleretur, qui est filius sinistrae parentis sui. Te ipsum cogita - an accurata analogia.
Tertius casus. A nodi duos filios habet
Difficillima causa. Inspiciamus novum exemplum.
Quaere successorem
Dicamus nos nodi clavi delere 25. Quis in eius loco ponere debeamus? Unus e suis asseclis (nepotes vel posteritas) fiet successor(ille, qui remoto nodo succedet).
Quomodo intellegendum est, quis successor factus sit? Intuitive, hic est nodi in arbore cuius clavis est maxima proxima a nodo deleta. Algorithmus talis est. Ad dextram eius descende (semper ad dextram, quia iam dictum est successorem clavem maiorem esse quam clavem nodi deletam), et deinde per catenam posteris sinistri huius dexterae propaginis. . In exemplo, ad nodi cum clavibus iremus 35, et tunc descendamus ad folium per catenam filii sui sinistri β in hoc casu, haec catena sola nodi consistit in clavibus 30. Proprie nos querimus. nam nodi minimi in nodis statuto majores quam nos nodi quaerimus.
Successor inquisitionis modum code:
public Node<T> getSuccessor(Node<T> deleteNode) {
Node<T> parentSuccessor = deleteNode;//ΡΠΎΠ΄ΠΈΡΠ΅Π»Ρ ΠΏΡΠ΅Π΅ΠΌΠ½ΠΈΠΊΠ°
Node<T> successor = deleteNode;//ΠΏΡΠ΅Π΅ΠΌΠ½ΠΈΠΊ
Node<T> current = successor.getRightChild();//ΠΏΡΠΎΡΡΠΎ "ΠΏΡΠΎΠ±Π΅Π³Π°ΡΡΠΈΠΉ" ΡΠ·Π΅Π»
while (current != null) {
parentSuccessor = successor;
successor = current;
current = current.getLeftChild();
}
//Π½Π° Π²ΡΡ
ΠΎΠ΄Π΅ ΠΈΠ· ΡΠΈΠΊΠ»Π° ΠΈΠΌΠ΅Π΅ΠΌ ΠΏΡΠ΅Π΅ΠΌΠ½ΠΈΠΊΠ° ΠΈ ΡΠΎΠ΄ΠΈΡΠ΅Π»Ρ ΠΏΡΠ΅Π΅ΠΌΠ½ΠΈΠΊΠ°
if (successor != deleteNode.getRightChild()) {//Π΅ΡΠ»ΠΈ ΠΏΡΠ΅Π΅ΠΌΠ½ΠΈΠΊ Π½Π΅ ΡΠΎΠ²ΠΏΠ°Π΄Π°Π΅Ρ Ρ ΠΏΡΠ°Π²ΡΠΌ ΠΏΠΎΡΠΎΠΌΠΊΠΎΠΌ ΡΠ΄Π°Π»ΡΠ΅ΠΌΠΎΠ³ΠΎ ΡΠ·Π»Π°
parentSuccessor.setLeftChild(successor.getRightChild());//ΡΠΎ Π΅Π³ΠΎ ΡΠΎΠ΄ΠΈΡΠ΅Π»Ρ Π·Π°Π±ΠΈΡΠ°Π΅Ρ ΡΠ΅Π±Π΅ ΠΏΠΎΡΠΎΠΌΠΊΠ° ΠΏΡΠ΅Π΅ΠΌΠ½ΠΈΠΊΠ°, ΡΡΠΎΠ±Ρ Π½Π΅ ΠΏΠΎΡΠ΅ΡΡΡΡ Π΅Π³ΠΎ
successor.setRightChild(deleteNode.getRightChild());//ΡΠ²ΡΠ·ΡΠ²Π°Π΅ΠΌ ΠΏΡΠ΅Π΅ΠΌΠ½ΠΈΠΊΠ° Ρ ΠΏΡΠ°Π²ΡΠΌ ΠΏΠΎΡΠΎΠΌΠΊΠΎΠΌ ΡΠ΄Π°Π»ΡΠ΅ΠΌΠΎΠ³ΠΎ ΡΠ·Π»Π°
}
return successor;
}
Plena code ad modum delete:
public boolean delete(int deleteKey) {
Node<T> current = root;
Node<T> parent = current;
boolean isLeftChild = false;//Π Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ ΠΎΡ ΡΠΎΠ³ΠΎ, ΡΠ²Π»ΡΠ΅ΡΡΡ Π»ΠΈ ΡΠ΄Π°Π»ΡΠ΅ΠΌΡΠΉ ΡΠ·Π΅Π» Π»Π΅Π²ΡΠΌ ΠΈΠ»ΠΈ ΠΏΡΠ°Π²ΡΠΌ ΠΏΠΎΡΠΎΠΌΠΊΠΎΠΌ ΡΠ²ΠΎΠ΅Π³ΠΎ ΡΠΎΠ΄ΠΈΡΠ΅Π»Ρ, Π±ΡΠ»Π΅Π²ΡΠΊΠ°Ρ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ isLeftChild Π±ΡΠ΄Π΅Ρ ΠΏΡΠΈΠ½ΠΈΠΌΠ°ΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ true ΠΈΠ»ΠΈ false ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²Π΅Π½Π½ΠΎ.
while (current.getKey() != deleteKey) {
parent = current;
if (deleteKey < current.getKey()) {
current = current.getLeftChild();
isLeftChild = true;
} else {
isLeftChild = false;
current = current.getRightChild();
}
if (current == null)
return false;
}
if (current.getLeftChild() == null && current.getRightChild() == null) {//ΠΏΠ΅ΡΠ²ΡΠΉ ΡΠ»ΡΡΠ°ΠΉ
if (current == root)
current = null;
else if (isLeftChild)
parent.setLeftChild(null);
else
parent.setRightChild(null);
}
else if (current.getRightChild() == null) {//Π²ΡΠΎΡΠΎΠΉ ΡΠ»ΡΡΠ°ΠΉ
if (current == root)
root = current.getLeftChild();
else if (isLeftChild)
parent.setLeftChild(current.getLeftChild());
else
current.setRightChild(current.getLeftChild());
} else if (current.getLeftChild() == null) {
if (current == root)
root = current.getRightChild();
else if (isLeftChild)
parent.setLeftChild(current.getRightChild());
else
parent.setRightChild(current.getRightChild());
}
else {//ΡΡΠ΅ΡΠΈΠΉ ΡΠ»ΡΡΠ°ΠΉ
Node<T> successor = getSuccessor(current);
if (current == root)
root = successor;
else if (isLeftChild)
parent.setLeftChild(successor);
else
parent.setRightChild(successor);
}
return true;
}
Complexitas ad O(log(n)) approximari potest.
Inveniens maximum / minimum in arbore
Patet quomodo invenire valorem minimum in arbore - sequentiter moveri debes per catenam elementorum sinistrae dextrae arboris, respective; cum ad schedam perveneris, elementum minimum/maximum erit.
public Node<T> getMinimum(Node<T> startPoint) {
Node<T> current = startPoint;
Node<T> parent = current;
while (current != null) {
parent = current;
current = current.getLeftChild();
}
return parent;
}
public Node<T> getMaximum(Node<T> startPoint) {
Node<T> current = startPoint;
Node<T> parent = current;
while (current != null) {
parent = current;
current = current.getRightChild();
}
return parent;
}
Complexionis - O (log(n))
Symmetrica bypass
Traversal invisit unumquemque nodi arboris ut cum eo aliquid agat.
Symmetria recursiva algorithmus traversalis:
- Facere actionem sinistro infante
- Facere actionem tecum
- Facere actionem pueri ius
Code:
public void inOrder(Node<T> current) {
if (current != null) {
inOrder(current.getLeftChild());
System.out.println(current.getData() + " ");//ΠΠ΄Π΅ΡΡ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ Π²ΡΠ΅, ΡΡΠΎ ΡΠ³ΠΎΠ΄Π½ΠΎ
inOrder(current.getRightChild());
}
}
conclusio,
Denique! Si nihil explicavi aut commentarios habes, eas in commentarios derelinquas. Ut promissum est, codicem integrum praebeo.
Node.java:
public class Node<T> {
private T data;
private int key;
private Node<T> leftChild;
private Node<T> rightChild;
public Node(T data, int key) {
this.data = data;
this.key = key;
}
public void setLeftChild(Node<T> newNode) {
leftChild = newNode;
}
public void setRightChild(Node<T> newNode) {
rightChild = newNode;
}
public Node<T> getLeftChild() {
return leftChild;
}
public Node<T> getRightChild() {
return rightChild;
}
public T getData() {
return data;
}
public int getKey() {
return key;
}
}
BinaryTree.java:
public class BinaryTree<T> {
private Node<T> root;
public Node<T> find(int key) {
Node<T> current = root;
while (current.getKey() != key) {
if (key < current.getKey())
current = current.getLeftChild();
else
current = current.getRightChild();
if (current == null)
return null;
}
return current;
}
public void insert(T insertData, int key) {
Node<T> current = root;
Node<T> parent;
Node<T> newNode = new Node<>(insertData, key);
if (root == null)
root = newNode;
else {
while (true) {
parent = current;
if (key < current.getKey()) {
current = current.getLeftChild();
if (current == null) {
parent.setLeftChild(newNode);
return;
}
}
else {
current = current.getRightChild();
if (current == null) {
parent.setRightChild(newNode);
return;
}
}
}
}
}
public Node<T> getMinimum(Node<T> startPoint) {
Node<T> current = startPoint;
Node<T> parent = current;
while (current != null) {
parent = current;
current = current.getLeftChild();
}
return parent;
}
public Node<T> getMaximum(Node<T> startPoint) {
Node<T> current = startPoint;
Node<T> parent = current;
while (current != null) {
parent = current;
current = current.getRightChild();
}
return parent;
}
public Node<T> getSuccessor(Node<T> deleteNode) {
Node<T> parentSuccessor = deleteNode;
Node<T> successor = deleteNode;
Node<T> current = successor.getRightChild();
while (current != null) {
parentSuccessor = successor;
successor = current;
current = current.getLeftChild();
}
if (successor != deleteNode.getRightChild()) {
parentSuccessor.setLeftChild(successor.getRightChild());
successor.setRightChild(deleteNode.getRightChild());
}
return successor;
}
public boolean delete(int deleteKey) {
Node<T> current = root;
Node<T> parent = current;
boolean isLeftChild = false;
while (current.getKey() != deleteKey) {
parent = current;
if (deleteKey < current.getKey()) {
current = current.getLeftChild();
isLeftChild = true;
} else {
isLeftChild = false;
current = current.getRightChild();
}
if (current == null)
return false;
}
if (current.getLeftChild() == null && current.getRightChild() == null) {
if (current == root)
current = null;
else if (isLeftChild)
parent.setLeftChild(null);
else
parent.setRightChild(null);
}
else if (current.getRightChild() == null) {
if (current == root)
root = current.getLeftChild();
else if (isLeftChild)
parent.setLeftChild(current.getLeftChild());
else
current.setRightChild(current.getLeftChild());
} else if (current.getLeftChild() == null) {
if (current == root)
root = current.getRightChild();
else if (isLeftChild)
parent.setLeftChild(current.getRightChild());
else
parent.setRightChild(current.getRightChild());
}
else {
Node<T> successor = getSuccessor(current);
if (current == root)
root = successor;
else if (isLeftChild)
parent.setLeftChild(successor);
else
parent.setRightChild(successor);
}
return true;
}
public void inOrder(Node<T> current) {
if (current != null) {
inOrder(current.getLeftChild());
System.out.println(current.getData() + " ");
inOrder(current.getRightChild());
}
}
}
PS
O ad degeneratum (n)
Multi vestrum notasse: quid, si non libratam arborem? Exempli gratia: nodos pone cum claves in arbore crescentes: 1,2,3,4,5,6. Et sic, arbor structuram arboris amittet, et ideo accessus notitiae efficacia. Incomplexitas operationum inquisitionis, insertionis et deletionis eadem fiet ac cum indice coniuncto: O (n). Haec est praecipua, opinor, arborum binarum incommoda.
Tantum usores descripserunt in aliquet participare possunt.
Diutissime in centrum non fui, et scire velim quos articulos de quibus locis plura videre velis?
-
Data structurae
-
Algorithmus (DP, recursio, data compressio, etc.)
-
Applicatio notitiarum structurarum et algorithmorum in vita reali
-
Programming Android Applications in Java
-
Applicationes programmandi interreti Java
2 utentes censuerunt. 1 Insere abstinuisse.
Source: www.habr.com