欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

利用java實現(xiàn)二叉搜索樹

 更新時間:2021年04月16日 14:21:01   作者:\(^o^)/kūn  
這篇文章主要介紹了利用java實現(xiàn)二叉搜索樹,文中有非常詳細(xì)的代碼示例,對正在學(xué)習(xí)java的小伙伴們有非常好的幫助,需要的朋友可以參考下

二叉搜索樹的定義

  • 它是一顆二叉樹
  • 任一節(jié)點的左子樹上的所有節(jié)點的值一定小于該節(jié)點的值
  • 任一節(jié)點的右子樹上的所有節(jié)點的值一定大于該節(jié)點的值

二叉排序樹

特點: 二叉搜索樹的中序遍歷結(jié)果是有序的(升序)!

實現(xiàn)一顆二叉搜索樹

  • 實現(xiàn)二叉搜索樹,將實現(xiàn)插入,刪除,查找三個方面
  • 二叉搜索樹的節(jié)點是不可以進行修改的,如果修改,則可能會導(dǎo)致搜索樹的錯誤

二叉搜索樹的定義類

  • 二叉搜索樹的節(jié)點類 —— class Node
  • 二叉搜索樹的屬性:要找到一顆二叉搜索樹只需要知道這顆樹的根節(jié)點。
public class BST {
    static class Node {
        private int key;
        private Node left;
        private Node right;

        public Node(int key) {
            this.key = key;
        }
    }

    private Node root;//BST的根節(jié)點
}

二叉搜索樹的查找

  • 二叉搜索樹的查找思路:
  • ①如果要查找的值等于當(dāng)前節(jié)點的值,那么,就找到了
  • ②如果要查找的值小于當(dāng)前節(jié)點的值,那么,就往當(dāng)前節(jié)點的左子樹走
  • ③如果要查找的值大于當(dāng)前節(jié)點的值,那么,就往當(dāng)前節(jié)點的右子樹走
  • 最終,如果走到空了還沒有找到,就說明不存在這個key
/**
 * 查找是否存在節(jié)點
 *
 * 思路:根據(jù)二叉排序樹的特點:
 * ①如果要查找的值小于當(dāng)前節(jié)點的值,那么,就往當(dāng)前節(jié)點的左子樹走
 * ②如果要查找的值大于當(dāng)前節(jié)點的值,那么,就往當(dāng)前節(jié)點的右子樹走
 *
 * @param key 帶查找的key
 * @return boolean是否存在
 */
public boolean find(int key) {
	Node cur = root;
	while (cur != null) {
		if (key < root.key) {
			cur = cur.left;
		} else if (key > root.key) {
			cur = cur.right;
		} else {
			return true;
		}
	}
	return false;
}

