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

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

[[388287]]

なぜツリー構造が必要なのでしょうか?

1. 配列格納方法の分析:

  • 利点: 下付き文字で要素に高速にアクセスします。順序付けられた配列の場合、バイナリ検索を使用して検索速度を上げることもできます。
  • デメリット: 特定の値を取得したり、値を挿入したり (特定の順序で) すると、テーブル全体が移動されるため、非効率的です。

2. チェーンストレージ方式の分析:

  • 利点: ある程度、配列の保存方法を最適化します (たとえば、数値ノードを挿入するには、挿入されたノードをリンク リストにリンクするだけでよく、削除効率が非常に高くなります)。
  • デメリット: 検索を実行する場合、効率は依然として非常に低く、最初のノードからトラバースする必要があります。

3. ツリー保存方法の分析:データの保存と読み取りの効率を向上させることができます。たとえば、バイナリソートツリーを使用すると、データ検索の速度が保証されるだけでなく、データの挿入、削除、変更の速度も保証されます。集合[7,3,10,1,5,9,12]がツリーに格納されており、分析は次のようになると仮定します。


二分木の前順、中順、後順の走査

  • 事前順序トラバーサル: 親ノードを出力し、左ノードを出力し、右ノードを出力します。
  • 順序どおりのトラバーサル: 左のノードを出力し、親ノードを出力し、右のノードを出力します。
  • 後順トラバーサル: 左ノードを出力し、右ノードを出力し、親ノードを出力します。

需要事例

次のバイナリ ツリー ノードの保存、事前順序トラバーサル検索、順序内トラバーサル検索、事後順序トラバーサル検索、およびノー​​ド削除機能を完了します。

ノードを削除するための要件は次のとおりです。

  1. 削除するノードがリーフノードの場合は、そのノードを削除します。
  2. 削除されるノードが非リーフノードの場合、ツリーは削除されます。
  3. テストして、リーフ ノード 5 とサブツリー 3 を削除します。

