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 アップデートをリリース

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

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

推薦する

「AIGC+」|新たなマーケティングパラダイム:AIGCは海外進出企業にとって「新たな武器」となり得るか?

わずか 1 年で、AIGC がもたらした業界を変革するアプリケーションは、徐々に人々の生活の隅々に浸...

AIカンファレンスは数多くあるが、私たちは違う

[51CTO.com からのオリジナル記事] テクノロジーが国の基盤であるならば、人工知能は将来の技...

...

...

AI が Sogou 入力方式の新バージョンを強化: 音声認識は 9 つの言語をサポート

最近、Sogou 入力方式がバージョン 10.8 に更新されました。新バージョンでは、主に音声入力と...

...

AIはセルオートマトンを通じてMinecraftで家を建てることを学ぶ

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

アルゴリズム問題の分析プロセス

[[384555]]トピックを理解する最近アルゴリズムの問​​題をたくさん見ていますが、小さな問題を...

あなたのバイオテクノロジー研究は影響力がありますか? MITの機械学習フレームワークは期待できる

[[400942]]研究者にとって最も嬉しいことは、論文が「受理」されることです。論文が出版された後...

35歳で機械学習と人工知能の分野に参入?

最近、友人とこの問題について話し合っています。ご存知のとおり、IT 業界は標準的な「若者の仕事」です...

...

食品配達ドローンは登場するのか?テンセントが美団の増資を完了、無人配達の研究開発に4億ドルを投資

[[411531]]写真/トゥチョン美団は7月13日夜、テンセントのサブスクリプション契約に含まれる...

スマート音声アシスタントの未来

人工知能は、スマート音声アシスタントが私たちの日常生活でどのように使用されるかを真に変えましたが、私...

人工知能の旅:プロトタイピングは始まりに過ぎない

国内外で人工知能や機械学習のチームが大きな成果のニュースを共有し続けているのをよく見かけますが、実用...

AIがデータ分析を拡張し、効率化する方法

今日のデータ主導の世界では、AI が業界全体を変革しています。 AI は大規模なデータ分析を加速し、...