1. 程式人生 > >資料結構與演算法---樹結構(Tree structure)

資料結構與演算法---樹結構(Tree structure)

為什麼需要樹這種資料結構

陣列儲存方式的分析

  • 優點:通過下標方式訪問元素,速度快。對於有序陣列,還可使用二分查詢提高檢索速度。
  • 缺點:如果要檢索具體某個值,或者插入值(按一定順序)會整體移動,效率較低。

鏈式儲存方式的分析

  • 優點:在一定程度上對陣列儲存方式有優化(比如:插入一個數值節點,只需要將插入節點,連結到連結串列中即可, 刪除效率也很好)。
  • 缺點:在進行檢索時,效率仍然較低,比如(檢索某個值,需要從頭節點開始遍歷) 

樹儲存方式的分析

 能提高資料儲存,讀取的效率,  比如利用 二叉排序樹(Binary Sort Tree),既可以保證資料的檢索速度,同時也可以保證資料的插入,刪除,修改的速度。

 

樹結構示意圖

 

二叉樹的概念

  1. 樹有很多種,每個節點最多隻能有兩個子節點的一種形式稱為二叉樹。
  2. 二叉樹的子節點分為左節點和右節點。 
  3. 如果該二叉樹的所有葉子節點都在最後一層,並且結點總數= 2^n -1 , n 為層數,則我們稱為滿二叉樹。
  4. 如果該二叉樹的所有葉子節點都在最後一層或者倒數第二層,而且最後一層的葉子節點在左邊連續,倒數第二層的葉子節點在右邊連續,我們稱為完全二叉樹。

 

二叉樹遍歷的說明

前序遍歷: 先輸出父節點,再遍歷左子樹和右子樹

中序遍歷: 先遍歷左子樹,再輸出父節點,再遍歷右子樹

後序遍歷: 先遍歷左子樹,再遍歷右子樹,最後輸出父節點

小結: 看輸出父節點的順序,就確定是前序,中序還是後序

 示例:

