日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

二叉查找树的Java实现

發(fā)布時間:2024/10/12 java 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 二叉查找树的Java实现 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

轉(zhuǎn)自:http://blog.csdn.net/lovesqcc/article/details/6246615

為了克服對樹結(jié)構(gòu)編程的恐懼感,決心自己實現(xiàn)一遍二叉查找樹,以便掌握關(guān)于樹結(jié)構(gòu)編程的一些技巧和方法。以下是基本思路:

?

??????? [1] 關(guān)于容器與封裝。封裝,是一種非常重要的系統(tǒng)設(shè)計思想;無論是面向過程的函數(shù),還是面向?qū)ο蟮膶ο?#xff0c;都是實現(xiàn)抽象和封裝的技術(shù)手段。要使系統(tǒng)更加安全更具可維護性,就應(yīng)當將封裝思想謹記心中。容器是封裝思想的絕好示例。用戶對容器的印象應(yīng)該簡潔地表達為:A. 可以存入指定的東西; B. 可以取出所期望的東西。 而至于這容器中究竟有什么機關(guān),藏的是毒蛇還是黃金,都是對用戶不可見的。二叉查找樹就是這樣一個容器。面向?qū)ο缶幊讨?#xff0c;為實現(xiàn)樹結(jié)構(gòu),自然要對樹結(jié)點對象進行建模。這里采用了內(nèi)部類;外部類對二叉查找樹進行建模,而樹結(jié)點作為內(nèi)部類實現(xiàn)。

?

?????? [2] 本程序盡量實現(xiàn)一個比較實用的二叉查找樹,其中包括動態(tài)的插入、刪除操作;查詢給定關(guān)鍵字、最小關(guān)鍵字、最大關(guān)鍵字;獲取二叉樹的有序列表(用于排序)等。因為我希望以后還能用到這個容器的,而不僅僅是編程練習(xí)。二叉查找樹操作的大部分算法參考了《算法導(dǎo)論2》第12章內(nèi)容,刪除操作略顯笨拙。程序中有錯誤之處,歡迎指出。

?

????? [3]? 程序如下:

?

?????

