bst java_BST(二叉搜索树) Java 实现解析
1.二叉搜索樹的定義:一顆樹的所有左子樹都比根小,所有右子樹都比根大,成為二叉搜索樹。
2.該BST樹實現了9個重要方法,分別是關鍵字查找,插入,刪除,刪除節點后續節點查找,前序遍歷,中序遍歷,后序遍歷,獲取最大節點,獲取最小節點。
3.以下是Java的代碼實現:
//定義Node類,擁有元素值,節點名稱,左孩子節點,右孩子節點,4個成員變量。
class Node {
int element;
String name;
Node leftChild;
Node rightChild;
public Node(int element, String name) {
this.element = element;
this.name = name;
}
}
public class BinSearchTreeDemo {
public Node root;
//查找節點
//方法思路:從根開始找起,如果比根小,就查找左孩子,如果比根大,就查找右孩子,如果相等,則返回該節點。
public Node find(int key){
if(root==null){
System.out.println("The tree is empty...");
return null;
}
Node current=root;
while (current.element!=key){
if(current.element>key){
current=current.leftChild;
}else{
current=current.rightChild;
}
if(current==null){
return null;
}
}
return current;
}
//插入節點
//方法思路:從根節點開始遍歷,如果比根小,則繼續查找左孩子,如果比根大,則繼續查找右孩子,一直查到某節點左孩子或者右孩子為null,則在該節點后繼插入節點。
//注意:被插入的元素在樹中一定是葉子節點
public boolean insert(Node node){
if(root==null){
root=node;
return true;
}
Node current=root;
if(find(node.element)!=null){
System.out.println("不允許出現重復節點...");
return false;
}
while (current!=null){
if(current.element>node.element){
if(current.leftChild==null){
current.leftChild=node;
return true;
}
current=current.leftChild;
}else{
if(current.rightChild==null){
current.rightChild=node;
return true;
}
current=current.rightChild;
}
}
return false;
}
//前序遍歷(根左右的)
public void preOrder_iterator(Node node){
System.out.println(node.element+" ");
if(node.leftChild!=null){
preOrder_iterator(node.leftChild);
}
if(node.rightChild!=null){
preOrder_iterator(node.rightChild);
}
}
//中序遍歷(左根右)
public void inOrder_iterator(Node node){
if(node.leftChild!=null){
inOrder_iterator(node.leftChild);
}
System.out.println(node.element+" ");
if(node.rightChild!=null){
inOrder_iterator(node.rightChild);
}
}
//后序遍歷(左右根)
public void postOrder_iterator(Node node){
if(node.leftChild!=null){
postOrder_iterator(node.leftChild);
}
if(node.rightChild!=null){
postOrder_iterator(node.rightChild);
}
System.out.println(node.element+" ");
}
//獲取樹中最小節點
public Node getMinNode(Node node){
if(find(node.element)==null){
System.out.println("This node does not exist...");
return null;
}
Node current=node.leftChild;
while (current!=null){
current=current.leftChild;
}
return current;
}
//獲取樹中最大節點
public Node getMaxNode(Node node){
if(find(node.element)==null){
System.out.println("This node does not exist...");
return null;
}
Node current=node.rightChild;
while (current!=null){
current=current.rightChild;
}
return current;
}
//刪除節點
//方法思路:
//1.首先找到刪除節點和該節點對應的父親節點,分別用target變量和targetParent變量保存,并且利用一個布爾變量保存刪除的節點是父親的左孩子還是右孩子,左孩子則為true,右孩子則為
// false
//2.接下來進行節點刪除,刪除需要分為三種情況,第一種是刪除的是葉子節點,該情況是如果刪除的是父親的左孩子,則直接將父親的leftChild設為target的左孩子,,如果刪除的是右孩子,則 // 直接將父親的rightChild設為target的左孩子,即為null;第二種情況是刪除的節點帶有一個孩子節點,該節點可以是左孩子,也可以是右孩子,需要分開處理,如果刪除的節點本身是左子樹 // ,并且帶有左孩子,則將targetParent的左孩子指向target的左孩子,如果帶有右孩子,則將targetParent的左孩子指向target的右孩子;如果刪除的節點本身是右子樹,并且帶有左孩子 // ,則將targetParent的右孩子指向target的左孩子,否則指向右孩子。第三種情況是刪除的是帶有兩個孩子的節點,這種情況稍微復雜,我們單獨說明
//3.帶有兩個孩子的節點刪除情況分析:該方法伴有一個getFollwingNode的方法,目的是為了捕獲刪除節點的后續節點,思路如下,
// ①.先找到刪除節點的右子樹節點,調用getFollowingNode方法可以找到刪除節點的右子樹中的最左邊的節點,也就是最小節點,并返回該最小節點,此時調整該右子樹的結構,將返回節點的 // 父節點指向返回節點的右子樹(如果存在的話,左子樹一定是不存在的);
// ②.此時將刪除節點的父節點指向該返回的節點(注意左右情況),然后將返回節點的左指針指向刪除節點的左孩子,右指針指向刪除節點的右孩子,結束。
public boolean delete(int key){
if(root==null){
System.out.println("The tree is empty...");
return false;
}
Node targetParent=root;
Node target=root;
boolean isLeftChild=false;
//找到對應的刪除節點target和其父節點targetParent
while (target.element!=key){
if(key
targetParent=target;
target=target.leftChild;
isLeftChild=true;
}else{
targetParent=target;
target=target.rightChild;
isLeftChild=false;
}
if(target==null){
System.out.println("The target node does not exist...");
return false;
}
}
//如果刪除的節點是葉子節點
if(target.leftChild==null&&target.rightChild==null){
if(root.element==target.element){
root=null;
return true;
}
if(isLeftChild){
targetParent.leftChild=target.leftChild;
}else{
targetParent.rightChild=target.leftChild;
}
}
//如果刪除的節點只有一個子節點
//如果該節點是左子樹
else if(target.leftChild!=null&&target.rightChild==null){
if(root.element==target.element){
root=target.leftChild;
return true;
}
if(isLeftChild){
targetParent.leftChild=target.leftChild;
}else{
targetParent.leftChild=target.rightChild;
}
}
//如果該節點是右子樹
else if(target.leftChild==null&&target.rightChild!=null){
if(root.element==target.element){
root=target.rightChild;
return true;
}
if(isLeftChild){
targetParent.rightChild=target.leftChild;
}else{
targetParent.rightChild=target.rightChild;
}
}
else{
Node followingNode = this.getFollowingNode(target);
if(target.element == root.element)
root = followingNode;
else if(isLeftChild)
targetParent.leftChild = followingNode;
else
targetParent.rightChild = followingNode;
followingNode.leftChild = target.leftChild;
followingNode.rightChild = target.rightChild;
}
return true;
}
//獲取刪除節點后續節點
public Node getFollowingNode(Node node2Del){
Node nodeParent = node2Del;
//只有被刪除節點有左右子節點時,才會調用該方法
//這里直接調用rightChild是沒有問題的
Node node = node2Del.rightChild;
while(node.leftChild != null){
nodeParent = node;
node = node.leftChild;
}
if(node.element != node2Del.rightChild.element)
nodeParent.leftChild = node.rightChild;
else
nodeParent.rightChild = node.rightChild;
return node;
}
}
總結
以上是生活随笔為你收集整理的bst java_BST(二叉搜索树) Java 实现解析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 实现栈_栈的Java实现
- 下一篇: java 执行cd_Java调用Linu