將下列二叉樹 前序、中序、後序輸出

  1 package com.tree;
  2 
  3 /**
  4  * Created by wanbf on 2019/7/9.
  5  */
  6 
  7 public class BinaryTreeDemo {
  8 
  9     public static void main(String[] args) {
 10         //先需要建立一顆二叉樹
 11         BinaryTree binaryTree = new BinaryTree();
 12         //建立需要的結點
 13         HeroNode root = new HeroNode(1, "宋江");
 14         HeroNode node2 = new HeroNode(2, "吳用");
 15         HeroNode node3 = new HeroNode(3, "盧俊義");
 16         HeroNode node4 = new HeroNode(4, "林沖");
 17         //HeroNode node5 = new HeroNode(5, "關勝");
 18 
 19         //說明,我們先手動建立該二叉樹,後面我們學習遞迴的方式建立二叉樹
 20         root.setLeft(node2);
 21         root.setRight(node3);
 22         node3.setRight(node4);
 23         //node3.setLeft(node5);
 24         binaryTree.setRoot(root);
 25 
 26         //測試
 27         System.out.println("前序遍歷"); // 1,2,3,4
 28         binaryTree.preOrder();
 29 
 30         //測試
 31         System.out.println("中序遍歷");
 32         binaryTree.infixOrder(); // 2,1,3,4
 33 
 34         System.out.println("後序遍歷");
 35         binaryTree.postOrder(); // 2,4,3,1
 36 
 37     }
 38 
 39 }
 40 
 41 
 42 
 43 
 44 //定義BinaryTree 二叉樹
 45 class BinaryTree {
 46     private HeroNode root;
 47 
 48     public void setRoot(HeroNode root) {
 49         this.root = root;
 50     }
 51     //前序遍歷
 52     public void preOrder() {
 53         if(this.root != null) {
 54             this.root.preOrder();
 55         }else {
 56             System.out.println("二叉樹為空,無法遍歷");
 57         }
 58     }
 59 
 60     //中序遍歷
 61     public void infixOrder() {
 62         if(this.root != null) {
 63             this.root.infixOrder();
 64         }else {
 65             System.out.println("二叉樹為空,無法遍歷");
 66         }
 67     }
 68     //後序遍歷
 69     public void postOrder() {
 70         if(this.root != null) {
 71             this.root.postOrder();
 72         }else {
 73             System.out.println("二叉樹為空,無法遍歷");
 74         }
 75     }
 76 }
 77 
 78 
 79 //先建立HeroNode 結點
 80 class HeroNode {
 81     private int no;
 82     private String name;
 83     private HeroNode left; //預設null
 84     private HeroNode right; //預設null
 85     public HeroNode(int no, String name) {
 86         this.no = no;
 87         this.name = name;
 88     }
 89     public int getNo() {
 90         return no;
 91     }
 92     public void setNo(int no) {
 93         this.no = no;
 94     }
 95     public String getName() {
 96         return name;
 97     }
 98     public void setName(String name) {
 99         this.name = name;
100     }
101     public HeroNode getLeft() {
102         return left;
103     }
104     public void setLeft(HeroNode left) {
105         this.left = left;
106     }
107     public HeroNode getRight() {
108         return right;
109     }
110     public void setRight(HeroNode right) {
111         this.right = right;
112     }
113     @Override
114     public String toString() {
115         return "HeroNode [no=" + no + ", name=" + name + "]";
116     }
117 
118     //編寫前序遍歷的方法
119     public void preOrder() {
120         System.out.println(this); //先輸出父結點
121         //遞歸向左子樹前序遍歷
122         if(this.left != null) {
123             this.left.preOrder();
124         }
125         //遞歸向右子樹前序遍歷
126         if(this.right != null) {
127             this.right.preOrder();
128         }
129     }
130     //中序遍歷
131     public void infixOrder() {
132 
133         //遞歸向左子樹中序遍歷
134         if(this.left != null) {
135             this.left.infixOrder();
136         }
137         //輸出父結點
138         System.out.println(this);
139         //遞歸向右子樹中序遍歷
140         if(this.right != null) {
141             this.right.infixOrder();
142         }
143     }
144     //後序遍歷
145     public void postOrder() {
146         if(this.left != null) {
147             this.left.postOrder();
148         }
149         if(this.right != null) {
150             this.right.postOrder();
151         }
152         System.out.println(this);
153     }
154 }
程式碼
 1 前序遍歷
 2 HeroNode [no=1, name=宋江]
 3 HeroNode [no=2, name=吳用]
 4 HeroNode [no=3, name=盧俊義]
 5 HeroNode [no=4, name=林沖]
 6 中序遍歷
 7 HeroNode [no=2, name=吳用]
 8 HeroNode [no=1, name=宋江]
 9 HeroNode [no=3, name=盧俊義]
10 HeroNode [no=4, name=林沖]
11 後序遍歷
12 HeroNode [no=2, name=吳用]
13 HeroNode [no=4, name=林沖]
14 HeroNode [no=3, name=盧俊義]
15 HeroNode [no=1, name=宋江]
輸出

前上圖的 3號節點 "盧俊" , 增加一個左子節點 [5, 關勝]

使用前序,中序,後序遍歷,請寫出各自輸出的順序是什麼?

 

 1 public static void main(String[] args) {
 2         //先需要建立一顆二叉樹
 3         BinaryTree binaryTree = new BinaryTree();
 4         //建立需要的結點
 5         HeroNode root = new HeroNode(1, "宋江");
 6         HeroNode node2 = new HeroNode(2, "吳用");
 7         HeroNode node3 = new HeroNode(3, "盧俊義");
 8         HeroNode node4 = new HeroNode(4, "林沖");
 9         HeroNode node5 = new HeroNode(5, "關勝");
10 
11         //說明,我們先手動建立該二叉樹,後面我們學習遞迴的方式建立二叉樹
12         root.setLeft(node2);
13         root.setRight(node3);
14         node3.setRight(node4);
15         node3.setLeft(node5);
16         binaryTree.setRoot(root);
17 
18         //測試
19         System.out.println("前序遍歷"); // 1,2,3,5,4
20         binaryTree.preOrder();
21 
22         //測試
23         System.out.println("中序遍歷");
24         binaryTree.infixOrder(); // 2,1,5,3,4
25 
26         System.out.println("後序遍歷");
27         binaryTree.postOrder(); // 2,5,4,3,1
28 
29     }
程式碼
 1 前序遍歷
 2 HeroNode [no=1, name=宋江]
 3 HeroNode [no=2, name=吳用]
 4 HeroNode [no=3, name=盧俊義]
 5 HeroNode [no=5, name=關勝]
 6 HeroNode [no=4, name=林沖]
 7 中序遍歷
 8 HeroNode [no=2, name=吳用]
 9 HeroNode [no=1, name=宋江]
