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

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

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

ブログ    
ブログ    

推薦する

ChatGPTを使用してスマートコントラクトとブロックチェーンに革命を起こす方法

1. はじめに近年、人工知能(AI)の進歩により、さまざまな業界に革命が起きています。 ChatGP...

組み込みアルゴリズムソートアルゴリズム

[[433624]] 1. バブルソートバブル ソートは、C 言語のシンプルな初級レベルのソート ア...

AI と Wi-Fi 6: 家庭内 Wi-Fi の革命を推進

固定ネットワークが F5G (第 5 世代) 時代に入るにつれ、家庭用 Wi-Fi テクノロジも、新...

...

Java 実装と読み取り/書き込みロック アルゴリズムの考え方

問題の背景: 複数のスレッドが共有リソースへの読み取りおよび書き込みアクセスを実行します。書き込みス...

...

大きなモデルが常に「事実」を間違えた場合はどうすればよいでしょうか? 300以上の論文のレビューはこちら

ビッグモデルは事実の知識を習得する上で優れた能力と可能性を示していますが、ドメイン知識の欠如、リアル...

快手は快易のビッグモデルの助けを借りてコメントエリアでのインテリジェントな返信を実現する「AI小快」をテスト中

快手は10月26日、「AI小快」アカウントの内部テストを正式に開始し、ショートビデオコメントエリアで...

市場規模は100億を超え、マシンビジョンはブルーオーシャンの傾向を示す

マシンビジョンとは、人間の目の代わりに機械を使って物事を測定・判断し、その判断結果に基づいて現場の設...

ビッグデータと AI: 3 つの実際の使用例

ビッグデータと人工知能は、企業が新しい方法で顧客体験を向上させるのに役立ちます。 AIとビッグデータ...

自動運転車と機械学習:交通の未来を変える

自動運転車と機械学習は、自動車業界に革命をもたらす画期的な技術として登場しました。人工知能 (AI)...

...

人工知能は衛星地図の鮮明度を向上させ、世界の再生可能エネルギープロジェクトや森林被覆率を示す

マイクロソフトの共同創業者ポール・アレン氏が設立したアレンAI研究所は最近、Satlasと呼ばれる新...

AIチップ市場に必要なのは火か氷か?

最近、AIチップ市場は明らかに冷え込んでいます。チップ市場のリーダーであるNvidiaが先日発表した...