二叉樹(binary tree)是n(n>=0)個節點的有限集合,該集合或者爲空集,或者由一個根結點和兩棵互不相交的、分別稱爲根結點的左子樹(left subtree)和右子樹(right subtree)的二叉樹組成。
二叉樹有着如下特色:
node
全部結點都只有左子樹的二叉樹稱爲左斜樹;全部結點都只有右子樹的二叉樹稱爲右斜樹。左斜樹和右斜樹統稱爲斜樹。linux
在二叉樹中,若是全部分支結點都存在左子樹和右子樹,而且全部葉子都在同一層上,這樣的二叉樹稱爲滿二叉樹。滿二叉樹有如下特色:
1)葉子只能出如今最下一層;
2)只有度爲0和2的節點;
3)在一樣深度的二叉樹中,滿二叉樹的結點個數最多,葉子數最多。 nginx
對一棵具備n個節點的二叉樹按層序編號,若是編號爲i(1<=i<=n)的結點與一樣深度的滿二叉樹中編號爲i的結點在二叉樹中的位置徹底相同,這棵二叉樹一定是一棵徹底二叉樹。徹底二叉樹的特色:
1)葉子結點只能出如今最下兩層,且最下層的葉子結點都集中在二叉樹左側連續的位置;
2)若是有度爲1的結點,只可能有一個,且該結點只有左孩子。算法
注意:滿二叉樹必定是徹底二叉樹,但反過來不必定成立。數據庫
平衡二叉樹又被稱爲AVL樹(有別於AVL算法),且具備如下性質:它是一 棵空樹或它的左右兩個子樹的高度差的絕對值不超過1,而且左右兩個子樹都是一棵平衡二叉樹。
AVL樹應用於windows對進程地址空間的管理。windows
紅黑樹是一種自平衡二叉查找樹,經過對任何一條從根到葉子的簡單路徑上各個節點的顏色進行約束,確保沒有一條路徑會比其餘路徑長2倍,於是是近似平衡的。因此相對於嚴格要求平衡的AVL樹來講,它的旋轉保持平衡次數較少。用於搜索時,插入刪除次數多的狀況下咱們就用紅黑樹來取代AVL。
紅黑樹的應用比較普遍,好比:
1)C++的STL中,map和set都是用紅黑樹實現的;
2)linux進程調度Completely Fair Scheduler,用紅黑樹管理進程控制塊;
3)nginx中,用紅黑樹管理timer等。bash
B樹是一種平衡的多叉樹,又稱是多路查找樹。通常用於數據庫中作索引,由於它們分支多層數少,由於磁盤IO是很是耗時的,而像大量數據存儲在磁盤中因此咱們要有效的減小磁盤IO次數避免磁盤頻繁的查找。
B+樹是B樹的變種樹,有n棵子樹的節點中含有n個關鍵字,每一個關鍵字不保存數據,只用來索引,數據都保存在葉子節點。數據結構
字典樹(Trie樹),又稱爲單詞查找樹,是一種樹形結構,經常使用來操做字符串。字典樹有這樣幾個基本性質:
1)根結點不包含字符,除根結點外的每個子結點都包含一個字符;
2)從根結點到某一個結點,路徑上通過的字符鏈接起來,就是該結點對應的字符串;
3)每一個結點的全部子結點包含的字符都不相同。 post
咱們先採用廣義表,建立一個棵二叉樹:學習
function BinaryTree(){
var root = null; //根節點
// 採用廣義表表示的創建二叉樹方法
this.init_tree = function(string){
var stack = new Stack.Stack();
var k = 0;
var new_node = null;
for(var i =0; i < string.length;i++){
var item = string[i];
if(item=="("){
stack.push(new_node);
k = 1;
}else if(item==")"){
stack.pop();
}else if(item==","){
k = 2;
}else{
new_node = BinTreeNode(item);
if(root==null){
root = new_node;
}else if(k==1){
// 左子樹
var top_item = stack.top();
top_item.leftChild = new_node;
new_node.parentNode = top_item;
}else{
// 右子樹
var top_item = stack.top();
top_item.rightChild = new_n
ode;
new_node.parentNode = top_item;
}
}
}
}
};
複製代碼
遍歷是二叉樹中最基本的操做。二叉樹的遍歷是從根結點出發,按照某種次序訪問二叉樹中的全部結點,使得每一個結點被訪問一次且僅被訪問一次。
前序遍歷操做定義爲:
若二叉樹爲空,則空操做返回;不然
1)訪問根結點;
2)前序遍歷根結點的左子樹;
3)前序遍歷根結點的右子樹。
// 前序遍歷
this.pre_order = function(node){
if(node==null){
return;
}
console.log(node.data);
this.pre_order(node.leftChild);
this.pre_order(node.rightChild);
};
複製代碼
對於上圖3-1所示的二叉樹,按前序遍歷獲得的結點序列爲:ABDHIEJCFG。
中序遍歷操做定義爲:
若二叉樹爲空,則空操做返回;不然
1)中序遍歷根結點的左子樹;
2)訪問根結點;
3)中序遍歷根結點的右子樹。
// 中序遍歷
this.in_order = function(node){
if(node==null){
return;
}
this.in_order(node.leftChild);
console.log(node.data);
this.in_order(node.rightChild);
};
複製代碼
對於上圖3-1所示的二叉樹,按中序遍歷獲得的結點序列爲:HDIBJEAFCG。
後序遍歷操做定義爲:
若二叉樹爲空,則空操做返回;不然
1)後序遍歷根結點的左子樹;
2)後序遍歷根結點的右子樹;
3)訪問根結點。
// 後序遍歷
this.post_order = function(node){
if(node==null){
return;
}
this.post_order(node.leftChild);
this.post_order(node.rightChild);
console.log(node.data);
};
複製代碼
對於上圖3-1所示的二叉樹,按後序遍歷獲得的結點序列爲:HIDJEBFGCA。
層序遍歷,是指從二叉樹的第一層(根結點)開始,從上至下逐層遍歷,在同一層中,按從左到右的順序對結點逐個訪問。
對於上圖3-1所示的二叉樹,按層序遍歷獲得的結點序列爲:ABCDEFGHIJ。
以上是我對幾種基本二叉樹作了初步的介紹,但願之後你們看到某個二叉樹名詞,腦海就能快速創建起二叉樹模型,同時也爲深刻學習數據結構打下基礎~~