10 HeroNode [no=5, name=關勝]
11 HeroNode [no=3, name=盧俊義]
12 HeroNode [no=4, name=林沖]
13 後序遍歷
14 HeroNode [no=2, name=吳用]
15 HeroNode [no=5, name=關勝]
16 HeroNode [no=4, name=林沖]
17 HeroNode [no=3, name=盧俊義]
18 HeroNode [no=1, name=宋江]
輸出

 二叉樹-查詢指定節點

1.編寫前序查詢,中序查詢和後序查詢的方法。

2.並分別使用三種查詢方式,查詢 heroNO = 5 的節點

3.並分析各種查詢方式,分別比較了多少次

思路分析

 

  1 /**
  2  * Created by wanbf on 2019/7/9.
  3  */
  4 public class BinaryTreeDemo {
  5 
  6     public static void main(String[] args) {
  7         //先需要建立一顆二叉樹
  8         BinaryTree binaryTree = new BinaryTree();
  9         //建立需要的結點
 10         HeroNode root = new HeroNode(1, "宋江");
 11         HeroNode node2 = new HeroNode(2, "吳用");
 12         HeroNode node3 = new HeroNode(3, "盧俊義");
 13         HeroNode node4 = new HeroNode(4, "林沖");
 14         HeroNode node5 = new HeroNode(5, "關勝");
 15 
 16         //說明,我們先手動建立該二叉樹,後面我們學習遞迴的方式建立二叉樹
 17         root.setLeft(node2);
 18         root.setRight(node3);
 19         node3.setRight(node4);
 20         node3.setLeft(node5);
 21         binaryTree.setRoot(root);
 22 
 23         //前序遍歷
 24         //前序遍歷的次數 :4
 25         System.out.println("前序遍歷方式~~~");
 26         HeroNode resNode = binaryTree.preOrderSearch(5);
 27         if (resNode != null) {
 28             System.out.printf("找到了,資訊為 no=%d name=%s", resNode.getNo(), resNode.getName());
 29         } else {
 30             System.out.printf("沒有找到 no = %d 的英雄", 5);
 31         }
 32 
 33         //中序遍歷查詢
 34         //中序遍歷3次
 35         System.out.println("中序遍歷方式~~~");
 36         HeroNode resNode = binaryTree.infixOrderSearch(5);
 37         if (resNode != null) {
 38             System.out.printf("找到了,資訊為 no=%d name=%s", resNode.getNo(), resNode.getName());
 39         } else {
 40             System.out.printf("沒有找到 no = %d 的英雄", 5);
 41         }
 42 
 43         //後序遍歷查詢
 44         //後序遍歷查詢的次數  2次
 45         System.out.println("後序遍歷方式~~~");
 46         HeroNode resNode = binaryTree.postOrderSearch(5);
 47         if (resNode != null) {
 48             System.out.printf("找到了,資訊為 no=%d name=%s", resNode.getNo(), resNode.getName());
 49         } else {
 50             System.out.printf("沒有找到 no = %d 的英雄", 5);
 51         }
 52     }
 53 
 54 }
 55 
 56 //定義BinaryTree 二叉樹
 57 class BinaryTree {
 58     private HeroNode root;
 59 
 60     public void setRoot(HeroNode root) {
 61         this.root = root;
 62     }
 63     //前序遍歷查詢
 64     public HeroNode preOrderSearch(int no) {
 65         if(root != null) {
 66             return root.preOrderSearch(no);
 67         } else {
 68             return null;
 69         }
 70     }
 71     //中序遍歷查詢
 72     public HeroNode infixOrderSearch(int no) {
 73         if(root != null) {
 74             return root.infixOrderSearch(no);
 75         }else {
 76             return null;
 77         }
 78     }
 79     //後序遍歷查詢
 80     public HeroNode postOrderSearch(int no) {
 81         if(root != null) {
 82             return this.root.postOrderSearch(no);
 83         }else {
 84             return null;
 85         }
 86     }
 87 }
 88 
 89 //先建立HeroNode 結點
 90 class HeroNode {
 91     private int no;
 92     private String name;
 93     private HeroNode left; //預設null
 94     private HeroNode right; //預設null
 95     public HeroNode(int no, String name) {
 96         this.no = no;
 97         this.name = name;
 98     }
 99     public int getNo() {
100         return no;
101     }
102     public void setNo(int no) {
103         this.no = no;
104     }
105     public String getName() {
106         return name;
107     }
108     public void setName(String name) {
109         this.name = name;
110     }
111     public HeroNode getLeft() {
112         return left;
113     }
114     public void setLeft(HeroNode left) {
115         this.left = left;
116     }
117     public HeroNode getRight() {
118         return right;
119     }
120     public void setRight(HeroNode right) {
121         this.right = right;
122     }
123     @Override
124     public String toString() {
125         return "HeroNode [no=" + no + ", name=" + name + "]";
126     }
127     //前序遍歷查詢
128     /**
129      *
130      * @param no 查詢no
131      * @return 如果找到就返回該Node ,如果沒有找到返回 null
132      */
133     public HeroNode preOrderSearch(int no) {
134         System.out.println("進入前序遍歷");
135         //比較當前結點是不是
136         if(this.no == no) {
137             return this;
138         }
139         //1.則判斷當前結點的左子節點是否為空,如果不為空,則遞迴前序查詢
140         //2.如果左遞迴前序查詢,找到結點,則返回
141         HeroNode resNode = null;
142         if(this.left != null) {
143             resNode = this.left.preOrderSearch(no);
144         }
145         if(resNode != null) {//說明我們左子樹找到
146             return resNode;
147         }
148         //1.左遞迴前序查詢,找到結點,則返回,否繼續判斷,
149         //2.當前的結點的右子節點是否為空,如果不空,則繼續向右遞迴前序查詢
150         if(this.right != null) {
151             resNode = this.right.preOrderSearch(no);
152         }
153         return resNode;
154     }
155 
156     //中序遍歷查詢
157     public HeroNode infixOrderSearch(int no) {
158         //判斷當前結點的左子節點是否為空,如果不為空,則遞迴中序查詢
159         HeroNode resNode = null;
160         if(this.left != null) {
161             resNode = this.left.infixOrderSearch(no);
162         }
163         if(resNode != null) {
164             return resNode;
165         }
166         System.out.println("進入中序查詢");
167         //如果找到,則返回,如果沒有找到,就和當前結點比較,如果是則返回當前結點
168         if(this.no == no) {
169             return this;
170         }
171         //否則繼續進行右遞迴的中序查詢
172         if(this.right != null) {
173             resNode = this.right.infixOrderSearch(no);
174         }
175         return resNode;
176 
177     }
178 
179     //後序遍歷查詢
180     public HeroNode postOrderSearch(int no) {
181 
182         //判斷當前結點的左子節點是否為空,如果不為空,則遞迴後序查詢
183         HeroNode resNode = null;
184         if(this.left != null) {
185             resNode = this.left.postOrderSearch(no);
186         }
187         if(resNode != null) {//說明在左子樹找到
188             return resNode;
189         }
190 
191         //如果左子樹沒有找到,則向右子樹遞迴進行後序遍歷查詢
192         if(this.right != null) {
193             resNode = this.right.postOrderSearch(no);
194         }
195         if(resNode != null) {
196             return resNode;
197         }
198         System.out.println("進入後序查詢");
199         //如果左右子樹都沒有找到,就比較當前結點是不是
200         if(this.no == no) {
201             return this;
202         }
203         return resNode;
204     }
205 
206 }
程式碼
 1 前序遍歷方式~~~
 2 進入前序遍歷
 3 進入前序遍歷
 4 進入前序遍歷
 5 進入前序遍歷
 6 找到了,資訊為 no=5 name=關勝中序遍歷方式~~~
 7 進入中序查詢
 8 進入中序查詢
 9 進入中序查詢
