對於大量的輸入數據,鏈表的線性訪問時間太慢,不宜使用。樹是一種在實際編程中常常遇到的數據結構,其大部分操做的運行時間平均爲O(logN)。樹的邏輯結構十分簡單: 除了根節點以外每一個節點只有一個父節點,根節點沒有父節點:除了葉節點以外全部節點都有一個或多個子節點,父節點和子節點之間用指針連接。ios
面試時提到的樹大部分都是二叉樹。所謂二叉樹是書的一種特殊結構。在二叉樹中最重要的結構莫過於遍歷,即按照某一順序訪問樹中的全部節點,經常使用的遍歷方式主要有三種:前序,中序,後序。這三種遍歷都有遞歸和循環兩種不一樣的實現方法,每一種遍歷的遞歸實現都比循環實現要簡潔不少。面試
對於一顆普通的樹,因爲每一個節點的孩子個數能夠變化很大而且實現不知道,所以在數據結構中創建到各孩子節點直接的鏈接時不可行的,由於這樣會產生太多的浪費空間。(解決方案:將每一個節點的全部兒子都放在樹節點的鏈表中。以下)算法
typedef struct TNode { ElemType data; struct TNode *firstChild; struct TNode *NextChild; }TreeNode, *BinaryTree;
二叉樹:二叉樹的一個性質是平均二叉樹的深度要比N小得多。分析代表,這個平均深度爲O(N^0.5),而對於特殊類型的二叉樹,即二叉查找樹,其平均深度爲O(logN)。固然,在最壞的狀況下它的深度能夠達到N-1. 編程
二叉樹的主要用處之一是在編譯器的設計領域。例如:表達式樹:表達式樹的葉子是操做數,而其餘的節點是操做符,例如:數據結構
如今給出一種算法來把後綴表達式轉變成表達式樹。spa
輸入:a b + c d e + * *設計
思路:前兩個符號是操做數,所以建立兩棵單節點數並將指向它們的指針壓入棧中,每當讀入一個操做符時,將棧頂的兩個樹的指針出棧,造成一個新的樹,並將這棵新的樹的根節點指針入棧。直至結束。指針
//表達式樹 #include<iostream> #include<stack> using namespace std; typedef char ElemType; typedef struct TNode { ElemType data; struct TNode *Lchild; struct TNode *Rchild; }TreeNode, *BinaryTree; TNode* ExpressionTree(char str[]) { stack<TNode*> s; //建立一個棧指向二叉樹的節點 TNode *TreeNode; int i = 0; while(str[i] != '#') { if(str[i] >= 'a' && str[i] <= 'z') { TNode* childNode = new TNode(); childNode->data = str[i]; s.push(childNode); } else { TNode* treeNode = new TNode(); treeNode->data = str[i]; if(!s.empty()) { treeNode->Rchild = s.top(); s.pop(); } else return treeNode; if(!s.empty()) { treeNode->Lchild = s.top(); s.pop(); } else return treeNode; s.push(treeNode); } i++; } if(s.empty()) return NULL; else { TreeNode = s.top(); return TreeNode; } } void PostOrder(BinaryTree T) //後序遍歷二叉樹 { if(T == NULL) return; if(T->Lchild != NULL) { PostOrder(T->Lchild); } if(T->Rchild != NULL) { PostOrder(T->Rchild); } cout << T->data << " "; } void InOrder(BinaryTree T) //中序遍歷二叉樹 { if(T == NULL) return; if(T->Lchild != NULL) InOrder(T->Lchild); cout << T->data << " "; if(T->Rchild != NULL) InOrder(T->Rchild); } int main() { char ch[] = "ab+cde+**#"; TNode *T; T = ExpressionTree(ch); PostOrder(T); cout << endl; InOrder(T); system("pause"); return 0; }