自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Java編程內(nèi)功-數(shù)據(jù)結(jié)構(gòu)與算法「樹」

開發(fā) 后端 算法
本片繼續(xù)給大家介紹關(guān)于Java編程數(shù)據(jù)結(jié)構(gòu)與算法的相關(guān)內(nèi)容,今天主要介紹樹這種結(jié)構(gòu)。

[[388287]]

 為什么需要樹這種結(jié)構(gòu)

1.數(shù)組存儲方式分析:

  • 優(yōu)點:通過下標(biāo)方式訪問元素,速度快。對于有序數(shù)組,還可以使用二分查找提高檢索速度。
  • 缺點:如果檢索某個具體的值,或者插入值(按一定的順序)會整體移動,效率較低。

2.鏈?zhǔn)酱鎯Ψ绞椒治觯?/p>

  • 優(yōu)點:在一定程度上對數(shù)組存儲方式優(yōu)化(比如:插入一個數(shù)值節(jié)點,只需要將插入節(jié)點,鏈接到鏈表中即可,刪除效率很高)。
  • 缺點:在進行檢索時,效率仍然很低,需要從頭結(jié)點開始遍歷。

3.樹存儲方式分析:能提高數(shù)據(jù)存儲,讀取的效率,比如利用二叉排序樹(Binary sort tree),即可以保證數(shù)據(jù)的檢索速度,同時也可以保證數(shù)據(jù)的插入、刪除、修改的速度。假設(shè)一組[7,3,10,1,5,9,12]以樹的方式存儲,分析如下圖:


二叉樹的前序遍歷、中序遍歷、后序遍歷

  • 前序遍歷:輸出父節(jié)點、輸出左邊節(jié)點、輸出右邊節(jié)點;
  • 中序遍歷:輸出左邊節(jié)點、輸出父節(jié)點、輸出右邊節(jié)點;
  • 后序遍歷:輸出左邊節(jié)點、輸出右邊節(jié)點、輸出父節(jié)點;

需求案例

完成一個如下二叉樹節(jié)點存儲、前序遍歷搜索、中序遍歷搜索、后序遍歷搜索和刪除節(jié)點功能。

對于刪除節(jié)點要求如下:

  1. 如果刪除的節(jié)點是葉子節(jié)點,則刪除該節(jié)點。
  2. 如果刪除的節(jié)點是非葉子節(jié)點,則刪除該樹。
  3. 測試,刪除5號葉子節(jié)點和3號子樹。

