Java プログラミング スキル - データ構造とアルゴリズム「バイナリ ソート ツリー」

Java プログラミング スキル - データ構造とアルゴリズム「バイナリ ソート ツリー」

[[390181]]

基本的な紹介

バイナリ ソート (検索) ツリー: バイナリ ソート ツリー内のリーフ以外のノードの場合、左のノードの値は現在のノードの値よりも小さく、右のノードの値は現在のノードの値よりも大きくする必要があります。

**特記事項: **同一の値がある場合、ノードは左の子ノードまたは右の子ノードに配置できます。

たとえば、データ {7,3,10,12,5,1,9} の場合、対応するバイナリソートツリーは次のようになります。

バイナリソートツリーのノードを削除する

バイナリソートツリーの削除はより複雑です。次の図に示すように、考慮すべき状況が 3 つあります。

1. リーフノードを削除します(例:2、5、9、12)

  1. 最初に削除するノード targetNode を見つける必要があります
  2. targetNode の親ノード parentNode を検索します (親ノードが存在するかどうかを考慮します)
  3. targetNode が parentNode の左の子か右の子かを判断する
  4. 前の対応する削除によれば、左の子ノード => parent.left = null、右の子ノード => parent.right = null;

2. サブツリーが1つだけのノードを削除します(例:1)

  1. 最初に削除するノード targetNode を見つける必要があります
  2. targetNode の親ノード parentNode を検索します (親ノードが存在するかどうかを考慮します)
  3. ターゲットノードの子が左の子か右の子かを判断する
  4. targetNode が parentNode の左の子か右の子かを判断する
  5. targetNode が parentNode の左の子である場合:
  • targetNode の子ノードが左の子ノードである場合、parentNode.left = targetNode.left となります。targetNode の子ノードが右の子ノードである場合、parentNode.left = targetNode.right となります。
  • targetNode が parentNode の右の子である場合: targetNode の子が左の子である場合、parentNode.right = targetNode.left targetNode の子が右の子である場合、parentNode.right = targetNode.right

3. 2つのサブツリーを持つノードを削除します(例:7、3、10)

  1. 最初に削除するノード targetNode を見つける必要があります
  2. targetNode の親ノード parentNode を検索します (親ノードが存在するかどうかを考慮します)
  3. targetNode の右サブツリーから最小のノードを見つけ、一時変数を使用して右サブツリーの最小ノードの値を temp に保存し、右サブツリーの最小ノードを削除します。その後、targetNode.value = temp; を実行し、左サブツリーから見つけた場合は、左サブツリーの最大値を置き換えます。