10 找到了,資訊為 no=5 name=關勝後序遍歷方式~~~
11 進入後序查詢
12 進入後序查詢
13 找到了,資訊為 no=5 name=關勝
輸出

 二叉樹-刪除節點

定義:

  1. 如果刪除的節點是葉子節點,則刪除該節點
  2. 如果刪除的節點是非葉子節點,則刪除該子樹.

思路分析:

實現刪除程式碼:

 1 //定義BinaryTree 二叉樹
 2 class BinaryTree {
 3     private HeroNode root;
 4 
 5     public void setRoot(HeroNode root) {
 6         this.root = root;
 7     }
 8     
 9     //刪除結點
10     public void delNode(int no) {
11         if(root != null) {
12             //如果只有一個root結點, 這裡立即判斷root是不是就是要刪除結點
13             if(root.getNo() == no) {
14                 root = null;
15             } else {
16                 //遞迴刪除
17                 root.delNode(no);
18             }
19         }else{
20             System.out.println("空樹,不能刪除~");
21         }
22     }
23 }
24 class HeroNode {
25         private int no;
26     private String name;
27     private HeroNode left; //預設null
28     private HeroNode right; //預設null
29     public HeroNode(int no, String name) {
30         this.no = no;
31         this.name = name;
32     }
33     public int getNo() {
34         return no;
35     }
36     public void setNo(int no) {
37         this.no = no;
38     }
39     public String getName() {
40         return name;
41     }
42     public void setName(String name) {
43         this.name = name;
44     }
45     public HeroNode getLeft() {
46         return left;
47     }
48     public void setLeft(HeroNode left) {
49         this.left = left;
50     }
51     public HeroNode getRight() {
52         return right;
53     }
54     public void setRight(HeroNode right) {
55         this.right = right;
56     }
57     @Override
58     public String toString() {
59         return "HeroNode [no=" + no + ", name=" + name + "]";
60     }
61         //遞迴刪除結點
62     //1.如果刪除的節點是葉子節點,則刪除該節點
63     //2.如果刪除的節點是非葉子節點,則刪除該子樹
64     public void delNode(int no) {
65         
66         //思路
67         /*
68          *     1. 因為我們的二叉樹是單向的,所以我們是判斷當前結點的子結點是否需要刪除結點,而不能去判斷當前這個結點是不是需要刪除結點.
69             2. 如果當前結點的左子結點不為空,並且左子結點 就是要刪除結點,就將this.left = null; 並且就返回(結束遞迴刪除)
70             3. 如果當前結點的右子結點不為空,並且右子結點 就是要刪除結點,就將this.right= null ;並且就返回(結束遞迴刪除)
71             4. 如果第2和第3步沒有刪除結點,那麼我們就需要向左子樹進行遞迴刪除
72             5.  如果第4步也沒有刪除結點,則應當向右子樹進行遞迴刪除.
73 
74          */
75         //2. 如果當前結點的左子結點不為空,並且左子結點 就是要刪除結點,就將this.left = null; 並且就返回(結束遞迴刪除)
76         if(this.left != null && this.left.no == no) {
77             this.left = null;
78             return;
79         }
80         //3.如果當前結點的右子結點不為空,並且右子結點 就是要刪除結點,就將this.right= null ;並且就返回(結束遞迴刪除)
81         if(this.right != null && this.right.no == no) {
82             this.right = null;
83             return;
84         }
85         //4.我們就需要向左子樹進行遞迴刪除
86         if(this.left != null) {
87             this.left.delNode(no);
88         }
89         //5.則應當向右子樹進行遞迴刪除
90         if(this.right != null) {
91             this.right.delNode(no);
92         }
93     }
94 }    
程式碼

