bst java_BST(二叉搜索树) Java 实现解析
1.二叉搜索樹的定義:一顆樹的所有左子樹都比根小,所有右子樹都比根大,成為二叉搜索樹。
2.該BST樹實(shí)現(xiàn)了9個(gè)重要方法,分別是關(guān)鍵字查找,插入,刪除,刪除節(jié)點(diǎn)后續(xù)節(jié)點(diǎn)查找,前序遍歷,中序遍歷,后序遍歷,獲取最大節(jié)點(diǎn),獲取最小節(jié)點(diǎn)。
3.以下是Java的代碼實(shí)現(xiàn):
//定義Node類,擁有元素值,節(jié)點(diǎn)名稱,左孩子節(jié)點(diǎn),右孩子節(jié)點(diǎn),4個(gè)成員變量。
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;
//查找節(jié)點(diǎn)
//方法思路:從根開始找起,如果比根小,就查找左孩子,如果比根大,就查找右孩子,如果相等,則返回該節(jié)點(diǎn)。
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;
}
//插入節(jié)點(diǎn)
//方法思路:從根節(jié)點(diǎn)開始遍歷,如果比根小,則繼續(xù)查找左孩子,如果比根大,則繼續(xù)查找右孩子,一直查到某節(jié)點(diǎn)左孩子或者右孩子為null,則在該節(jié)點(diǎn)后繼插入節(jié)點(diǎn)。
//注意:被插入的元素在樹中一定是葉子節(jié)點(diǎn)
public boolean insert(Node node){
if(root==null){
root=node;
return true;
}
Node current=root;
if(find(node.element)!=null){
System.out.println("不允許出現(xiàn)重復(fù)節(jié)點(diǎn)...");
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+" ");
}
//獲取樹中最小節(jié)點(diǎn)
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;
}
//獲取樹中最大節(jié)點(diǎn)
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;
}
//刪除節(jié)點(diǎn)
//方法思路:
//1.首先找到刪除節(jié)點(diǎn)和該節(jié)點(diǎn)對(duì)應(yīng)的父親節(jié)點(diǎn),分別用target變量和targetParent變量保存,并且利用一個(gè)布爾變量保存刪除的節(jié)點(diǎn)是父親的左孩子還是右孩子,左孩子則為true,右孩子則為
// false
//2.接下來進(jìn)行節(jié)點(diǎn)刪除,刪除需要分為三種情況,第一種是刪除的是葉子節(jié)點(diǎn),該情況是如果刪除的是父親的左孩子,則直接將父親的leftChild設(shè)為target的左孩子,,如果刪除的是右孩子,則 // 直接將父親的rightChild設(shè)為target的左孩子,即為null;第二種情況是刪除的節(jié)點(diǎn)帶有一個(gè)孩子節(jié)點(diǎn),該節(jié)點(diǎn)可以是左孩子,也可以是右孩子,需要分開處理,如果刪除的節(jié)點(diǎn)本身是左子樹 // ,并且?guī)в凶蠛⒆?#xff0c;則將targetParent的左孩子指向target的左孩子,如果帶有右孩子,則將targetParent的左孩子指向target的右孩子;如果刪除的節(jié)點(diǎn)本身是右子樹,并且?guī)в凶蠛⒆?// ,則將targetParent的右孩子指向target的左孩子,否則指向右孩子。第三種情況是刪除的是帶有兩個(gè)孩子的節(jié)點(diǎn),這種情況稍微復(fù)雜,我們單獨(dú)說明
//3.帶有兩個(gè)孩子的節(jié)點(diǎn)刪除情況分析:該方法伴有一個(gè)getFollwingNode的方法,目的是為了捕獲刪除節(jié)點(diǎn)的后續(xù)節(jié)點(diǎn),思路如下,
// ①.先找到刪除節(jié)點(diǎn)的右子樹節(jié)點(diǎn),調(diào)用getFollowingNode方法可以找到刪除節(jié)點(diǎn)的右子樹中的最左邊的節(jié)點(diǎn),也就是最小節(jié)點(diǎn),并返回該最小節(jié)點(diǎn),此時(shí)調(diào)整該右子樹的結(jié)構(gòu),將返回節(jié)點(diǎn)的 // 父節(jié)點(diǎn)指向返回節(jié)點(diǎn)的右子樹(如果存在的話,左子樹一定是不存在的);
// ②.此時(shí)將刪除節(jié)點(diǎn)的父節(jié)點(diǎn)指向該返回的節(jié)點(diǎn)(注意左右情況),然后將返回節(jié)點(diǎn)的左指針指向刪除節(jié)點(diǎn)的左孩子,右指針指向刪除節(jié)點(diǎn)的右孩子,結(jié)束。
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;
//找到對(duì)應(yīng)的刪除節(jié)點(diǎn)target和其父節(jié)點(diǎn)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;
}
}
//如果刪除的節(jié)點(diǎn)是葉子節(jié)點(diǎn)
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;
}
}
//如果刪除的節(jié)點(diǎn)只有一個(gè)子節(jié)點(diǎn)
//如果該節(jié)點(diǎn)是左子樹
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;
}
}
//如果該節(jié)點(diǎn)是右子樹
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;
}
//獲取刪除節(jié)點(diǎn)后續(xù)節(jié)點(diǎn)
public Node getFollowingNode(Node node2Del){
Node nodeParent = node2Del;
//只有被刪除節(jié)點(diǎn)有左右子節(jié)點(diǎn)時(shí),才會(huì)調(diào)用該方法
//這里直接調(diào)用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;
}
}
總結(jié)
以上是生活随笔為你收集整理的bst java_BST(二叉搜索树) Java 实现解析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 实现栈_栈的Java实现
- 下一篇: java的图形界面上传附件_Java图形