コード例:

  1. パッケージ com.xie.bst;
  2.  
  3. パブリッククラスBinarySortTreeDemo {
  4. 公共 静的void main(String[] args) {
  5. int [] arr = {7, 3, 10, 12, 5, 1, 9, 2};
  6. バイナリソートツリーを新規作成します。
  7. ( int i : arr )の場合{
  8. バイナリソートツリーに追加(新しいノード(i)) ;
  9. }
  10. System.out.println ( "バイナリソートツリーの順序付きトラバーサル~" );
  11. バイナリソートツリーの順序を固定します。
  12.  
  13. System.out.println ( "リーフノードの削除をテストする" ) ;
  14. バイナリソートツリー.delNode(10);
  15. System.out.println ( "ノードを削除した後" ) ;
  16. バイナリソートツリーの順序を固定します。
  17. }
  18. }
  19.  
  20. クラス BinarySortTree {
  21. プライベートノードルート;
  22.  
  23. //削除するノードの親ノードを見つける
  24. パブリックノードsearchParent(ノードノード) {
  25. ルートがnull場合
  26. root.searchParent(ノード)を返します
  27. }それ以外{
  28. 戻る ヌル;
  29. }
  30. }
  31.  
  32. // 削除するノードを見つける
  33. パブリックノード検索( int値){
  34. ルートがnull場合
  35. 戻る ヌル;
  36. }それ以外{
  37. root.search(値)を返します
  38. }
  39. }
  40.  
  41. /**
  42. * ノードをルートとする二分ソート木の最小値を見つけ、ノードをルートノードとする二分ソート木の最小ノードを削除します。
  43. *
  44. * @param node 入力ノード(バイナリソートツリーのルートノードとして)
  45. * @returnルートノードとしてノードを持つバイナリソートツリーの最小ノード値を返します
  46. */
  47. 公共  int delRightTreeMin(ノードノード) {
  48. ノードターゲット = ノード;
  49. //左のノードを見つけるためにループする
  50. while ( target.left != null ) {
  51. ターゲット = target.left ;
  52. }
  53. //最小のノードを削除
  54. delNode(ターゲット値);
  55. ターゲット値を返します
  56. }
  57.  
  58. /**
  59. * ノードをルートとする二分ソート木の最大値を見つけ、ノードをルートノードとする二分ソート木の最大ノードを削除します。
  60. *
  61. * @param node 入力ノード(バイナリソートツリーのルートノードとして)
  62. * @returnルートノードとしてノードを持つバイナリソートツリーの最大ノード値を返します
  63. */
  64. 公共  int delLeftTreeMax(ノードノード) {
  65. ノードターゲット = ノード;
  66. while ( target.right != null ) {
  67. ターゲット = target.right ;
  68. }
  69.  
  70. // 最大のノードを削除する
  71. delNode(ターゲット値);
  72. ターゲット値を返します
  73. }
  74.  
  75. //ノードを削除する
  76. パブリックvoid delNode( int値) {
  77. ルートがnull場合
  78. 戻る;
  79. }それ以外{
  80. ノード targetNode = search(値);
  81. ターゲットノードnullの場合
  82. 戻る;
  83. }
  84. ターゲットノード == ルートの場合 {
  85. ルート = null ;
  86. 戻る;
  87. }
  88. ノード parentNode = searchParent(targetNode);
  89.  
  90. targetNode.left == nullかつ targetNode.right == null場合{
  91. //削除するノードがリーフノードの場合
  92. 親ノードの左がnull で、親ノードのが targetNode の値の場合){
  93. 親ノード.left = null ;
  94. }
  95. 親ノードの右がnull != nullかつ親ノードの右がtargetNode の値 == の場合){
  96. 親ノード.right = null ;
  97. }
  98. }それ以外の場合( targetNode.left ! = null && targetNode.right ! = null ) {
  99. //削除するノードが2つのサブツリーを持つノードの場合
  100. int minValue = delRightTreeMin ( targetNode.right );
  101. ターゲットノードの値 = minValue;
  102. // 上位コードと下位コードを削除しても効果は同じです
  103. // int maxValue = delLeftTreeMax ( targetNode.left );
  104. //targetNode.value = maxValue;
  105. }それ以外{
  106. //削除するノードには左の子ノードのみがあります
  107. targetNode.left != null )の場合{
  108. 親ノードがnull場合
  109. 親ノードの左辺がターゲットノードの場合
  110. 親ノードの左=ターゲットノードの左 ;
  111. }それ以外{
  112. 親ノードの右=ターゲットノードの左 ;
  113. }
  114. }それ以外{
  115. //親ノードが空の場合は、ルートの位置を変更します
  116. ルート= targetNode.left ;
  117. }
  118. } else {//削除するノードには右の子ノードのみがある
  119. 親ノードがnull場合
  120. 親ノードの左辺がターゲットノードの場合
  121. 親ノードの左=ターゲットノードの右;
  122. }それ以外{
  123. 親ノードの右=ターゲットノードの右;
  124. }
  125. }それ以外{
  126. //親ノードが空の場合は、ルートの位置を変更します
  127. ルート = targetNode.right ;
  128. }
  129.  
  130. }
  131. }
  132. }
  133. }
  134.  
  135. //ノードを追加
  136. パブリックvoid add (Node ノード) {
  137. ルートがnull場合
  138. ルート = ノード;
  139. }それ以外{
  140. root.add (ノード);
  141. }
  142. }
  143.  
  144. // 順序通りの走査
  145. パブリックvoid infixOrder() {
  146. ルートがnull場合
  147. ルートの順序を固定します。
  148. }それ以外{
  149. System.out.println ( "バイナリソートが空なので走査できません" );
  150. }
  151. }
  152.  
  153. }
  154.  
  155. クラスノード{
  156. int値;
  157. ノード;
  158. ノード;
  159.  
  160. パブリックノード( int値){
  161. this.value = 値;
  162. }
  163.  
  164. /**
  165. * 削除するノードの親ノードを見つける
  166. *
  167. * @param node 削除するノード
  168. * @return削除するノードの親ノード
  169. */
  170. パブリックノードsearchParent(ノードノード) {
  171. //現在のノードが削除するノードの親ノードである場合は、
  172. if (( this.left != null && this.left .value == node.value) ||
  173. ( this.right != null && this.right .value == node.value)) {
  174. これを返します
  175. }それ以外{
  176. if ( this.left != null && node.value < this.value) {
  177. //検索対象のノードの値が現在のノードの値より小さい場合は、左のサブツリーを再帰的に検索します
  178. this.left.searchParent (ノード)を返します
  179. }そうでない場合 (this.right ! = null && value >= this.value) {
  180. //検索対象のノードの値が現在のノードの値より小さい場合は、左のサブツリーを再帰的に検索します
  181. this.right.searchParent (ノード)を返します
  182. }それ以外{
  183. 戻る ヌル;
  184. }
  185. }
  186. }
  187.  
  188. /**
  189. * 削除するノードを見つける
  190. *
  191. * @param value 削除するノードの値
  192. * @return削除されたノード
  193. */
  194. パブリックノード検索( int値){
  195. if (値 == this.value) {
  196. これを返します
  197. }それ以外の場合 (値 < this.value) {
  198. if ( this.left != null ) {
  199. this.left.search (値)を返します
  200. }それ以外{
  201. 戻る ヌル;
  202. }
  203. }それ以外{
  204. if ( this.right != null ) {
  205. this.right.search (値)を返します
  206. }それ以外{
  207. 戻る ヌル;
  208. }
  209. }
  210. }
  211.  
  212. // バイナリソートツリーの要件を満たすためにノードを再帰的に追加します
  213. パブリックvoid add (Node ノード) {
  214. if (ノード == null ) {
  215. 戻る;
  216. }
  217. (ノード値<this値)の場合{
  218. if ( this.left == null ) {
  219. this.left = ノード;
  220. }それ以外{
  221. // 左のサブツリーに再帰的に追加する
  222. this.left.add (ノード) ;
  223. }
  224. }それ以外{
  225. this.rightnull場合
  226. this.right = ノード;
  227. }それ以外{
  228. // 右の子ノードに再帰的に追加します
  229. this.right.add (ノード) ;
  230. }
  231. }
  232. }
  233.  
  234. // 順序通りの走査
  235. パブリックvoid infixOrder() {
  236. if ( this.left != null ) {
  237. this.left .infixOrder();
  238. }
  239. System.out.println (これ) ;
  240. if ( this.right != null ) {
  241. this.right .infixOrder();
  242. }
  243. }
  244.  
  245. @オーバーライド
  246. パブリック文字列toString() {
  247. 戻る  「ノード{」 +
  248. "値=" + 値 +
  249. '}' ;
  250. }
  251. }