代碼案例

  1. package com.xie.tree; 
  2.  
  3. public class BinaryTreeDemo { 
  4.  
  5.     public static void main(String[] args) { 
  6.         BinaryTree binaryTree = new BinaryTree(); 
  7.  
  8.         HeroNode root = new HeroNode(1, "宋江"); 
  9.         HeroNode node2 = new HeroNode(2, "吳用"); 
  10.         HeroNode node3 = new HeroNode(3, "盧俊義"); 
  11.         HeroNode node4 = new HeroNode(4, "林沖"); 
  12.         HeroNode node5 = new HeroNode(5, "關(guān)勝"); 
  13.  
  14.         //先手動創(chuàng)建該二叉樹,后面用遞歸方式 
  15.         root.setLeft(node2); 
  16.         root.setRight(node3); 
  17.         node3.setRight(node4); 
  18.         node3.setLeft(node5); 
  19.  
  20.         binaryTree.setRoot(root); 
  21.  
  22.         //前序遍歷 
  23.         System.out.println("前序遍歷"); 
  24.         binaryTree.preOrder(); 
  25.  
  26.         //中序遍歷 
  27.         System.out.println("中序遍歷"); 
  28.         binaryTree.infixOrder(); 
  29.  
  30.         //后續(xù)遍歷 
  31.         System.out.println("后續(xù)遍歷"); 
  32.         binaryTree.postOrder(); 
  33.  
  34.         //前序遍歷查找 
  35.         System.out.println("前序遍歷查找~~"); 
  36.         HeroNode resultNode = binaryTree.preOrderSearch(5); 
  37.         if (resultNode != null) { 
  38.             System.out.printf("找到了,信息為no=%d,name=%s\n", resultNode.getNo(), resultNode.getName()); 
  39.             System.out.println("遍歷次數(shù):" + HeroNode.preCount); 
  40.         } else { 
  41.             System.out.println("沒有找到"); 
  42.         } 
  43.  
  44.         //中序遍歷查找 
  45.         System.out.println("中序遍歷查找~~"); 
  46.         HeroNode resultNode1 = binaryTree.infixOrderSearch(5); 
  47.         if (resultNode1 != null) { 
  48.             System.out.printf("找到了,信息為no=%d,name=%s\n", resultNode1.getNo(), resultNode1.getName()); 
  49.             System.out.println("遍歷次數(shù):" + HeroNode.infoxCount); 
  50.         } else { 
  51.             System.out.println("沒有找到"); 
  52.         } 
  53.  
  54.         //后序遍歷查找 
  55.         System.out.println("后序遍歷查找~~"); 
  56.         HeroNode resultNode2 = binaryTree.postOrderSearch(5); 
  57.         if (resultNode2 != null) { 
  58.             System.out.printf("找到了,信息為no=%d,name=%s\n", resultNode2.getNo(), resultNode2.getName()); 
  59.             System.out.println("遍歷次數(shù):" + HeroNode.postCount); 
  60.         } else { 
  61.             System.out.println("沒有找到"); 
  62.         } 
  63.  
  64.         System.out.println("刪除3號節(jié)點"); 
  65.         binaryTree.delNo(3); 
  66.         System.out.println("刪除后的節(jié)點"); 
  67.         binaryTree.preOrder(); 
  68.         /** 
  69.          * 前序遍歷 
  70.          * HeroNode{no=1, name=宋江} 
  71.          * HeroNode{no=2, name=吳用} 
  72.          * HeroNode{no=3, name=盧俊義} 
  73.          * HeroNode{no=5, name=關(guān)勝} 
  74.          * HeroNode{no=4, name=林沖} 
  75.          * 中序遍歷 
  76.          * HeroNode{no=2, name=吳用} 
  77.          * HeroNode{no=1, name=宋江} 
  78.          * HeroNode{no=5, name=關(guān)勝} 
  79.          * HeroNode{no=3, name=盧俊義} 
  80.          * HeroNode{no=4, name=林沖} 
  81.          * 后續(xù)遍歷 
  82.          * HeroNode{no=2, name=吳用} 
  83.          * HeroNode{no=5, name=關(guān)勝} 
  84.          * HeroNode{no=4, name=林沖} 
  85.          * HeroNode{no=3, name=盧俊義} 
  86.          * HeroNode{no=1, name=宋江} 
  87.          * 前序遍歷查找~~ 
  88.          * 找到了,信息為no=5,name=關(guān)勝 
  89.          * 遍歷次數(shù):4 
  90.          * 中序遍歷查找~~ 
  91.          * 找到了,信息為no=5,name=關(guān)勝 
  92.          * 遍歷次數(shù):3 
  93.          * 后序遍歷查找~~ 
  94.          * 找到了,信息為no=5,name=關(guān)勝 
  95.          * 遍歷次數(shù):2 
  96.          * 刪除3號節(jié)點 
  97.          * 刪除后的節(jié)點 
  98.          * HeroNode{no=1, name=宋江} 
  99.          * HeroNode{no=2, name=吳用} 
  100.          */ 
  101.     } 
  102.  
  103. class BinaryTree { 
  104.     private HeroNode root; 
  105.  
  106.     public void setRoot(HeroNode root) { 
  107.         this.root = root; 
  108.     } 
  109.  
  110.     //前序遍歷 
  111.     public void preOrder() { 
  112.         if (this.root != null) { 
  113.             this.root.preOrder(); 
  114.         } 
  115.     } 
  116.  
  117.     //中序遍歷 
  118.     public void infixOrder() { 
  119.         if (this.root != null) { 
  120.             this.root.infixOrder(); 
  121.         } 
  122.     } 
  123.  
  124.     //刪除節(jié)點 
  125.     public void delNo(int no) { 
  126.         if (this.root != null) { 
  127.             if (this.root.getNo() == no) { 
  128.                 this.root = null
  129.             } else { 
  130.                 this.root.delNo(no); 
  131.             } 
  132.         } 
  133.         return
  134.     } 
  135.  
  136.     //后序遍歷 
  137.     public void postOrder() { 
  138.         if (this.root != null) { 
  139.             this.root.postOrder(); 
  140.         } 
  141.     } 
  142.  
  143.     //前序遍歷查找 
  144.     public HeroNode preOrderSearch(int no) { 
  145.         if (root != null) { 
  146.             return root.preOrderSearch(no); 
  147.         } else { 
  148.             return null
  149.         } 
  150.     } 
  151.  
  152.     //中序遍歷查找 
  153.     public HeroNode infixOrderSearch(int no) { 
  154.         if (root != null) { 
  155.             return root.infixOrderSearch(no); 
  156.         } else { 
  157.             return null
  158.         } 
  159.     } 
  160.  
  161.     //后序遍歷查找 
  162.     public HeroNode postOrderSearch(int no) { 
  163.         if (root != null) { 
  164.             return root.postOrderSearch(no); 
  165.         } else { 
  166.             return null
  167.         } 
  168.     } 
  169.  
  170. class HeroNode { 
  171.     static int preCount = 0; 
  172.     static int infoxCount = 0; 
  173.     static int postCount = 0; 
  174.  
  175.     private int no
  176.     private String name
  177.     private HeroNode left
  178.     private HeroNode right
  179.  
  180.     public HeroNode(int no, String name) { 
  181.         this.no = no
  182.         this.name = name
  183.     } 
  184.  
  185.     public int getNo() { 
  186.         return no
  187.     } 
  188.  
  189.     public void setNo(int no) { 
  190.         this.no = no
  191.     } 
  192.  
  193.     public String getName() { 
  194.         return name
  195.     } 
  196.  
  197.     public void setName(String name) { 
  198.         this.name = name
  199.     } 
  200.  
  201.     public HeroNode getLeft() { 
  202.         return left
  203.     } 
  204.  
  205.     public void setLeft(HeroNode left) { 
  206.         this.left = left
  207.     } 
  208.  
  209.     public HeroNode getRight() { 
  210.         return right
  211.     } 
  212.  
  213.     public void setRight(HeroNode right) { 
  214.         this.right = right
  215.     } 
  216.  
  217.     @Override 
  218.     public String toString() { 
  219.         return "HeroNode{" + 
  220.                 "no=" + no + 
  221.                 ", name=" + name + 
  222.                 '}'
  223.     } 
  224.  
  225.     //前序遍歷 
  226.     public void preOrder() { 
  227.         System.out.println(this); 
  228.         //遞歸向左子樹前序遍歷 
  229.         if (this.left != null) { 
  230.             this.left.preOrder(); 
  231.         } 
  232.  
  233.         //遞歸向右子樹前序遍歷 
  234.         if (this.right != null) { 
  235.             this.right.preOrder(); 
  236.         } 
  237.     } 
  238.  
  239.     //中序遍歷 
  240.     public void infixOrder() { 
  241.         //遞歸向左子樹中序遍歷 
  242.         if (this.left != null) { 
  243.             this.left.infixOrder(); 
  244.         } 
  245.         System.out.println(this); 
  246.         //遞歸向右子樹中序遍歷 
  247.         if (this.right != null) { 
  248.             this.right.infixOrder(); 
  249.         } 
  250.     } 
  251.  
  252.     //后序遍歷 
  253.     public void postOrder() { 
  254.         //遞歸向左子樹后序遍歷 
  255.         if (this.left != null) { 
  256.             this.left.postOrder(); 
  257.         } 
  258.         //遞歸向右子樹后序遍歷 
  259.         if (this.right != null) { 
  260.             this.right.postOrder(); 
  261.         } 
  262.         System.out.println(this); 
  263.     } 
  264.  
  265.     //遞歸刪除節(jié)點 
  266.     //1.如果刪除的節(jié)點是葉子節(jié)點,則刪除該節(jié)點。 
  267.     //2.如果刪除的節(jié)點是非葉子節(jié)點,則刪除該樹。 
  268.     public void delNo(int no) { 
  269.         /** 
  270.          * 1.因為我們的二叉樹是單向的,所以我們是判斷當(dāng)前節(jié)點的子節(jié)點是否是需要刪除的節(jié)點,而不能去判斷當(dāng)前節(jié)點是否是需要刪除的節(jié)點。 
  271.          * 2.如果當(dāng)前節(jié)點的左子節(jié)點不為空,并且左子節(jié)點就是需要刪除的節(jié)點,就將this.left = null;并且返回(結(jié)束遞歸)。 
  272.          * 3.如果當(dāng)前節(jié)點的右子節(jié)點不為空,并且右子節(jié)點就是需要刪除的節(jié)點,將將this.right = null;并且返回(結(jié)束遞歸)。 
  273.          * 4.如果第2步和第3步?jīng)]有刪除節(jié)點,那么就要向左子樹進行遞歸刪除。 
  274.          * 5.如果第4步也沒有刪除節(jié)點,則應(yīng)當(dāng)向右子樹進行遞歸刪除。 
  275.          */ 
  276.         if (this.left != null && this.left.no == no) { 
  277.             this.left = null
  278.             return
  279.         } 
  280.  
  281.         if (this.right != null && this.right.no == no) { 
  282.             this.right = null
  283.             return
  284.         } 
  285.  
  286.         if (this.left != null) { 
  287.             this.left.delNo(no); 
  288.         } 
  289.  
  290.         if (this.right != null) { 
  291.             this.right.delNo(no); 
  292.         } 
  293.  
  294.     } 
  295.  
  296.     //前序遍歷查找 
  297.     public HeroNode preOrderSearch(int no) { 
  298.  
  299.         HeroNode res = null
  300.  
  301.         preCount++;//這里必須放在this.no == no 判斷之前,才進行實際的比較 
  302.         //若果找到,就返回 
  303.         if (this.no == no) { 
  304.             return this; 
  305.         } 
  306.         //沒有找到,向左子樹遞歸進行前序查找 
  307.         if (this.left != null) { 
  308.             res = this.left.preOrderSearch(no); 
  309.         } 
  310.         //如果res != null 就直接返回 
  311.         if (res != null) { 
  312.             return res; 
  313.         } 
  314.         //如果左子樹沒有找打,向右子樹進行前序查找 
  315.         if (this.right != null) { 
  316.             res = this.right.preOrderSearch(no); 
  317.         } 
  318.         //如果找到就返回 
  319.         if (res != null) { 
  320.             return res; 
  321.         } 
  322.         return res; 
  323.     } 
  324.  
  325.     //中序遍歷查找 
  326.     public HeroNode infixOrderSearch(int no) { 
  327.  
  328.         HeroNode res = null
  329.         if (this.left != null) { 
  330.             res = this.left.infixOrderSearch(no); 
  331.         } 
  332.         if (res != null) { 
  333.             return res; 
  334.         } 
  335.         infoxCount++;//這里必須放在this.no == no 判斷之前,才進行實際的比較 
  336.         if (this.no == no) { 
  337.             return this; 
  338.         } 
  339.         if (this.right != null) { 
  340.             res = this.right.infixOrderSearch(no); 
  341.         } 
  342.         if (res != null) { 
  343.             return res; 
  344.         } 
  345.         return res; 
  346.     } 
  347.  
  348.     //后序遍歷查找 
  349.     public HeroNode postOrderSearch(int no) { 
  350.  
  351.         HeroNode res = null
  352.         if (this.left != null) { 
  353.             res = this.left.postOrderSearch(no); 
  354.         } 
  355.         if (res != null) { 
  356.             return res; 
  357.         } 
  358.  
  359.         if (this.right != null) { 
  360.             res = this.right.postOrderSearch(no); 
  361.         } 
  362.         if (res != null) { 
  363.             return res; 
  364.         } 
  365.         postCount++;//這里必須放在this.no == no 判斷之前,才進行實際的比較 
  366.         if (this.no == no) { 
  367.             return this; 
  368.         } 
  369.         return res; 
  370.     } 

 【編輯推薦】

 

責(zé)任編輯:姜華 來源: 今日頭條
相關(guān)推薦

2021-04-07 09:26:37

Java數(shù)據(jù)結(jié)構(gòu)算法

2021-05-12 09:07:09

Java數(shù)據(jù)結(jié)構(gòu)算法

2021-03-24 10:41:04

Java數(shù)據(jù)結(jié)構(gòu)算法

2021-04-13 09:37:41

Java數(shù)據(jù)結(jié)構(gòu)算法

2021-03-09 06:30:32

JAVA數(shù)據(jù)結(jié)構(gòu)算法

2021-03-26 08:40:28

Java數(shù)據(jù)結(jié)構(gòu)算法

2021-03-12 09:13:47

Java數(shù)據(jù)結(jié)構(gòu)算法

2021-03-23 08:33:22

Java數(shù)據(jù)結(jié)構(gòu)算法

2021-04-01 10:34:18

Java編程數(shù)據(jù)結(jié)構(gòu)算法

2021-03-10 08:42:19

Java數(shù)據(jù)結(jié)構(gòu)算法

2021-03-17 09:27:36

Java數(shù)據(jù)結(jié)構(gòu)算法

2021-03-08 06:28:57

JAVA數(shù)據(jù)結(jié)構(gòu)與算法稀疏數(shù)組

2021-04-16 09:40:52

Java數(shù)據(jù)結(jié)構(gòu)算法

2021-03-29 10:13:47

Java編程數(shù)據(jù)結(jié)構(gòu)算法

2021-03-19 10:25:12

Java數(shù)據(jù)結(jié)構(gòu)算法

2021-04-15 09:36:44

Java數(shù)據(jù)結(jié)構(gòu)算法

2021-04-22 10:07:45

Java數(shù)據(jù)結(jié)構(gòu)算法

2021-03-14 08:27:40

Java數(shù)據(jù)結(jié)構(gòu)算法

2021-04-23 09:12:09

Java數(shù)據(jù)結(jié)構(gòu)算法

2021-03-11 08:53:20

Java數(shù)據(jù)結(jié)構(gòu)算法
點贊
收藏

51CTO技術(shù)棧公眾號