[c-sharp]?view plaincopyprint?
  • /**?
  • ?*?@author?shuqin1984??2011-3-13?
  • ?*??
  • ?*?此程序?qū)崿F(xiàn)一個二叉查找樹的功能,可以進行動態(tài)插入、刪除關(guān)鍵字;?
  • ?*?查詢給定關(guān)鍵字、最小關(guān)鍵字、最大關(guān)鍵字;轉(zhuǎn)換為有序列表(用于排序)?
  • ?*??
  • ?*??
  • ?*/??
  • package?datastructure.tree;??
  • import?java.util.ArrayList;??
  • import?java.util.List;??
  • ??
  • public?class?BinarySearchTree?{??
  • ??????
  • ????//?樹的根結(jié)點??
  • ????private?TreeNode?root?=?null;??
  • ??????
  • ????//?遍歷結(jié)點列表??
  • ????private?List<TreeNode>?nodelist?=?new?ArrayList<TreeNode>();??
  • ??????
  • ????private?class?TreeNode?{??
  • ??????????
  • ????????private?int?key;??
  • ????????private?TreeNode?leftChild;??
  • ????????private?TreeNode?rightChild;??
  • ????????private?TreeNode?parent;??
  • ??????????
  • ????????public?TreeNode(int?key,?TreeNode?leftChild,?TreeNode?rightChild,?TreeNode?parent)?{??
  • ????????????this.key?=?key;??
  • ????????????this.leftChild?=?leftChild;??
  • ????????????this.rightChild?=?rightChild;??
  • ????????????this.parent?=?parent;??
  • ????????}?????
  • ????????public?int?getKey()?{??
  • ????????????return?key;??
  • ????????}??
  • ????????public?String?toString()??
  • ????????{??
  • ????????????String?leftkey?=?(leftChild?==?null???""?:?String.valueOf(leftChild.key));????
  • ????????????String?rightkey?=?(rightChild?==?null???""?:?String.valueOf(rightChild.key));???
  • ????????????return?"("?+?leftkey?+?"?,?"?+?key?+?"?,?"?+?rightkey?+?")";??
  • ????????}??
  • ??????????
  • ????}??
  • ??????
  • ????/**?
  • ?????*?isEmpty:?判斷二叉查找樹是否為空;若為空,返回?true?,否則返回?false?.??
  • ?????*??
  • ?????*/??
  • ????public?boolean?isEmpty()??
  • ????{??
  • ????????if?(root?==?null)?{??
  • ????????????return?true;??
  • ????????}?else?{??
  • ????????????return?false;??
  • ????????}?????????????
  • ????}??
  • ??????
  • ????/**?
  • ?????*?TreeEmpty:?對于某些二叉查找樹操作(比如刪除關(guān)鍵字)來說,若樹為空,則拋出異常。?
  • ?????*/??
  • ????public?void?TreeEmpty()?throws?Exception???
  • ????{??
  • ????????if?(isEmpty())?{??
  • ????????????throw?new?Exception("樹為空!");??
  • ????????}??
  • ????}??
  • ??????
  • ????/**?
  • ?????*?search:?在二叉查找樹中查詢給定關(guān)鍵字??
  • ?????*?@param?key?給定關(guān)鍵字?
  • ?????*?@return?匹配給定關(guān)鍵字的樹結(jié)點?
  • ?????*/??
  • ????public?TreeNode?search(int?key)???
  • ????{??
  • ????????TreeNode?pNode?=?root;??
  • ????????while?(pNode?!=?null?&&?pNode.key?!=?key)?{??
  • ????????????if?(key?<?pNode.key)?{??
  • ????????????????pNode?=?pNode.leftChild;??
  • ????????????}??
  • ????????????else?{??
  • ????????????????pNode?=?pNode.rightChild;??
  • ????????????}??
  • ????????}??
  • ????????return?pNode;??
  • ????}??
  • ??????
  • ????/**?
  • ?????*?minElemNode:?獲取二叉查找樹中的最小關(guān)鍵字結(jié)點?
  • ?????*?@return?二叉查找樹的最小關(guān)鍵字結(jié)點?
  • ?????*?@throws?Exception?若樹為空,則拋出異常?
  • ?????*/??
  • ????public?TreeNode?minElemNode(TreeNode?node)?throws?Exception??
  • ????{??
  • ????????if?(node?==?null)?{??
  • ????????????throw?new?Exception("樹為空!");??
  • ????????}??
  • ????????TreeNode?pNode?=?node;??
  • ????????while?(pNode.leftChild?!=?null)?{??
  • ????????????pNode?=?pNode.leftChild;??
  • ????????}??
  • ????????return?pNode;??
  • ????}??
  • ??????
  • ????/**?
  • ?????*?maxElemNode:?獲取二叉查找樹中的最大關(guān)鍵字結(jié)點?
  • ?????*?@return?二叉查找樹的最大關(guān)鍵字結(jié)點?
  • ?????*?@throws?Exception?若樹為空,則拋出異常?
  • ?????*/??
  • ????public?TreeNode?maxElemNode(TreeNode?node)?throws?Exception???
  • ????{??
  • ????????if?(node?==?null)?{??
  • ????????????throw?new?Exception("樹為空!");??
  • ????????}??
  • ????????TreeNode?pNode?=?node;??
  • ????????while?(pNode.rightChild?!=?null)?{??
  • ????????????pNode?=?pNode.rightChild;??
  • ????????}??
  • ????????return?pNode;??
  • ????}??
  • ??????
  • ????/**?
  • ?????*?successor:?獲取給定結(jié)點在中序遍歷順序下的后繼結(jié)點?
  • ?????*?@param?node?給定樹中的結(jié)點?
  • ?????*?@return?若該結(jié)點存在中序遍歷順序下的后繼結(jié)點,則返回其后繼結(jié)點;否則返回?null?
  • ?????*?@throws?Exception??
  • ?????*/??
  • ????public?TreeNode?successor(TreeNode?node)?throws?Exception??
  • ????{??
  • ????????if?(node?==?null)?{??
  • ????????????return?null;??
  • ????????}??
  • ??????????
  • ????????//?若該結(jié)點的右子樹不為空,則其后繼結(jié)點就是右子樹中的最小關(guān)鍵字結(jié)點??
  • ????????if?(node.rightChild?!=?null)?{???
  • ????????????return?minElemNode(node.rightChild);??
  • ????????}??
  • ????????//?若該結(jié)點右子樹為空??
  • ????????TreeNode?parentNode?=?node.parent;??
  • ????????while?(parentNode?!=?null?&&?node?==?parentNode.rightChild)?{??
  • ????????????node?=?parentNode;??
  • ????????????parentNode?=?parentNode.parent;??
  • ????????}??
  • ????????return?parentNode;??
  • ????}??
  • ??????
  • ??????
  • ????/**?
  • ?????*?precessor:?獲取給定結(jié)點在中序遍歷順序下的前趨結(jié)點?
  • ?????*?@param?node?給定樹中的結(jié)點?
  • ?????*?@return?若該結(jié)點存在中序遍歷順序下的前趨結(jié)點,則返回其前趨結(jié)點;否則返回?null?
  • ?????*?@throws?Exception??
  • ?????*/??
  • ????public?TreeNode?precessor(TreeNode?node)?throws?Exception??
  • ????{??
  • ????????if?(node?==?null)?{??
  • ????????????return?null;??
  • ????????}??
  • ??????????
  • ????????//?若該結(jié)點的左子樹不為空,則其前趨結(jié)點就是左子樹中的最大關(guān)鍵字結(jié)點??
  • ????????if?(node.leftChild?!=?null)?{???
  • ????????????return?maxElemNode(node.leftChild);??
  • ????????}??
  • ????????//?若該結(jié)點左子樹為空??
  • ????????TreeNode?parentNode?=?node.parent;??
  • ????????while?(parentNode?!=?null?&&?node?==?parentNode.leftChild)?{??
  • ????????????node?=?parentNode;??
  • ????????????parentNode?=?parentNode.parent;??
  • ????????}??
  • ????????return?parentNode;??
  • ????}??
  • ??????
  • ??????
  • ????/**?
  • ?????*?insert:?將給定關(guān)鍵字插入到二叉查找樹中?
  • ?????*?@param?key?給定關(guān)鍵字?
  • ?????*/??
  • ????public?void?insert(int?key)??
  • ????{??
  • ????????TreeNode?parentNode?=?null;??
  • ????????TreeNode?newNode?=?new?TreeNode(key,?null,?null,null);??
  • ????????TreeNode?pNode?=?root;??
  • ????????if?(root?==?null)?{??
  • ????????????root?=?newNode;??
  • ????????????return?;??
  • ????????}??
  • ????????while?(pNode?!=?null)?{??
  • ????????????parentNode?=?pNode;??
  • ????????????if?(key?<?pNode.key)?{?????
  • ????????????????pNode?=?pNode.leftChild;??
  • ????????????}??
  • ????????????else?if?(key?>?pNode.key)?{??
  • ????????????????pNode?=?pNode.rightChild;??
  • ????????????}?else?{??
  • ????????????????//?樹中已存在匹配給定關(guān)鍵字的結(jié)點,則什么都不做直接返回????????????????????
  • ????????????????return?;??
  • ????????????}??
  • ????????}??
  • ????????if?(key?<?parentNode.key)?{??
  • ????????????parentNode.leftChild?=?newNode;??
  • ????????????newNode.parent?=?parentNode;??
  • ????????}??
  • ????????else?{??
  • ????????????parentNode.rightChild?=?newNode;??
  • ????????????newNode.parent?=?parentNode;??
  • ????????}?????????
  • ??????????
  • ????}??
  • ??????
  • ????/**?
  • ?????*?insert:?從二叉查找樹中刪除匹配給定關(guān)鍵字相應(yīng)的樹結(jié)點?
  • ?????*?@param?key?給定關(guān)鍵字?
  • ?????*/??
  • ????public?void?delete(int?key)?throws?Exception??
  • ????{??
  • ????????TreeNode?pNode?=?search(key);??
  • ????????if?(pNode?==?null)?{??
  • ????????????throw?new?Exception("樹中不存在要刪除的關(guān)鍵字!");??
  • ????????}??
  • ????????delete(pNode);??
  • ????}??
  • ??????
  • ????/**?
  • ?????*?delete:?從二叉查找樹中刪除給定的結(jié)點.?
  • ?????*?@param?pNode?要刪除的結(jié)點?
  • ?????*??
  • ?????*?前置條件:?給定結(jié)點在二叉查找樹中已經(jīng)存在?
  • ?????*?@throws?Exception??
  • ?????*/??
  • ????private?void?delete(TreeNode?pNode)?throws?Exception???
  • ????{??
  • ??????????if?(pNode?==?null)?{??
  • ??????????????return?;??
  • ??????????}??
  • ??????????if?(pNode.leftChild?==?null?&&?pNode.rightChild?==?null)?{?//?該結(jié)點既無左孩子結(jié)點,也無右孩子結(jié)點??
  • ??????????????TreeNode?parentNode?=?pNode.parent;??
  • ??????????????if?(pNode?==?parentNode.leftChild)?{??
  • ??????????????????parentNode.leftChild?=?null;??
  • ??????????????}?else?{??
  • ??????????????????parentNode.rightChild?=?null;??
  • ??????????????}??
  • ??????????????return?;??
  • ??????????}??
  • ??????????if?(pNode.leftChild?==?null?&&?pNode.rightChild?!=?null)?{?//?該結(jié)點左孩子結(jié)點為空,右孩子結(jié)點非空??
  • ??????????????TreeNode?parentNode?=?pNode.parent;??
  • ??????????????if?(pNode?==?parentNode.leftChild)?{??
  • ??????????????????parentNode.leftChild?=?pNode.rightChild;??
  • ??????????????????pNode.rightChild.parent?=?parentNode;??
  • ??????????????}??
  • ??????????????else?{??
  • ??????????????????parentNode.rightChild?=?pNode.rightChild;??
  • ??????????????????pNode.rightChild.parent?=?parentNode;??
  • ??????????????}??
  • ??????????????return?;??
  • ??????????}??
  • ??????????if?(pNode.leftChild?!=?null?&&?pNode.rightChild?==?null)?{?//?該結(jié)點左孩子結(jié)點非空,右孩子結(jié)點為空??
  • ??????????????TreeNode?parentNode?=?pNode.parent;??
  • ??????????????if?(pNode?==?parentNode.leftChild)?{??
  • ??????????????????parentNode.leftChild?=?pNode.leftChild;??
  • ??????????????????pNode.rightChild.parent?=?parentNode;??
  • ??????????????}??
  • ??????????????else?{??
  • ??????????????????parentNode.rightChild?=?pNode.leftChild;??
  • ??????????????????pNode.rightChild.parent?=?parentNode;??
  • ??????????????}??
  • ??????????????return?;??
  • ??????????}??
  • ??????????//?該結(jié)點左右孩子結(jié)點均非空,則刪除該結(jié)點的后繼結(jié)點,并用該后繼結(jié)點取代該結(jié)點??
  • ??????????TreeNode?successorNode?=?successor(pNode);??
  • ??????????delete(successorNode);??
  • ??????????pNode.key?=?successorNode.key;??
  • ????}??
  • ??????
  • ????/**?
  • ?????*?inOrderTraverseList:?獲得二叉查找樹的中序遍歷結(jié)點列表?
  • ?????*?@return?二叉查找樹的中序遍歷結(jié)點列表?
  • ?????*/??
  • ????public?List<TreeNode>?inOrderTraverseList()??
  • ????{??
  • ????????if?(nodelist?!=?null)?{??
  • ???????????nodelist.clear();??
  • ????????}??
  • ????????inOrderTraverse(root);??
  • ????????return?nodelist;??
  • ????}??
  • ??????
  • ????/**?
  • ?????*?inOrderTraverse:?對給定二叉查找樹進行中序遍歷?
  • ?????*?@param?root?給定二叉查找樹的根結(jié)點?
  • ?????*/??
  • ????private?void?inOrderTraverse(TreeNode?root)??
  • ????{??
  • ????????if?(root?!=?null)?{??
  • ????????????inOrderTraverse(root.leftChild);??
  • ????????????nodelist.add(root);??
  • ????????????inOrderTraverse(root.rightChild);??
  • ????????}??
  • ????}??
  • ??????
  • ????/**?
  • ?????*?toStringOfOrderList:?獲取二叉查找樹中關(guān)鍵字的有序列表?
  • ?????*?@return?二叉查找樹中關(guān)鍵字的有序列表?
  • ?????*/??
  • ????public?String?toStringOfOrderList()??
  • ????{??
  • ????????StringBuilder?sbBuilder?=?new?StringBuilder("?[?");??
  • ????????for?(TreeNode?p:?inOrderTraverseList())?{??
  • ????????????sbBuilder.append(p.key);??
  • ????????????sbBuilder.append("?");??
  • ????????}??
  • ????????sbBuilder.append("]");??
  • ????????return?sbBuilder.toString();??
  • ????}??
  • ??????
  • ????/**?
  • ?????*?獲取該二叉查找樹的字符串表示?
  • ?????*/??
  • ????public?String?toString()??
  • ????{??
  • ????????StringBuilder?sbBuilder?=?new?StringBuilder("?[?");??
  • ????????for?(TreeNode?p:?inOrderTraverseList())?{??
  • ????????????sbBuilder.append(p);??
  • ????????????sbBuilder.append("?");??
  • ????????}??
  • ????????sbBuilder.append("]");??
  • ????????return?sbBuilder.toString();??
  • ????}??
  • ????public?TreeNode?getRoot()?{??
  • ????????return?root;??
  • ????}??
  • ??????
  • ????public?static?void?testNode(BinarySearchTree?bst,?TreeNode?pNode)?throws?Exception?{??
  • ????????System.out.println("本結(jié)點:?"?+?pNode);??
  • ????????System.out.println("前趨結(jié)點:?"?+?bst.precessor(pNode));??
  • ????????System.out.println("后繼結(jié)點:?"?+?bst.successor(pNode));??
  • ????}??
  • ??????
  • ????public?static?void?testTraverse(BinarySearchTree?bst)?{??
  • ????????System.out.println("二叉樹遍歷:"?+?bst);??
  • ????????System.out.println("二叉查找樹轉(zhuǎn)換為有序列表:?"?+?bst.toStringOfOrderList());??
  • ????}??
  • ??????
  • ????public?static?void?main(String[]?args)???
  • ????{??
  • ????????try?{??
  • ????????????BinarySearchTree?bst?=?new?BinarySearchTree();??
  • ????????????System.out.println("查找樹是否為空??"?+?(bst.isEmpty()???"是"?:?"否"));??
  • ????????????int[]?keys?=?new?int[]?{15,?6,?18,?3,?7,?13,?20,?2,?9,?4};??
  • ????????????for?(int?key:?keys)?{??
  • ????????????????bst.insert(key);??
  • ????????????}??
  • ????????????System.out.println("查找樹是否為空??"?+?(bst.isEmpty()???"是"?:?"否"));??
  • ??????????????
  • ????????????TreeNode?minkeyNode?=?bst.minElemNode(bst.getRoot());??
  • ????????????System.out.println("最小關(guān)鍵字:?"?+?minkeyNode.getKey());??
  • ????????????testNode(bst,?minkeyNode);??
  • ??????????????
  • ????????????TreeNode?maxKeyNode?=?bst.maxElemNode(bst.getRoot());??
  • ????????????System.out.println("最大關(guān)鍵字:?"?+?maxKeyNode.getKey());??
  • ????????????testNode(bst,?maxKeyNode);??
  • ??????????????
  • ????????????System.out.println("根結(jié)點關(guān)鍵字:?"?+?bst.getRoot().getKey());??
  • ????????????testNode(bst,?bst.getRoot());??
  • ????????????testTraverse(bst);??
  • ??????????????
  • ????????????System.out.println("******************************?");??
  • ??????????????
  • ????????????System.out.println("查找?7?:?"?+?(bst.search(7)?!=?null???"查找成功!"?:?"查找失敗,不存在該關(guān)鍵字!"));??
  • ????????????bst.delete(7);??
  • ????????????System.out.println("查找?7?:?"?+?(bst.search(7)?!=?null???"查找成功!"?:?"查找失敗,不存在該關(guān)鍵字!"));??
  • ????????????System.out.println("查找?12?:?"?+?(bst.search(12)?!=?null???"查找成功!"?:?"查找失敗,不存在該關(guān)鍵字!"));??
  • ????????????bst.insert(12);??
  • ????????????System.out.println("查找?12?:?"?+?(bst.search(12)?!=?null???"查找成功!"?:?"查找失敗,不存在該關(guān)鍵字!"));??
  • ??????????????
  • ????????????testTraverse(bst);??
  • ??????????????
  • ????????????System.out.println("******************************?");??
  • ??????????????
  • ????????????bst.insert(16);??
  • ????????????bst.delete(6);??
  • ????????????bst.delete(4);??
  • ??????????????
  • ????????????testTraverse(bst);??
  • ??????????????
  • ????????}?catch?(Exception?e)?{??
  • ????????????System.out.println(e.getMessage());??
  • ????????????e.printStackTrace();??
  • ????????}??
  • ????}??
  • ??????
  • ??????
  • } ??
  • ?

    轉(zhuǎn)載于:https://www.cnblogs.com/cugwx/p/3664306.html

    總結(jié)

    以上是生活随笔為你收集整理的二叉查找树的Java实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。