【編集者のおすすめ】

  1. Dubbo はマイクロサービスの面接で必ず聞かれる質問です。こんなに詳しい情報では仕事が見つからないのではないかと心配ですか?
  2. 2021年に注目すべきIT業界の5つのトレンド
  3. 無料のセキュリティソフトは寂しい!ため息をつく
  4. インターフェースのUIが変わります! Windows 10 21H2 の最新プレビューを一足先にチェック
  5. マイクロソフト、エクスプローラー検索などの問題を修正するため、Windows 101909 の KB5000850 アップデートをリリース

<<:  ビジネスプロセス管理を使用してマイクロサービス、人、ロボットを調整する方法

>>:  ディープラーニングニューラルネットワークによる予測区間

ブログ    
ブログ    
ブログ    
ブログ    
ブログ    

推薦する

マイクロソフトCEOナデラ氏との対談:AIは雇用を奪うよりも多くを創出する

マイクロソフトのCEOに就任して以来、サティア・ナデラ氏はマイクロソフトを改革した英雄とみなされてき...

...

メルセデス・ベンツCIO:デジタル変革には人工知能の推進力が必要

メルセデス・ベンツは長年、機械学習と従来の人工知能に依存してきました。しかし、現在では、たとえば M...

ロビン・リー:百度はすでに独自のハイエンドチップを製造する能力がある

「中国の改革開放40年はIT産業の爆発的な成長をもたらしたが、ハイエンドチップは常に輸入に依存してき...

銀行業務における人工知能と機械学習の利用拡大

[[432637]]銀行ガバナンスリーダーシップネットワーク(BGLN)は最近、銀行が人工知能(AI...

アリババ、量子アルゴリズムとエラー訂正の探究をサポートする量子シミュレータ「Taizhang 2.0」をオープンソース化

この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI)より許可を得て転載...

視覚慣性走行距離計のIMU事前統合モデルについてお話しましょう

エンジニアリングの実践では、単に視覚オドメトリ (VO) を使用するのではなく、視覚と IMU を組...

...

AI言語モデルにおける幻覚バイアスのリスク

音声アシスタントからチャットボットまで、人工知能 (AI) はテクノロジーとのやり取りの方法に革命を...

エンタープライズレベルの AI を実装するにはどうすればよいでしょうか? Watson なら問題ありません!

[51CTO.com からのオリジナル記事] 人工知能は間違いなく、今日最も注目されている技術の ...

在庫: 2020 年の最もクールな AI チップ スタートアップ 10 社

AIチップをめぐる争いはインテルやエヌビディアなどの半導体大手の間で激化しているが、多くの中小企業も...

...

パナソニック、AI企業ブルーヨンダーを60億ドル超で買収へ

海外メディアの報道によると、パナソニックは今年3月にアメリカのAIソフト開発会社ブルーヨンダーを70...

Python 用 OpenCV について Dlib を使って顔検出を実装する

Dlib は、プログラミング言語 C++ で記述された汎用のクロスプラットフォーム ソフトウェア ラ...