在《大話數據結構》一中有這樣一段話“無論多高大的樹,那也是從小到大的,由根到葉,一點點成長起來的,俗話說十年樹木,百年樹人,可一棵大樹又何止十年這樣容易”。所以了解二叉樹的算法,必先了解樹的基本概念。
1.樹的基本概念
① 節點、根節點、父節點、子節點、兄弟節點
② 一棵樹可以沒有任何節點,成為空樹
③ 一棵樹可以只有1個節點,也就是只有根節點
④ 子樹、左子樹、右子樹
⑤ 節點的度
(degree):子樹的個數
⑥ 樹的度
:所有節點度中的最大值
⑦ 葉子節點(leaf): 度為0的節點
⑧ 非葉子節點:度不為0的節點
2.樹的深度
① 層數(level):根節點在第1層,根節點的子節點在第2層。
② 節點的深度(depth): 從根節點到當前節點的唯一路徑上的及節點總數。
③ 節點的高度(height):從當前節點到最遠葉子節點的路徑上的節點總數。
④ 樹的深度:所有節點深度中的最大值。
⑤ 樹的高度:左右節點高中中的最大值
⑥ 樹的深度等于樹的高度。
3.二叉樹(Binary Tree)
二叉樹的特點
1.每個節點的度最大為2(最多擁有2棵子樹)
2.左子樹和右子樹是有順序的
3.即使某節點只有一顆子樹,也要區分左右子樹。
二叉樹具有五種基本形態:
1.空二叉樹。
2.只有一個根節點
3.根節點只有左子樹
4.根節點只有右子樹
5.根節點既有左子樹又有右子樹。
所以,二叉樹是有序樹
3-1.二叉搜索(Binary Search Tree)
二叉搜索樹是二叉樹的一種,是應用非常廣泛的一種二叉樹,又被成為:兒茶查找樹,二叉排序樹。
二叉搜索樹的特點:
1.任意一個節點的值都大于其左子樹所有節點的值。
2.任意一個節點的值都小于其右子樹所有節點的值。
3.它的左右子樹也是一棵二叉搜索樹。
二叉搜索樹的作用:
二叉搜索書可以大大提高搜索數據的效率
二叉搜索存儲的元素必須具備可比較性
(1). 比如Int、double等
(2). 如果是自定義類型,需要制定比較方式
(3). 不允許為null
3-2.真二叉樹(Proper Binary Tree)
真二叉樹:所有節點的度要么為0,要么為2。
3-3. 滿二叉樹(Full Binary Tree)
滿二叉樹:最后一層節點的度都為0,其他節點的度都為2.
在同樣高度的二叉樹中,滿二叉樹的葉子節點數量最多,總結點數量最多。
滿二叉樹一定是真二叉樹,真二叉樹樹不一定是滿二叉樹。
3-4.完全叉樹(Complete Binary Tree)
對完全二叉樹:對節點從上至下、左至右開始編號,其所有編號都能與相同高度的滿二叉樹種的編號對應。
葉子節點指揮出現在最后2層,最后1層的葉子節點都靠左對齊。
完全二叉樹從根節點至倒數第2層是一顆滿二叉樹。
滿二叉樹一定是完全二叉樹,完全二叉樹不一定是滿二叉樹
4.二叉樹的遍歷
二叉樹的產檢遍歷有4中方法:
● 前序遍歷(Preorder Traversal)
● 中序遍歷(Inorder Traversal)
● 后序遍歷(Postorder Traversal)
● 層序遍歷(Level Order Traversal)
4-1.前序遍歷(Preorder Traversal)
訪問順序
根節點
、前序遍歷左子樹
、前序遍歷右子樹
7, 4 ,2 , 1, 3 , 5 , 9, 8 , 11 , 10 ,12
前序遍歷.png
前序遍歷核心代碼:(遞歸思想)
/**
* 前序遍歷
*/
public void preorderTraversal() {
preorderTraversal(root);
}
private void preorderTraversal(Node<E> node) {
if (node == null) return;
System.out.println(node.element);
preorderTraversal(node.left);
preorderTraversal(node.right);
}
4-2 中序遍歷(Inorder Traversal)
訪問順序
中序遍歷左子樹
、根節點
,中序遍歷右子樹
1, 2 ,3 , 4, 5 , 7 , 8, 9 , 10 , 11 ,12
中序遍歷.png
中序遍歷核心代碼:(遞歸思想)
/**
* 中序遍歷
*/
public void inorderTraversal() {
inorderTraversal(root);
}
private void inorderTraversal(Node<E> node) {
if (node == null) return;
inorderTraversal(node.left);
System.out.println(node.element);
inorderTraversal(node.right);
}
4-3 后序遍歷(Postorder Traversal)
訪問順序
后序遍歷左子樹
、后序遍歷右子樹
、根節點
1, 3 ,2 , 5, 4 , 8 , 10 , 12 ,11, 9 , 7
后序遍歷.png
后序遍歷核心代碼:(遞歸思想)
/**
* 后序遍歷
*/
public void postorderTraversal() {
postorderTraversal(root);
}
private void postorderTraversal(Node<E> node) {
if (node == null) return;
postorderTraversal(node.left);
postorderTraversal(node.right);
System.out.println(node.element);
}
4-4 層序遍歷(Level Order Traversal)
訪問順序
從上到下
,從左到右
依次訪問每一個節點
7, 4 ,9 , 2, 5 , 8, 11 , 1 , 3 ,10 , 12
層序遍歷.png
層序遍歷核心代碼:(隊列思想)
? 實現思路
- 將根節點入隊
- 循環執行以下操作,直到隊列為空
?將隊頭節點 A 出隊,進行訪問
?將 A 的左子節點入隊
?將 A 的右子節點入隊
/**
* 層序遍歷
*/
public void levelOrderTraversal() {
if (root == null) return;
// 創建隊列
Queue<Node<E>> queue = new LinkedList<>();
// 將根節點入隊
queue.offer(root);
while (!queue.isEmpty()) {
// 頭節點出隊
Node<E> node = queue.poll();
if (node.left != null) {
//左節點入隊
queue.offer(node.left);
}
if (node.right != null) {
//右節點入隊
queue.offer(node.right);
}
}
}
以上是關于二叉樹基本概念的學習,記錄一下,方便自己日后查閱。
其它相關:
二叉搜索樹(Binary Search Tree).
AVL樹(艾薇兒樹).