一、前序遍歷
前序遍歷簡單來講,遍歷順序是:根節點-左子樹-右子樹
1、遞歸遍歷
1 void preorder(BinTree *T) 2 { 3 if(T==NULL) 4 return; 5 cout << T->data; 6 preorder(T->left); 7 preorder(T->right); 8 }
2、迭代遍歷(用棧實現)
1 void preorder2(BinTree *T) 2 { 3 //空樹,直接返回 4 if(T==NULL) 5 return; 6 //定義一個存放二叉樹節點的棧結構 7 stack<BinTree*>s; 8 BinTree *pcur; 9 pcur = T; 10 //循環遍歷二叉樹直到根節點為空或者棧為空 11 while (pcur || !s.empty()) 12 { 13 if (pcur) 14 { 15 cout << pcur->data; 16 s.push(pcur); 17 pcur = pcur->left; 18 }else 19 { 20 //當根節點為空時,說明左子樹已遍歷完,通過取出棧頂結點,來訪問根節點的右子樹 21 pcur = s.top(); 22 s.pop(); 23 pcur = pcur->right; 24 } 25 } 26 }
二、中序遍歷
遍歷順序是:左子樹-根節點-右子樹
1、遞歸遍歷
1 void inoeder(BinTree *T) 2 { 3 if(T == NULL) 4 return; 5 inoeder(T->left); 6 cout << T->data; 7 inoeder(T->right); 8 }
2、迭代遍歷(用棧實現)
1 void inorder2(BinTree *T) 2 { 3 if(T == NULL) 4 return; 5 stack<BinTree*>s; 6 BinTree *pcur; 7 pcur = T; 8 while (pcur || !s.empty()) 9 { 10 if (pcur) 11 { 12 //根節點非空,入棧,繼續遍歷左子樹直到根節點為空 13 s.push(pcur); 14 pcur = pcur->left; 15 }else 16 { 17 //根節點為空,說明左子樹已經遍歷完,彈出根節點打印,通過根節點訪問右子樹 18 pcur = s.top(); 19 s.pop(); 20 cout << pcur->data; 21 pcur = pcur->right; 22 } 23 } 24 }
三、后序遍歷
遍歷順序:左子樹-右子樹-根節點
1、遞歸遍歷
1 void postorder(BinTree *T) 2 { 3 if (T==NULL) 4 return; 5 postorder(T->left); 6 postorder(T->right); 7 cout << T->data; 8 }
2、迭代遍歷(用棧實現)
1 void postorder2(BinTree *T) 2 { 3 if(T == NULL) 4 return; 5 stack<BinTree*>s; 6 s.push(T); 7 BinTree *pcur; 8 pcur = NULL; 9 while (!s.empty()) 10 { 11 pcur = s.top(); 12 if (pcur->left == NULL && pcur->right == NULL) 13 { 14 cout << pcur->data; 15 s.pop(); 16 }else 17 { 18 //注意右孩子先入棧左孩子后入棧,這樣再次循環時左孩子節點才先出棧 19 if(pcur->right) 20 { 21 s.push(pcur->right); 22 pcur->right = NULL; 23 } 24 if (pcur->left) 25 { 26 s.push(pcur->left); 27 pcur->left = NULL; 28 } 29 } 30 } 31 }
四、層序遍歷
層序遍歷是圖的廣度優先搜索的應用,常用隊列結構實現
1.迭代遍歷
關鍵點:根節點一出隊列,就要判斷其左右孩子是否為空,若不為空的話依次入隊列
1 void leveltraversal(BinTree *T) 2 { 3 queue<BinTree*> s; 4 s.push(T); 5 BinTree* pcur; 6 while (!s.empty()) 7 { 8 pcur=s.front(); 9 cout<<pcur->data; 10 s.pop(); 11 if (pcur->left) 12 { 13 s.push(pcur->left); 14 } 15 if (pcur->right) 16 { 17 s.push(pcur->right); 18 } 19 } 20 }
2、分層遍歷二叉樹,即從上到下按層次訪問該樹,每一層單獨輸出一行
思想:定義兩個變量last,nlast,last代表正在打印的當前行的最右節點,nlast代表目前出現的進入隊列的最右節點(下一行節點),nlast跟蹤的是隊列中加入的節點。
last等於節點1,1入隊列,打印1並彈出1,將1的左右孩子放入隊列,2入隊列,並讓nlast等於節點2,3入隊列並讓nlast等於節點3,此時發現last與之前出隊列的1節點相等,換行,並將nlast賦給last(等於節點3)。
接下來,節點2出棧,打印節點2,並讓結點2的孩子進入隊列,節點4進入隊列並讓nlast等於節點4,節點3出隊列並打印節點3,讓節點3的孩子進入隊列,節點5進入隊列並讓nlast等於節點5,節點6進入隊列並讓nlast等於節點6,此時發現last與上次出隊列的節點3相等,於是換行,並將nlast賦給last(等於節點6),接下來類此。
1 void leveltraversal3(BinTree *T) 2 { 3 if(T == NULL) 4 return; 5 queue<BinTree*>s; 6 s.push(T); 7 BinTree *pcur,*last,*nlast; 8 last = T; 9 nlast = NULL; 10 while (!s.empty()) 11 { 12 pcur = s.front(); 13 cout << pcur->data; 14 s.pop(); 15 if (pcur->left) 16 { 17 s.push(pcur->left); 18 nlast = pcur->left; 19 } 20 if (pcur->right) 21 { 22 s.push(pcur->right); 23 nlast = pcur->right; 24 } 25 if (last == pcur) 26 { 27 cout << endl; 28 last = nlast; 29 } 30 } 31 }