測試:

 1 public static void main(String[] args) {
 2         //先需要建立一顆二叉樹
 3         BinaryTree binaryTree = new BinaryTree();
 4         //建立需要的結點
 5         HeroNode root = new HeroNode(1, "宋江");
 6         HeroNode node2 = new HeroNode(2, "吳用");
 7         HeroNode node3 = new HeroNode(3, "盧俊義");
 8         HeroNode node4 = new HeroNode(4, "林沖");
 9         HeroNode node5 = new HeroNode(5, "關勝");
10 
11         //說明,我們先手動建立該二叉樹,後面我們學習遞迴的方式建立二叉樹
12         root.setLeft(node2);
13         root.setRight(node3);
14         node3.setRight(node4);
15         node3.setLeft(node5);
16         binaryTree.setRoot(root);
17         System.out.println("刪除前,前序遍歷");
18         binaryTree.preOrder(); //  1,2,3,5,4
19         binaryTree.delNode(5);
20         //binaryTree.delNode(3);
21         System.out.println("刪除後,前序遍歷");
22         binaryTree.preOrder(); // 1,2,3,4    
23 }
24 輸出:
25 刪除前,前序遍歷
26 HeroNode [no=1, name=宋江]
27 HeroNode [no=2, name=吳用]
28 HeroNode [no=3, name=盧俊義]
29 HeroNode [no=5, name=關勝]
30 HeroNode [no=4, name=林沖]
31 刪除後,前序遍歷
32 HeroNode [no=1, name=宋江]
33 HeroNode [no=2, name=吳用]
34 HeroNode [no=3, name=盧俊義]
35 HeroNode [no=4, name=林沖]
36 如果是刪除binaryTree.delNode(3);
37 則輸出:
38 刪除前,前序遍歷
39 HeroNode [no=1, name=宋江]
40 HeroNode [no=2, name=吳用]
41 HeroNode [no=3, name=盧俊義]
42 HeroNode [no=5, name=關勝]
43 HeroNode [no=4, name=林沖]
44 刪除後,前序遍歷
45 HeroNode [no=1, name=宋江]
46 HeroNode [no=2, name=吳用]
程式碼

 拓展:

上面我們定義了兩個刪除規則,那麼我們考慮另外刪除規則又怎麼實現。‘

如果要刪除的節點是非葉子節點,現在我們不希望將該非葉子節點為根節點的子樹刪除,需要指定規則, 假如規定如下:

  1. 如果該非葉子節點A只有一個子節點B,則子節點B替代節點A
  2. 如果該非葉子節點A有左子節點B和右子節點C,則讓左子節點B替代節點A。

 這個程式碼實現在後續講二叉排序樹時,在講解具體的刪除方法。

順序儲存二叉樹

順序儲存二叉樹的概念

基本說明

從資料儲存來看,陣列儲存方式和樹 的儲存方式可以相互轉換,即陣列可 以轉換成樹,樹也可以轉換成陣列, 看示意圖。

要求:

  1. 上圖的二叉樹的結點,要求以陣列 的方式來存放 arr : [1, 2, 3, 4, 5, 6, 7]
  2. 要求在遍歷陣列 arr時,仍然可以以 前序遍歷,中序遍歷和後序遍歷的 方式完成結點的遍歷

順序儲存二叉樹的特點:

  1. 順序二叉樹通常只考慮完全二叉樹
  2. 第n個元素的左子節點為  2 * n + 1
  3. 第n個元素的右子節點為  2 * n + 2
  4. 第n個元素的父節點為  (n-1) / 2
  5.  n : 表示二叉樹中的第幾個元素

需求: 給你一個數組 {1,2,3,4,5,6,7},要求以二叉樹前序遍歷的方式進行遍歷。 前序遍歷的結果應當為 1,2,4,5,3,6,7

 1 public class ArrBinaryTreeDemo {
 2 
 3     public static void main(String[] args) {
 4         int[] arr = { 1, 2, 3, 4, 5, 6, 7 };
 5         //建立一個 ArrBinaryTree
 6         ArrBinaryTree arrBinaryTree = new ArrBinaryTree(arr);
 7         arrBinaryTree.preOrder(); // 1,2,4,5,3,6,7
 8     }
 9 
10 }
11 
12 //編寫一個ArrayBinaryTree, 實現順序儲存二叉樹遍歷
13 
14 class ArrBinaryTree {
15     private int[] arr;//儲存資料結點的陣列
16 
17     public ArrBinaryTree(int[] arr) {
18         this.arr = arr;
19     }
20 
21     //過載preOrder
22     public void preOrder() {
23         this.preOrder(0);
24     }
25 
26     //編寫一個方法,完成順序儲存二叉樹的前序遍歷
27     /**
28      *
29      * @param index 陣列的下標
30      */
31     public void preOrder(int index) {
32         //如果陣列為空,或者 arr.length = 0
33         if(arr == null || arr.length == 0) {
34             System.out.println("陣列為空,不能按照二叉樹的前序遍歷");
35         }
36         //輸出當前這個元素
37         System.out.println(arr[index]);
38         //向左遞迴遍歷
39         if((index * 2 + 1) < arr.length) {
40             preOrder(2 * index + 1 );
41         }
42         //向右遞迴遍歷
43         if((index * 2 + 2) < arr.length) {
44             preOrder(2 * index + 2);
45         }
46     }
47 
48 }
程式碼

順序儲存二叉樹應用例項

八大排序演算法中的堆排序,就會使用到順序儲存二叉樹, 關於堆排序後續在講。

&n