コード例

  1. パッケージ com.xie.tree;
  2.  
  3. パブリッククラス BinaryTreeDemo {
  4.  
  5. 公共 静的void main(String[] args) {
  6. バイナリツリー binaryTree = new BinaryTree();
  7.  
  8. HeroNode ルート = new HeroNode(1, "Song Jiang" );
  9. HeroNode node2 = 新しいHeroNode(2, "Wu Yong" );
  10. HeroNode node3 = 新しい HeroNode(3, "Lu Junyi" );
  11. HeroNode node4 = 新しい HeroNode(4, "Lin Chong" );
  12. HeroNode node5 = 新しい HeroNode(5, "Guan Sheng" );
  13.  
  14. // まず手動でバイナリツリーを作成し、次に再帰を使用します
  15. ルート.setLeft(ノード2);
  16. ルートを右に設定します(ノード3);
  17. ノード4を右に設定します。
  18. ノード3を左に設定します(ノード5);
  19.  
  20. バイナリツリーのルートを設定します。
  21.  
  22. // 事前順序トラバーサル
  23. System.out.println ( "事前順序トラバーサル" );
  24. バイナリツリーの事前順序付け();
  25.  
  26. // 順序通りの走査
  27. System.out.println ( "順序通りの走査" );
  28. バイナリツリーの順序を固定します。
  29.  
  30. //後続のトラバーサル
  31. System.out.println ( "後続のトラバーサル" ) ;
  32. バイナリツリーの postOrder() を返します。
  33.  
  34. // 先行順序トラバーサル検索
  35. System.out.println ( "事前順序トラバーサル検索~~" );
  36. HeroNode の結果ノード = binaryTree.preOrderSearch(5);
  37. 結果ノードがnull場合
  38. System.out.printf ( "見つかりました。情報は番号=%d、名前=%s\nです" 、resultNode.getNo()、resultNode.getName());
  39. System.out.println ( "トラバーサル数:" + HeroNode.preCount);
  40. }それ以外{
  41. System.out.println ( "見つかりません" );
  42. }
  43.  
  44. // 順序通りのトラバーサル検索
  45. System.out.println ( "インオーダートラバーサル検索~~" );
  46. ヒーローノード resultNode1 = binaryTree.infixOrderSearch(5);
  47. (resultNode1 != null )の場合 {
  48. System.out.printf ( "見つかりました。情報は番号=%d、名前=%s\nです" 、resultNode1.getNo()、resultNode1.getName());
  49. System.out.println ( "トラバーサル数:" + HeroNode.infoxCount);
  50. }それ以外{
  51. System.out.println ( "見つかりません" );
  52. }
  53.  
  54. // 後順トラバーサル検索
  55. System.out.println ( "後順トラバーサル検索~~" );
  56. HeroNode の結果ノード2 = binaryTree.postOrderSearch(5);
  57. (resultNode2がnullの場合){
  58. System.out.printf ( "見つかりました。情報は番号=%d、名前=%s\nです" 、resultNode2.getNo()、resultNode2.getName());
  59. System.out.println ( "トラバーサル数:" + HeroNode.postCount);
  60. }それ以外{
  61. System.out.println ( "見つかりません" );
  62. }
  63.  
  64. System.out.println ( "ノード3を削除します" );
  65. バイナリツリー.delNo(3);
  66. System.out.println ( "削除後のノード" );
  67. バイナリツリーの事前順序付け();
  68. /**
  69. * 事前注文トラバーサル
  70. * HeroNode{番号=1、名前=Song Jiang}
  71. * HeroNode{番号=2、名前=Wu Yong}
  72. * HeroNode{番号=3、名前=Lu Junyi}
  73. * HeroNode{番号=5、名前=Guan Sheng}
  74. * HeroNode{番号=4、名前=Lin Chong}
  75. * 順序通りの走査
  76. * HeroNode{番号=2、名前=Wu Yong}
  77. * HeroNode{番号=1、名前=Song Jiang}
  78. * HeroNode{番号=5、名前=Guan Sheng}
  79. * HeroNode{番号=3、名前=Lu Junyi}
  80. * HeroNode{番号=4、名前=Lin Chong}
  81. * その後のトラバース
  82. * HeroNode{番号=2、名前=Wu Yong}
  83. * HeroNode{番号=5、名前=Guan Sheng}
  84. * HeroNode{番号=4、名前=Lin Chong}
  85. * HeroNode{番号=3、名前=Lu Junyi}
  86. * HeroNode{番号=1、名前=Song Jiang}
  87. * 事前注文トラバーサル検索~~
  88. * 見つかりました、情報番号=5、名前= Guan Sheng
  89. * トラバース回数: 4
  90. * 順序探索検索~~
  91. * 見つかりました、情報番号=5、名前= Guan Sheng
  92. * トラバース回数: 3
  93. * 後順トラバーサル検索~~
  94. * 見つかりました、情報番号=5、名前= Guan Sheng
  95. * トラバース回数: 2
  96. * ノード3を削除
  97. * 削除後のノード
  98. * HeroNode{番号=1、名前=Song Jiang}
  99. * HeroNode{番号=2、名前=Wu Yong}
  100. */
  101. }
  102. }
  103.  
  104. クラス BinaryTree {
  105. プライベート HeroNode ルート;
  106.  
  107. パブリックvoid setRoot(HeroNode ルート) {
  108. ルート
  109. }
  110.  
  111. // 事前順序トラバーサル
  112. パブリックボイドpreOrder() {
  113. this.root != null の場合{
  114. this.root.preOrder();
  115. }
  116. }
  117.  
  118. // 順序通りの走査
  119. パブリックvoid infixOrder() {
  120. this.root != null の場合{
  121. this.root.infixOrder();
  122. }
  123. }
  124.  
  125. //ノードを削除する
  126. パブリックvoid delNo( int  いいえ) {
  127. this.root != null の場合{
  128. if (this.root.getNo() == no ) {
  129. this.root = null ;
  130. }それ以外{
  131. this.root.delNo(いいえ);
  132. }
  133. }
  134. 戻る;
  135. }
  136.  
  137. //後順トラバーサル
  138. パブリックボイドpostOrder() {
  139. this.root != null の場合{
  140. this.root.postOrder();
  141. }
  142. }
  143.  
  144. // 先行順序トラバーサル検索
  145. パブリックHeroNode preOrderSearch( int  いいえ) {
  146. ルートがnull場合
  147. root.preOrderSearch( no )を返します
  148. }それ以外{
  149. 戻る ヌル;
  150. }
  151. }
  152.  
  153. // 順序通りのトラバーサル検索
  154. パブリックHeroNode infixOrderSearch( int  いいえ) {
  155. ルートがnull場合
  156. root.infixOrderSearch( no );を返します
  157. }それ以外{
  158. 戻る ヌル;
  159. }
  160. }
  161.  
  162. // 後順トラバーサル検索
  163. パブリックHeroNode postOrderSearch( int  いいえ) {
  164. ルートがnull場合
  165. root.postOrderSearch( no )を返します
  166. }それ以外{
  167. 戻る ヌル;
  168. }
  169. }
  170. }
  171.  
  172. クラスHeroNode {
  173. 静的 プリカウント = 0;
  174. 静的  int インフォックスカウント = 0;
  175. 静的 投稿= 0;
  176.  
  177. プライベートint  いいえ;
  178. プライベート文字列;
  179. プライベートHeroNodeが残りました;
  180. プライベートHeroNode;
  181.  
  182. パブリックHeroNode( int  いいえ、文字列){
  183. this.no =いいえ;
  184. this.name =名前;
  185. }
  186.  
  187. 公共 整数getNo() {
  188. 戻る いいえ;
  189. }
  190.  
  191. パブリックボイドsetNo( int  いいえ) {
  192. this.no =いいえ;
  193. }
  194.  
  195. パブリック文字列getName() {
  196. 戻る 名前;
  197. }
  198.  
  199. パブリックvoid setName(文字列) {
  200. this.name =名前;
  201. }
  202.  
  203. パブリックHeroNode getLeft() {
  204. 戻る ;
  205. }
  206.  
  207. パブリックvoid setLeft(HeroNode left ) {
  208. this.left =;
  209. }
  210.  
  211. パブリックHeroNode getRight() {
  212. 戻る ;
  213. }
  214.  
  215. パブリックvoid setRight(HeroNode) {
  216. this.right =;
  217. }
  218.  
  219. @オーバーライド
  220. パブリック文字列toString() {
  221. 戻る  「ヒーローノード{" +
  222. 「いいえ=」 +いいえ+
  223. ", 名前=" +名前+
  224. '}' ;
  225. }
  226.  
  227. // 事前順序トラバーサル
  228. パブリックボイドpreOrder() {
  229. System.out.println (これ) ;
  230. // 左のサブツリーを前順序で再帰的に走査する
  231. if ( this.left != null ) {
  232. this.left.preOrder ();
  233. }
  234.  
  235. // 右のサブツリーを前順序で再帰的に走査する
  236. if ( this.right != null ) {
  237. this.right .preOrder();
  238. }
  239. }
  240.  
  241. // 順序通りの走査
  242. パブリックvoid infixOrder() {
  243. //左のサブツリーを順番に再帰的に走査する
  244. if ( this.left != null ) {
  245. this.left .infixOrder();
  246. }
  247. System.out.println (これ) ;
  248. //右のサブツリーを順番に再帰的に走査する
  249. if ( this.right != null ) {
  250. this.right .infixOrder();
  251. }
  252. }
  253.  
  254. //後順走査
  255. パブリックボイドpostOrder() {
  256. // 左のサブツリーを後順に再帰的に走査する
  257. if ( this.left != null ) {
  258. this.left .postOrder();
  259. }
  260. // 右のサブツリーを後順で再帰的に走査する
  261. if ( this.right != null ) {
  262. this.right .postOrder();
  263. }
  264. System.out.println (これ) ;
  265. }
  266.  
  267. // ノードを再帰的に削除する
  268. //1. 削除するノードがリーフノードの場合は、そのノードを削除します。
  269. //2. 削除されたノードが非リーフノードの場合は、ツリーを削除します。
  270. パブリックvoid delNo( int  いいえ) {
  271. /**
  272. * 1. バイナリ ツリーは一方向であるため、現在のノードの子ノードが削除する必要があるノードであるかどうかを判断できますが、現在のノードが削除する必要があるノードであるかどうかを判断することはできません。
  273. * 2. 現在のノードの左の子が空でなく、左の子が削除対象のノードである場合は、 this.left = null ; を設定して戻ります (再帰を終了)。
  274. * 3. 現在のノードの右の子が空でなく、右の子が削除対象のノードである場合は、 this.right = null ; を設定して戻ります (再帰を終了)。
  275. * 4. 手順 2 と 3 でノードが削除されない場合、左のサブツリーに対して再帰的な削除が実行されます。
  276. * 5. 手順 4 でノードが削除されなかった場合は、右側のサブツリーに対して再帰的な削除を実行する必要があります。
  277. */
  278. if ( this.left != null && this.left . no == no ) {
  279. this.left = null ;
  280. 戻る;
  281. }
  282.  
  283. this.right != null && this.right . no == no場合{
  284. this.right = null ;
  285. 戻る;
  286. }
  287.  
  288. if ( this.left != null ) {
  289. this.left.delNo (いいえ) ;
  290. }
  291.  
  292. if ( this.right != null ) {
  293. this.right .delNo(いいえ);
  294. }
  295.  
  296. }
  297.  
  298. // 先行順序トラバーサル検索
  299. パブリックHeroNode preOrderSearch( int  いいえ) {
  300.  
  301. HeroNode res = null ;
  302.  
  303. preCount++; //実際の比較を実行するには、 this.no == no の判定の前にこれを配置する必要があります。
  304. //見つかった場合は返す
  305. if ( this.no == no ) {
  306. これを返します
  307. }
  308. //見つからない場合は、左のサブツリーを再帰的に検索して先行順序を検索します
  309. if ( this.left != null ) {
  310. res = this.left.preOrderSearch ( no );
  311. }
  312. // res の場合! = nullは直接返されます
  313. (res != null )の場合{
  314. resを返します
  315. }
  316. //左のサブツリーが見つからない場合は、右のサブツリーに対して事前順序検索を実行します
  317. if ( this.right != null ) {
  318. res = this.right.preOrderSearch ( no );
  319. }
  320. // 見つかった場合は返す
  321. (res != null )の場合{
  322. resを返します
  323. }
  324. resを返します
  325. }
  326.  
  327. // 順序通りのトラバーサル検索
  328. パブリックHeroNode infixOrderSearch( int  いいえ) {
  329.  
  330. HeroNode res = null ;
  331. if ( this.left != null ) {
  332. res = this.left.infixOrderSearch (いいえ);
  333. }
  334. (res != null )の場合{
  335. resを返します
  336. }
  337. infoxCount++; //実際の比較を実行するには、 this.no == no の判定の前にこれを配置する必要があります。
  338. if ( this.no == no ) {
  339. これを返します
  340. }
  341. if ( this.right != null ) {
  342. res = this.right.infixOrderSearch (いいえ);
  343. }
  344. (res != null )の場合{
  345. resを返します
  346. }
  347. resを返します
  348. }
  349.  
  350. // 後順トラバーサル検索
  351. パブリックHeroNode postOrderSearch( int  いいえ) {
  352.  
  353. HeroNode res = null ;
  354. if ( this.left != null ) {
  355. res = this.left.postOrderSearch ( no );
  356. }
  357. (res != null )の場合{
  358. resを返します
  359. }
  360.  
  361. if ( this.right != null ) {
  362. res = this.right.postOrderSearch (いいえ);
  363. }
  364. (res != null )の場合{
  365. resを返します
  366. }
  367. postCount++; //実際の比較を実行するには、 this.no == no の判定の前にこれを配置する必要があります
  368. if ( this.no == no ) {
  369. これを返します
  370. }
  371. resを返します
  372. }
  373. }

【編集者のおすすめ】

  1. K8S の基本的なアーキテクチャ概念とネットワーク モデルを理解するのに役立つ 5 分
  2. 1992 年に Baidu のプログラマーが逮捕されたことは、私たちにどのような警告を与えているのでしょうか。
  3. オープンソースのクラウドディスクツール: Nextcloud 21 プライベートクラウドディスク構築
  4. よりクリーンなMicrosoft Windows 10 21H2メジャーアップデートにより、システム内の肥大化したソフトウェアの数が削減されます
  5. 996 作業システムは良いのか悪いのか?

<<:  コミュニティは顔認証システムを起動し、アクセスカードを無効にしました。情報セキュリティを心配し、登録を望まない所有者は帰宅に困難をきたしています。顔認証の強制適用の境界線はどこにあるのでしょうか?

>>:  サプライチェーンをより俊敏にするにはどうすればよいでしょうか?データクリーニングの問題はAIに引き継がれる

ブログ    
ブログ    

推薦する

IoTとAIのトレンドが今日のビジネスに及ぼす影響

IoT と AI の誇大宣伝サイクルは、企業が大きな価値を認識し始める段階まで進んでいます。 IoT...

...

2年後には「ロボット」が人間の活動の80%以上をこなすようになるのでしょうか? AIに関する専門家の見解を聞く

写真:人工知能カンファレンスフォーラム 撮影:新民晩報主任記者 劉欣 「私は生産性を変革し、新しい...

2021 年に企業に影響を与える自然言語処理のトレンド

[[384737]] [51CTO.com クイック翻訳] 昨今、自然言語技術は企業でますます活用さ...

ビジネスアナリストにとってAIが意味するもの

[[275322]]今日では、人工知能はもはや流行語ではなく、多くの環境ビジネスアナリストやその他の...

北京大学の王一州氏:信頼できるAI研究の名刺を磨くには、産業界、学界、研究機関の連携が必要

人工知能(AI)は1950年代に誕生し、3つの発展の波を経てきました。研究段階から大規模な産業化段階...

...

...

...

...

コンピュータビジョンがビジネス課題の解決に役立つ 5 つの方法

自動運転車、交通標識検出、顔認識、セルフサービスチェックアウト。 これらすべての高度なソリューション...

プログラマーという職業は10年以内にAIによって消滅するのでしょうか?

これは非常に興味深い質問です。プログラマーという職業はAIによって消滅することはないと思いますが、プ...

GPTストアはオンラインになるとすぐに混乱に陥り、偽造品、偽のトラフィック、禁止されたコンテンツが次々と出現します

新しくオープンしたGPTストアが「混沌」していることで有名になるとは思ってもいませんでした。見てくだ...

人間の審判が解雇される?冬季オリンピックのテストマッチで選手の得点をつけた人物はAIだった

2021年の欧州選手権でイングランドはデンマークを破り、初めて欧州選手権決勝に進出した。歴史に名を残...