Alang sa dula
Kini nga artikulo mahitungod sa binary search tree. Bag-o lang ako nagsulat og usa ka artikulo bahin sa
Ang kahoy usa ka istruktura sa datos nga gilangkuban sa mga node nga konektado sa mga sulud. Mahimo natong isulti nga ang usa ka kahoy usa ka espesyal nga kaso sa usa ka graph. Ania ang usa ka pananglitan nga kahoy:
Dili kini usa ka binary nga punoan sa pagpangita! Ang tanan ubos sa pagputol!
Terminolohiya
Gamut
gamut sa kahoy mao ang pinakataas nga node. Sa pananglitan, kini mao ang node A. Sa kahoy, usa ra ka agianan ang mahimong modala gikan sa gamut ngadto sa bisan unsang lain nga node! Sa tinuud, ang bisan unsang node mahimong isipon nga gamut sa subtree nga katumbas niini nga node.
Mga ginikanan/anak
Ang tanan nga mga node gawas sa gamut adunay eksakto nga usa ka ngilit padulong sa lain nga node. Ang node sa ibabaw sa kasamtangan nga node gitawag ginikanan kini nga node. Ang usa ka node nga nahimutang ubos sa kasamtangan ug konektado niini gitawag kaliwat kini nga node. Atong tagdon ang usa ka pananglitan. Kuhaa ang node B, unya ang ginikanan niini mahimong node A, ug ang mga anak niini mahimong mga node D, E, ug F.
Sheet
Ang node nga walay mga anak gitawag nga dahon sa kahoy. Sa pananglitan, ang mga node D, E, F, G, I, J, K mahimong mga dahon.
Kini ang sukaranan nga terminolohiya. Ang ubang mga konsepto hisgotan sa ulahi. Busa, ang binary tree usa ka kahoy diin ang matag node adunay dili molapas sa duha ka mga anak. Sama sa imong natag-an, ang kahoy gikan sa pananglitan dili binary, tungod kay ang mga node B ug H adunay labaw sa duha ka mga anak. Ania ang usa ka pananglitan sa usa ka binary tree:
Ang mga buko sa kahoy mahimong adunay bisan unsang kasayuran. Ang binary search tree usa ka binary tree nga adunay mosunod nga mga kabtangan:
- Ang wala ug tuo nga mga subtree kay binary nga search tree.
- Ang tanan nga mga node sa wala nga subtree sa usa ka arbitraryong node X adunay data key values ββnga mas ubos kaysa data key value sa node X mismo.
- Ang tanan nga mga node sa tuo nga subtree sa usa ka arbitraryong node X adunay mga yawe sa datos nga mga kantidad nga labaw pa sa o katumbas sa kantidad sa yawe sa datos sa node X mismo.
Key - pipila ka kinaiya sa node (pananglitan, usa ka numero). Ang yawe gikinahanglan aron makit-an ang elemento sa kahoy diin kini nga yawe katumbas. Pananglitan sa binary search tree:
pagtan-aw sa kahoy
Sa akong pagpadayon, akong iapil ang pipila (tingali dili kompleto) nga mga piraso sa code aron mapauswag ang imong pagsabut. Ang bug-os nga code anaa sa katapusan sa artikulo.
Ang kahoy gilangkoban sa mga node. Istruktura sa node:
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;
}
//...ΠΎΡΡΠ°Π»ΡΠ½ΡΠ΅ ΠΌΠ΅ΡΠΎΠ΄Ρ ΡΠ·Π»Π°
}
Ang matag node adunay duha ka mga anak (posible nga ang leftChild ug/o rightChild nga mga bata mahimong null). Tingali nakasabut ka nga sa kini nga kaso ang datos sa numero mao ang datos nga gitipigan sa node; yawe - yawe sa node.
Atong nahibal-an ang higot, karon atong hisgutan ang mga dinalian nga mga problema bahin sa mga kahoy. Human niini, ang pulong nga "kahoy" magpasabot sa konsepto sa usa ka binary search tree. Binary nga kahoy nga istruktura:
public class BinaryTree<T> {
private Node<T> root;
//ΠΌΠ΅ΡΠΎΠ΄Ρ Π΄Π΅ΡΠ΅Π²Π°
}
Isip usa ka field sa klase, gikinahanglan lang nato ang gamut sa kahoy, tungod kay gikan sa gamut, gamit ang getLeftChild() ug getRightChild() nga mga pamaagi, makaadto ka sa bisan unsang node sa kahoy.
Mga Algorithm sa Kahoy
ΠΠΎΠΈΡΠΊ
Ingnon ta nga ikaw adunay gitukod nga kahoy. Giunsa pagpangita ang elemento nga adunay yawe nga yawe? Kinahanglan nimo nga sunud-sunod nga mobalhin gikan sa gamut paubos sa kahoy ug itandi ang kantidad sa yawe sa yawe sa sunod nga node: kung ang yawe mas gamay kaysa sa yawe sa sunod nga node, dayon adto sa wala nga kaliwat sa node, kung daghan pa - sa tuo, kung ang mga yawe managsama - ang gitinguha nga node makit-an! May kalabotan nga code:
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;
}
Kung ang kasamtangan mahimong null, nan ang pag-uli nakaabot sa katapusan sa kahoy (sa usa ka konsepto nga lebel, ikaw anaa sa usa ka wala'y dapit sa kahoy - usa ka bata sa usa ka dahon).
Hunahunaa ang kaepektibo sa algorithm sa pagpangita sa usa ka balanse nga kahoy (usa ka kahoy diin ang mga node giapod-apod nga labi o dili kaayo parehas). Unya ang search efficiency mao ang O(log(n)), ug ang base 2 logarithm. Tan-awa: kung adunay n elemento sa usa ka balanse nga kahoy, nan kini nagpasabot nga adunay log(n) base 2 nga lebel sa kahoy. Ug sa pagpangita, alang sa usa ka lakang sa siklo, mopaubos ka sa usa ka lebel.
sal-ot
Kung nasabtan nimo ang esensya sa pagpangita, nan dili ka lisud nga masabtan ang pagsulud. Kinahanglan ka lang nga moadto sa dahon sa kahoy (sumala sa mga lagda sa pagkunsad nga gihulagway sa pagpangita) ug mahimong kaliwat niini - wala o tuo, depende sa yawe. Pagpatuman:
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;
}
}
}
}
}
Sa kini nga kaso, dugang sa kasamtangan nga node, gikinahanglan ang pagtipig sa impormasyon mahitungod sa ginikanan sa kasamtangan nga node. Kung ang kasamtangan mahimong null, ang parent variable maglangkob sa sheet nga atong gikinahanglan.
Ang kaepektibo sa pagsal-ot klaro nga parehas sa pagpangita - O(log(n)).
Pagtangtang
Ang pagtangtang mao ang labing komplikado nga operasyon nga kinahanglan buhaton sa usa ka kahoy. Klaro nga kinahanglan una nga pangitaon ang elemento nga atong tangtangon. Apan unsa man? Kung ibutang lang nato ang reperensiya niini sa null, nan mawad-an kita og impormasyon mahitungod sa subtree nga ang gamut niini nga node. Ang mga pamaagi sa pagtangtang sa kahoy gibahin sa tulo ka mga kaso.
Unang kaso. Ang node nga kuhaon walay mga anak.
Kung ang buko nga tangtangon walay mga anak, kini nagpasabot nga kini usa ka dahon. Busa, mahimo nimong itakda ang leftChild o rightChild nga mga field sa ginikanan niini nga null.
Ikaduha nga kaso. Ang node nga kuhaon adunay usa ka anak
Kini nga kaso dili usab lisud kaayo. Balikan nato ang atong ehemplo. Ibutang ta nga kinahanglan natong tangtangon ang usa ka elemento nga adunay yawe 14. Mouyon nga tungod kay kini ang husto nga bata sa node nga adunay yawe 10, nan bisan kinsa sa mga kaliwat niini (sa kini nga kaso, ang husto) adunay usa ka yawe nga labaw sa 10, mao nga ikaw dali nga "maputol" kini gikan sa kahoy, ug ikonektar ang ginikanan direkta sa bata sa node nga gitangtang, i.e. ikonektar ang node sa yawe 10 ngadto sa node 13. Ang sitwasyon mahimong susama kon kinahanglan natong tangtangon ang usa ka node nga wala nga anak sa ginikanan niini. Hunahunaa kini alang sa imong kaugalingon - usa ka eksaktong analohiya.
Ikatulo nga kaso. Si Node adunay duha ka anak
Ang pinakalisud nga kaso. Atong tan-awon ang usa ka bag-ong pananglitan.
Pagpangita usa ka manununod
Ingnon ta nga kinahanglan natong tangtangon ang node nga adunay yawe 25. Kinsa ang atong ibutang sa dapit niini? Usa sa iyang mga sumusunod (kaliwat o kaliwat sa mga kaliwat) kinahanglang mahimong manununod(ang usa nga mopuli sa gikuha nga node).
Giunsa nimo pagkahibalo kung kinsa ang kinahanglan nga mopuli? Sa intuitively, kini ang node sa kahoy kansang yawe mao ang sunod nga pinakadako gikan sa node nga gikuha. Ang algorithm mao ang mosunod. Kinahanglan ka nga moadto sa tuo nga bata niini (kanunay sa tuo, tungod kay giingon na nga ang yawe sa manununod mas dako kaysa sa yawe sa node nga gitangtang), ug dayon moagi sa kadena sa wala nga mga anak niini nga tuo. bata. Sa pananglitan, kinahanglan nga moadto kita sa node nga adunay yawe 35, ug dayon ipaubos ang kadena sa wala nga mga bata sa dahon - sa kini nga kaso, kini nga kadena naglangkob lamang sa node nga adunay yawe 30. Sa estrikto nga pagsulti, gipangita namon ang ang pinakagamay nga node sa set sa mga node nga mas dako pa sa gusto nga node.
Kodigo sa pamaagi sa pagpangita sa nagsunod:
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;
}
Ang kompleto nga code sa pamaagi sa pagtangtang:
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;
}
Ang pagkakomplikado mahimong mabanabana sa O(log(n)).
Pagpangita sa maximum/minimum sa usa ka kahoy
Dayag nga, kung giunsa pagpangita ang minimum / maximum nga kantidad sa kahoy - kinahanglan nimo nga sunud-sunod nga moagi sa kadena sa wala / tuo nga mga elemento sa kahoy, sa tinuud; pag-abot nimo sa dahon, kini ang minimum/maximum nga elemento.
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;
}
Pagkakomplikado - O(log(n))
Symmetric Bypass
Ang traversal usa ka pagbisita sa matag node sa kahoy aron mahimo ang usa ka butang niini.
Recursive symmetric traversal algorithm:
- Paghimo og aksyon sa wala nga bata
- Paghimo og aksyon sa imong kaugalingon
- Paghimo og aksyon sa husto nga bata
Code:
public void inOrder(Node<T> current) {
if (current != null) {
inOrder(current.getLeftChild());
System.out.println(current.getData() + " ");//ΠΠ΄Π΅ΡΡ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ Π²ΡΠ΅, ΡΡΠΎ ΡΠ³ΠΎΠ΄Π½ΠΎ
inOrder(current.getRightChild());
}
}
konklusyon
Sa kataposan! Kung wala ako nagpatin-aw sa usa ka butang o adunay bisan unsang mga komento, nan naghulat ako sa mga komento. Ingon sa gisaad, ania ang kompleto nga code.
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
Pag-us-os ngadto sa O(n)
Daghan kaninyo ang tingali nakamatikod: unsa kaha kon himoon ninyo nga dili balanse ang kahoy? Pananglitan, ibutang ang mga node sa kahoy nga adunay nagkadaghang mga yawe: 1,2,3,4,5,6... Unya ang kahoy medyo makapahinumdom sa usa ka nasumpay nga listahan. Ug oo, ang kahoy mawad-an sa iyang istruktura sa kahoy, ug busa ang kahusayan sa pag-access sa datos. Ang pagkakomplikado sa mga operasyon sa pagpangita, pagsal-ot, ug pagtangtang mahimong pareho sa usa ka gisumpay nga listahan: O(n). Kini mao ang usa sa labing importante, sa akong opinyon, disadvantages sa binary nga mga kahoy.
Ang mga rehistradong tiggamit lamang ang makaapil sa survey.
Dugay na kong wala sa HabrΓ©, ug gusto nakong mahibal-an kung unsang mga artikulo sa unsang mga hilisgutan ang gusto nimo nga makita pa?
-
Mga Istruktura sa Data
-
Algorithm (DP, recursion, data compression, ug uban pa)
-
Ang paggamit sa mga istruktura sa datos ug mga algorithm sa tinuud nga kinabuhi
-
Pagprograma sa mga aplikasyon sa android sa Java
-
Java Web Application Programming
2 user ang nagboto. 1 user ang ni- abstain.
Tinubdan: www.habr.com