二叉搜索樹的插入

  • 二叉搜索樹的插入思路:
  • 思路和查找一樣的,只是我們這次要進行的是插入操作,那么我們還需要一個parent節(jié)點,來時刻記錄當(dāng)前節(jié)點的雙親節(jié)點即:
  • ①如果要插入的值等于當(dāng)前節(jié)點的值,那么,無法插入(不可出現(xiàn)重復(fù)的key
  • ②如果要插入的值小于當(dāng)前節(jié)點的值,那么,就往當(dāng)前節(jié)點的左子樹走
  • ③如果要插入的值大于當(dāng)前節(jié)點的值,那么,就往當(dāng)前節(jié)點的右子樹走
  • 最終,如果走到空了,就說明不存在重復(fù)的key,只要往雙親節(jié)點的后面插就好了,就是合適的位置,具體往左邊還是右邊插入,需要比較待插入節(jié)點的keyparentkey
/**
 * 往二叉樹中插入節(jié)點
 *
 * 思路如下:
 *
 * @param key 待插入的節(jié)點
 */
public void insert(int key) {
	if (root == null) { //如果是空樹,那么,直接插入
		root = new Node(key);
		return;
	}

	Node cur = root;
	Node parent = null; //parent 為cur的父節(jié)點
	while (true) {
		if (cur == null) { //在遍歷過程中,找到了合適是位置,就指針插入(沒有重復(fù)節(jié)點)
			if (parent.key < key) {
				parent.right = new Node(key);
			} else {
				parent.left = new Node(key);
			}
			return;
		}

		if (key < cur.key) {
			parent = cur;
			cur = cur.left;
		} else if (key > cur.key) {
			parent = cur;
			cur = cur.right;
		} else {
			throw new RuntimeException("插入失敗,已經(jīng)存在key");
		}
	}
}

二叉搜索樹的刪除

  • 二叉搜索樹的刪除思路:(詳細(xì)的思路看注釋
  • 首先,需要先找到是否存在key節(jié)點,如果存在,則刪除,如果不存在則刪除錯誤
  • 對于,如果存在,則分為三種情況:
  • ①要刪除的節(jié)點,沒有左孩子

Ⅰ:要刪除的節(jié)點為根節(jié)點:root = delete.right;
Ⅱ:要刪除的節(jié)點為其雙親節(jié)點的左孩子:parent.left = delete.right;
Ⅲ:要刪除的節(jié)點為其雙親節(jié)點的右孩子:parent.right = delete.right;

  • ②要刪除的節(jié)點,沒有右孩子

Ⅰ:要刪除的節(jié)點為根節(jié)點:root = delete.left;
Ⅱ:要刪除的節(jié)點為其雙親節(jié)點的左孩子:parent.left = delete.left;
Ⅲ:要刪除的節(jié)點為其雙親節(jié)點的右孩子:parent.right = delete.left;

  • ③要刪除的節(jié)點,既有左孩子又有右孩子:

此時我們需要找到整顆二叉樹中第一個大于待刪除節(jié)點的節(jié)點,然后替換他倆的值,最后,把找到的節(jié)點刪除
Ⅰ:找到的節(jié)點的雙親節(jié)點為待刪除的節(jié)點:delete.key = find.key; findParent.right = find.right;
Ⅱ:找到的節(jié)點的雙親節(jié)點不是待刪除的節(jié)點:delete.key = find.key; findParent.left = find.right;

/**
 * 刪除樹中節(jié)點
 *
 * 思路如下:
 *
 * @param key 待刪除的節(jié)點
 */
public void remove(int key) {
	if (root == null) {
		throw new RuntimeException("為空樹,刪除錯誤!");
	}
	Node cur = root;
	Node parent = null;
	//查找是否key節(jié)點的位置
	while (cur != null) {
		if (key < cur.key) {
			parent = cur;
			cur = cur.left;
		} else if (key > cur.key) {
			parent = cur;
			cur = cur.right;
		} else {
			break;
		}
	}
	if (cur == null) {
		throw new RuntimeException("找不到key,輸入key不合法");
	}

	//cur 為待刪除的節(jié)點
	//parent 為待刪除的節(jié)點的父節(jié)點
	/*
         * 情況1:如果待刪除的節(jié)點沒有左孩子
         * 其中
         * ①待刪除的節(jié)點有右孩子
         * ②待刪除的節(jié)點沒有右孩子
         * 兩種情況可以合并
         */
	if (cur.left == null) {
		if (cur == root) { //①如果要刪除的是根節(jié)點
			root = cur.right;
		} else if (cur == parent.left) { //②如果要刪除的是其父節(jié)點的左孩子
			parent.left = cur.right;
		} else { //③如果要刪除的節(jié)點為其父節(jié)點的右孩子
			parent.right = cur.right;
		}
	}
	/*
         * 情況2:如果待刪除的節(jié)點沒有右孩子
         *
         * 其中:待刪除的節(jié)點必定存在左孩子
         */
	else if (cur.right == null) { //①如果要刪除的是根節(jié)點
		if (cur == root) {
			root = cur.left;
		} else if (cur == parent.left) { //②如果要刪除的是其父節(jié)點的左孩子
			parent.left = cur.left;
		} else { //③如果要刪除的節(jié)點為其父節(jié)點的右孩子
			parent.right = cur.left;
		}
	}
	/*
        * 情況3:如果待刪除的節(jié)點既有左孩子又有右孩子
        *
        * 思路:
        * 因為是排序二叉樹,要找到整顆二叉樹第一個大于該節(jié)點的節(jié)點,只需要,先向右走一步,然后一路往最左走就可以找到了
        * 因此:
        * ①先向右走一步
        * ②不斷向左走
        * ③找到第一個大于待刪除的節(jié)點的節(jié)點,將該節(jié)點的值,替換到待刪除的節(jié)點
        * ④刪除找到的這個節(jié)點
        * ⑤完成刪除
        *
         */
	else {
		Node nextParent = cur; //定義父節(jié)點,初始化就是待刪除的節(jié)點
		Node next = cur.right; //定義next為當(dāng)前走到的節(jié)點,最終目的是找到第一個大于待刪除的節(jié)點
		while (next.left != null) {
			nextParent = next;
			next = next.left;
		}
		cur.key = next.key; //找到之后,完成值的替換
		if (nextParent == cur) { //此時的父節(jié)點就是待刪除的節(jié)點,那么說明找到的節(jié)點為父節(jié)點的右孩子(因為此時next只走了一步)
			nextParent.right = next.right;
		} else { //此時父節(jié)點不是待刪除的節(jié)點,即next確實往左走了,且走到了頭.
			nextParent.left = next.right;
		}
	}

}

到此這篇關(guān)于利用java實現(xiàn)二叉搜索樹的文章就介紹到這了,更多相關(guān)java二叉搜索樹內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • IDEA修改java文件后 不用重啟Tomcat服務(wù)便可實現(xiàn)自動更新

    IDEA修改java文件后 不用重啟Tomcat服務(wù)便可實現(xiàn)自動更新

    這篇文章主要介紹了IDEA修改java文件后 不用重啟Tomcat服務(wù)便可實現(xiàn)自動更新,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • Java實現(xiàn)多線程下載和斷點續(xù)傳

    Java實現(xiàn)多線程下載和斷點續(xù)傳

    這篇文章主要為大家詳細(xì)介紹了Java實現(xiàn)多線程下載和斷點續(xù)傳,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • Spring Boot整合Spring Security簡單實現(xiàn)登入登出從零搭建教程

    Spring Boot整合Spring Security簡單實現(xiàn)登入登出從零搭建教程

    這篇文章主要給大家介紹了關(guān)于Spring Boot整合Spring Security簡單實現(xiàn)登入登出從零搭建的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧
    2018-09-09
  • Spring MVC的國際化實現(xiàn)代碼

    Spring MVC的國際化實現(xiàn)代碼

    本篇文章主要介紹了Spring MVC的國際化實現(xiàn)代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • 詳解JAVA類加載機制

    詳解JAVA類加載機制

    這篇文章主要介紹了JAVA類加載機制的相關(guān)知識,文中代碼非常詳細(xì),供大家參考和學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06
  • 淺談對Java雙冒號::的理解

    淺談對Java雙冒號::的理解

    這篇文章主要介紹了淺談對Java雙冒號::的理解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • java實現(xiàn)簡單撲克牌游戲

    java實現(xiàn)簡單撲克牌游戲

    這篇文章主要為大家詳細(xì)介紹了java實現(xiàn)簡單撲克牌游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-09-09
  • Java泛型在集合使用與自定義及繼承上的體現(xiàn)和通配符的使用

    Java泛型在集合使用與自定義及繼承上的體現(xiàn)和通配符的使用

    泛型又稱參數(shù)化類型,是Jdk5.0 出現(xiàn)的新特性,解決數(shù)據(jù)類型的安全性問題,在類聲明或?qū)嵗瘯r只要指定好需要的具體的類型即可。Java泛型可以保證如果程序在編譯時沒有發(fā)出警告,運行時就不會產(chǎn)生ClassCastException異常。同時,代碼更加簡潔、健壯
    2021-09-09
  • 深入解析Spring?Boot?的SPI機制詳情

    深入解析Spring?Boot?的SPI機制詳情

    這篇文章主要介紹了深入解析Spring?Boot的SPI機制詳情,SPI是JDK內(nèi)置的一種服務(wù)提供發(fā)現(xiàn)機制,可以用來啟用框架擴展和替換組件,主要用于框架中開發(fā),更多相關(guān)介紹,感興趣的小伙伴可以參考一下下面文章內(nèi)容
    2022-08-08
  • SpringBoot如何返回頁面的實現(xiàn)方法

    SpringBoot如何返回頁面的實現(xiàn)方法

    SpringBoot中使用Controller和頁面的結(jié)合能夠很好地實現(xiàn)用戶的功能及頁面數(shù)據(jù)的傳遞。本文介紹了如何實現(xiàn)頁面的返回以及這里面所包含的坑,感興趣的可以了解一下
    2021-07-07

最新評論