生活随笔
收集整理的這篇文章主要介紹了
二叉树的先序/中序/后序/层次遍历
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
【簡介】
樹形結構是一類重要的非線性數據結構,其中以樹和二叉樹最為常用。
二叉樹是每個結點最多有兩個子樹的有序樹。通常子樹的根被稱作“左子樹”(left subtree)和“右子樹”(right subtree)。二叉樹常被用作二叉查找樹和二叉堆或是二叉排序樹。二叉樹的每個結點至多只有二棵子樹(不存在度大于2的結點),二叉樹的子樹有左右之分,次序不能顛倒。二叉樹的第i層至多有2的 i -1次方個結點;深度為k的二叉樹至多有2^(k) -1個結點;對任何一棵二叉樹T,如果其終端結點數(即葉子結點數)為n0,度為2的結點數為n2,則n0 = n2 + 1。
二叉樹的鏈式存儲結構是一類重要的數據結構,其形式定義如下:
[cpp]?view plaincopy
?? typedef?struct?BiTNode{?? ?????? ????char?data;?? ?????? ????struct?BiTNode?*lchild,*rchild;?? }BiTNode,*BiTree;??
或者
[cpp] view plaincopy
??struct?TreeNode{??????int?val;??????TreeNode?*left;??????TreeNode?*right;??????TreeNode(int?x):val(x),left(nullptr),right(nullptr){}??};??
【二叉樹的創建】
通過讀入一個字符串,建立二叉樹的算法如下:
[cpp]?view plaincopy
?? int?CreateBiTree(BiTree?&T){?? ????char?data;?? ?????? ????scanf("%c",&data);?? ????if(data?==?'#'){?? ????????T?=?NULL;?? ????}?? ????else{?? ????????T?=?(BiTree)malloc(sizeof(BiTNode));?? ?????????? ????????T->data?=?data;?? ?????????? ????????CreateBiTree(T->lchild);?? ?????????? ????????CreateBiTree(T->rchild);?? ????}?? ????return?0;?? }??
或者
[cpp] view plaincopy
??void?CreateTree(TreeNode*?&root){??????int?val;????????????cin>>val;????????????if(val?==?-1){??????????root?=?nullptr;??????????return;??????}??????root?=?new?TreeNode(val);????????????CreateTree(root->left);????????????CreateTree(root->right);??}??
層次建立二叉樹:
[cpp] view plaincopy
struct?TreeNode?{??????int?val;??????TreeNode?*left;??????TreeNode?*right;??????TreeNode(int?x)?:?val(x),?left(NULL),?right(NULL)?{}??};??
[cpp] view plaincopy
??TreeNode*?CreateTreeByLevel(vector<char>?num){??????int?len?=?num.size();??????if(len?==?0){??????????return?NULL;??????}??????queue<TreeNode*>?queue;??????int?index?=?0;????????????TreeNode?*root?=?new?TreeNode(num[index++]);????????????queue.push(root);??????TreeNode?*p?=?NULL;??????while(!queue.empty()?&&?index?<?len){????????????????????p?=?queue.front();??????????queue.pop();????????????????????if(index?<?len?&&?num[index]?!=?-1){????????????????????????????TreeNode?*leftNode?=?new?TreeNode(num[index]);??????????????p->left?=?leftNode;??????????????queue.push(leftNode);??????????}??????????index++;????????????????????if(index?<?len?&&?num[index]?!=?-1){????????????????????????????TreeNode?*rightNode?=?new?TreeNode(num[index]);??????????????p->right?=?rightNode;??????????????queue.push(rightNode);??????????}??????????index++;??????}??????return?root;??}??
-1代表NULL
創建如上二叉樹輸入:
15 11 20 8 14 -1 -1 -1 -1 13 -1
【二叉樹的遍歷】
遍歷是對樹的一種最基本的運算,所謂遍歷二叉樹,就是按一定的規則和順序走遍二叉樹的所有結點,使每一個結點都被訪問一次,而且只被訪問一次。由于二叉樹是非線性結構,因此,樹的遍歷實質上是將二叉樹的各個結點轉換成為一個線性序列來表示。
【遞歸算法】
[cpp]?view plaincopy
?? void?Visit(BiTree?T){?? ????if(T->data?!=?'#'){?? ????????printf("%c?",T->data);?? ????}?? }?? ?? void?PreOrder(BiTree?T){?? ????if(T?!=?NULL){?? ?????????? ????????Visit(T);?? ?????????? ????????PreOrder(T->lchild);?? ?????????? ????????PreOrder(T->rchild);?? ????}?? }?? ?? void?InOrder(BiTree?T){?? ????if(T?!=?NULL){?? ?????????? ????????InOrder(T->lchild);?? ?????????? ????????Visit(T);?? ?????????? ????????InOrder(T->rchild);?? ????}?? }?? ?? void?PostOrder(BiTree?T){?? ????if(T?!=?NULL){?? ?????????? ????????PostOrder(T->lchild);?? ?????????? ????????PostOrder(T->rchild);?? ?????????? ????????Visit(T);?? ????}?? }??
【非遞歸算法】
【先序遍歷】
【思路】:訪問T->data后,將T入棧,遍歷左子樹;遍歷完左子樹返回時,棧頂元素應為T,出棧,再先序遍歷T的右子樹。
[cpp]?view plaincopy
? ? ?? void?PreOrder2(BiTree?T){?? ????stack<BiTree>?stack;?? ?????? ????BiTree?p?=?T;?? ?????? ????while(p?||?!stack.empty()){?? ????????if(p?!=?NULL){?? ?????????????? ????????????stack.push(p);?? ?????????????? ????????????printf("%c?",p->data);?? ?????????????? ????????????p?=?p->lchild;?? ????????}?? ????????else{?? ?????????????? ????????????p?=?stack.top();?? ????????????stack.pop();?? ?????????????? ????????????p?=?p->rchild;?? ????????}?? ????}?? } ?
[cpp] view plaincopy
??void?PreOrder(TreeNode*?root){??????if(root?==?NULL){??????????return;??????}??????stack<TreeNode*>?stack;??????stack.push(root);??????TreeNode?*p?=?NULL;??????while(!stack.empty()){??????????p?=?stack.top();??????????stack.pop();??????????cout<<p->val<<endl;????????????????????if(p->right){??????????????stack.push(p->right);??????????}????????????????????if(p->left){??????????????stack.push(p->left);??????????}??????}??}??
【中序遍歷】
【思路】:T是要遍歷樹的根指針,中序遍歷要求在遍歷完左子樹后,訪問根,再遍歷右子樹。
? ? ? ? ?先將T入棧,遍歷左子樹;遍歷完左子樹返回時,棧頂元素應為T,出棧,訪問T->data,再中序遍歷T的右子樹。
[cpp]?view plaincopy
void?InOrder2(BiTree?T){?? ????stack<BiTree>?stack;?? ?????? ????BiTree?p?=?T;?? ?????? ????while(p?||?!stack.empty()){?? ????????if(p?!=?NULL){?? ?????????????? ????????????stack.push(p);?? ?????????????? ????????????p?=?p->lchild;?? ????????}?? ????????else{?? ?????????????? ????????????p?=?stack.top();?? ????????????printf("%c?",p->data);?? ????????????stack.pop();?? ?????????????? ????????????p?=?p->rchild;?? ????????}?? ????}?? }??
【后序遍歷】
【思路】:T是要遍歷樹的根指針,后序遍歷要求在遍歷完左右子樹后,再訪問根。需要判斷根結點的左右子樹是否均遍歷過。
[cpp]?view plaincopy
?? typedef?struct?BiTNodePost{?? ????BiTree?biTree;?? ????char?tag;?? }BiTNodePost,*BiTreePost;?? ?? void?PostOrder2(BiTree?T){?? ????stack<BiTreePost>?stack;?? ?????? ????BiTree?p?=?T;?? ????BiTreePost?BT;?? ?????? ????while(p?!=?NULL?||?!stack.empty()){?? ?????????? ????????while(p?!=?NULL){?? ????????????BT?=?(BiTreePost)malloc(sizeof(BiTNodePost));?? ????????????BT->biTree?=?p;?? ?????????????? ????????????BT->tag?=?'L';?? ????????????stack.push(BT);?? ????????????p?=?p->lchild;?? ????????}?? ?????????? ????????while(!stack.empty()?&&?(stack.top())->tag?==?'R'){?? ????????????BT?=?stack.top();?? ?????????????? ????????????stack.pop(); ?? ????????????printf("%c?",BT->biTree->data);?? ????????}?? ?????????? ????????if(!stack.empty()){?? ????????????BT?=?stack.top();?? ?????????????? ????????????BT->tag?=?'R';?? ????????????p?=?BT->biTree;?? ????????????p?=?p->rchild;?? ????????}?? ????}?? }??
或者
[cpp] view plaincopy
vector<int>?postorderTraversal(TreeNode?*root)?{??????vector<int>?result;??????if(root?==?nullptr){??????????return?result;??????}??????stack<TreeNode*>?s;??????s.push(root);??????TreeNode?*node;??????while(!s.empty()){??????????node?=?s.top();??????????s.pop();??????????result.insert(result.begin(),node->val);????????????????????if(node->left){??????????????s.push(node->left);??????????}????????????????????if(node->right){??????????????s.push(node->right);??????????}??????}??????return?result;??}??
【層次遍歷】
【思路】:按從頂向下,從左至右的順序來逐層訪問每個節點,層次遍歷的過程中需要用隊列。
[cpp]?view plaincopy
?? void?LevelOrder(BiTree?T){?? ????BiTree?p?=?T;?? ?????? ????queue<BiTree>?queue;?? ?????? ????queue.push(p);?? ?????? ????while(!queue.empty()){?? ?????????? ????????p?=?queue.front();?? ?????????? ????????printf("%c?",p->data);?? ?????????? ????????queue.pop();?? ?????????? ????????if(p->lchild?!=?NULL){?? ????????????queue.push(p->lchild);?? ????????}?? ?????????? ????????if(p->rchild?!=?NULL){?? ????????????queue.push(p->rchild);?? ????????}?? ????}?? }??
【測試】
輸入:(先序)
15 11 8 -1 -1 14 13 -1 -1 -1 20 -1 -1
輸出:
代碼一:
[cpp] view plaincopy
????????#include?<iostream>??#include?<vector>??#include?<stack>??#include?<queue>??using?namespace?std;??????struct?TreeNode{??????int?val;??????TreeNode?*left;??????TreeNode?*right;??????TreeNode(int?x):val(x),left(nullptr),right(nullptr){}??};????void?CreateTree(TreeNode*?&root){??????int?val;????????????cin>>val;????????????if(val?==?-1){??????????root?=?nullptr;??????????return;??????}??????root?=?new?TreeNode(val);????????????CreateTree(root->left);????????????CreateTree(root->right);??}????void?PreOrder(TreeNode*?root,vector<int>?&result){??????if(root?==?nullptr){??????????return;??????}??????result.push_back(root->val);????????????PreOrder(root->left,result);????????????PreOrder(root->right,result);??}????void?PreOrder2(TreeNode*?root,vector<int>?&result){??????if(root?==?nullptr){??????????return;??????}??????stack<TreeNode*>?s;??????s.push(root);??????TreeNode?*node;??????while(!s.empty()){??????????node?=?s.top();??????????s.pop();??????????result.push_back(node->val);????????????????????if(node->right){??????????????s.push(node->right);??????????}????????????????????if(node->left){??????????????s.push(node->left);??????????}??????}??}????void?InOrder(TreeNode*?root,vector<int>?&result){??????if(root?==?nullptr){??????????return;??????}????????????InOrder(root->left,result);??????result.push_back(root->val);????????????InOrder(root->right,result);??}????void?InOrder2(TreeNode*?root,vector<int>?&result){??????if(root?==?nullptr){??????????return;??????}??????stack<TreeNode*>?s;??????TreeNode?*node?=?root;??????while(node?!=?nullptr?||?!s.empty()){????????????????????if(node?!=?nullptr){??????????????s.push(node);??????????????node?=?node->left;??????????}????????????????????else{??????????????node?=?s.top();??????????????s.pop();??????????????result.push_back(node->val);??????????????node?=?node->right;??????????}??????}??}????void?PostOrder(TreeNode*?root,vector<int>?&result){??????if(root?==?nullptr){??????????return;??????}????????????PostOrder(root->left,result);????????????PostOrder(root->right,result);??????result.push_back(root->val);??}????void?PostOrder2(TreeNode?*root,vector<int>?&result)?{??????if(root?==?nullptr){??????????return;??????}??????stack<TreeNode*>?s;??????s.push(root);??????TreeNode?*node;??????while(!s.empty()){??????????node?=?s.top();??????????s.pop();??????????result.insert(result.begin(),node->val);????????????????????if(node->left){??????????????s.push(node->left);??????????}????????????????????if(node->right){??????????????s.push(node->right);??????????}??????}??}????void?LevelOrder(TreeNode*?root,vector<int>?&result){??????if(root?==?nullptr){??????????return;??????}??????queue<TreeNode*>?queue;??????queue.push(root);??????TreeNode?*node;??????while(!queue.empty()){??????????node?=?queue.front();??????????queue.pop();??????????result.push_back(node->val);????????????????????if(node->left){??????????????queue.push(node->left);??????????}????????????????????if(node->right){??????????????queue.push(node->right);??????????}??????}??}????void?Print(vector<int>?result){??????int?size?=?result.size();??????for(int?i?=?0;i?<?size;++i){??????????cout<<result[i]<<"?";??????}??????cout<<endl;??}??int?main(){??????freopen("C:\\Users\\Administrator\\Desktop\\c++.txt",?"r",?stdin);??????TreeNode*?root?=?nullptr;??????vector<int>?result;????????????cout<<"1.?創建二叉樹"<<endl;??????CreateTree(root);??????cout<<"-----------------------------"<<endl;????????cout<<"2.1?遞歸先序遍歷"<<endl;??????PreOrder(root,result);??????Print(result);??????result.clear();??????cout<<"-----------------------------"<<endl;????????cout<<"2.2?非遞歸先序遍歷"<<endl;??????PreOrder2(root,result);??????Print(result);??????result.clear();??????cout<<"-----------------------------"<<endl;????????cout<<"3.1?遞歸中序遍歷"<<endl;??????InOrder(root,result);??????Print(result);??????result.clear();??????cout<<"-----------------------------"<<endl;????????cout<<"3.2?非遞歸中序遍歷"<<endl;??????InOrder2(root,result);??????Print(result);??????result.clear();??????cout<<"-----------------------------"<<endl;????????cout<<"4.1?遞歸后序遍歷"<<endl;??????PostOrder(root,result);??????Print(result);??????result.clear();??????cout<<"-----------------------------"<<endl;????????cout<<"4.2?非遞歸后序遍歷"<<endl;??????PostOrder2(root,result);??????Print(result);??????result.clear();??????cout<<"-----------------------------"<<endl;????????cout<<"5?層次遍歷"<<endl;??????LevelOrder(root,result);??????Print(result);??????result.clear();??????cout<<"-----------------------------"<<endl;??????return?0;??}??
測試用例:
輸入:
ABC##DE#G##F###
輸出:
代碼二:
[cpp]?view plaincopy
#include<iostream>?? #include<stack>?? #include<queue>?? using?namespace?std;?? ?? ?? typedef?struct?BiTNode{?? ?????? ????char?data;?? ?????? ????struct?BiTNode?*lchild,*rchild;?? }BiTNode,*BiTree;?? ?? ?? int?CreateBiTree(BiTree?&T){?? ????char?data;?? ?????? ????scanf("%c",&data);?? ????if(data?==?'#'){?? ????????T?=?NULL;?? ????}?? ????else{?? ????????T?=?(BiTree)malloc(sizeof(BiTNode));?? ?????????? ????????T->data?=?data;?? ?????????? ????????CreateBiTree(T->lchild);?? ?????????? ????????CreateBiTree(T->rchild);?? ????}?? ????return?0;?? }?? ?? void?Visit(BiTree?T){?? ????if(T->data?!=?'#'){?? ????????printf("%c?",T->data);?? ????}?? }?? ?? void?PreOrder(BiTree?T){?? ????if(T?!=?NULL){?? ?????????? ????????Visit(T);?? ?????????? ????????PreOrder(T->lchild);?? ?????????? ????????PreOrder(T->rchild);?? ????}?? }?? ?? void?InOrder(BiTree?T){???? ????if(T?!=?NULL){???? ?????????? ????????InOrder(T->lchild);???? ?????????? ????????Visit(T);???? ?????????? ????????InOrder(T->rchild);???? ????}???? }???? ?? void?PostOrder(BiTree?T){?? ????if(T?!=?NULL){?? ?????????? ????????PostOrder(T->lchild);?? ?????????? ????????PostOrder(T->rchild);?? ?????????? ????????Visit(T);?? ????}?? }?? ? ? ?? void?PreOrder2(BiTree?T){?? ????stack<BiTree>?stack;?? ?????? ????BiTree?p?=?T;?? ?????? ????while(p?||?!stack.empty()){?? ????????if(p?!=?NULL){?? ?????????????? ????????????stack.push(p);?? ?????????????? ????????????printf("%c?",p->data);?? ?????????????? ????????????p?=?p->lchild;?? ????????}?? ????????else{?? ?????????????? ????????????p?=?stack.top();?? ????????????stack.pop();?? ?????????????? ????????????p?=?p->rchild;?? ????????}?? ????}?? }?? ? ? ? ?? void?InOrder2(BiTree?T){?? ????stack<BiTree>?stack;?? ?????? ????BiTree?p?=?T;?? ?????? ????while(p?||?!stack.empty()){?? ????????if(p?!=?NULL){?? ?????????????? ????????????stack.push(p);?? ?????????????? ????????????p?=?p->lchild;?? ????????}?? ????????else{?? ?????????????? ????????????p?=?stack.top();?? ????????????printf("%c?",p->data);?? ????????????stack.pop();?? ?????????????? ????????????p?=?p->rchild;?? ????????}?? ????}?? }?? ?? ?? typedef?struct?BiTNodePost{?? ????BiTree?biTree;?? ????char?tag;?? }BiTNodePost,*BiTreePost;?? ?? void?PostOrder2(BiTree?T){?? ????stack<BiTreePost>?stack;?? ?????? ????BiTree?p?=?T;?? ????BiTreePost?BT;?? ?????? ????while(p?!=?NULL?||?!stack.empty()){?? ?????????? ????????while(p?!=?NULL){?? ????????????BT?=?(BiTreePost)malloc(sizeof(BiTNodePost));?? ????????????BT->biTree?=?p;?? ?????????????? ????????????BT->tag?=?'L';?? ????????????stack.push(BT);?? ????????????p?=?p->lchild;?? ????????}?? ?????????? ????????while(!stack.empty()?&&?(stack.top())->tag?==?'R'){?? ????????????BT?=?stack.top();?? ?????????????? ????????????stack.pop();?? ????????????BT->biTree;?? ????????????printf("%c?",BT->biTree->data);?? ????????}?? ?????????? ????????if(!stack.empty()){?? ????????????BT?=?stack.top();?? ?????????????? ????????????BT->tag?=?'R';?? ????????????p?=?BT->biTree;?? ????????????p?=?p->rchild;?? ????????}?? ????}?? }?? ?? void?LevelOrder(BiTree?T){?? ????BiTree?p?=?T;?? ?????? ????queue<BiTree>?queue;?? ?????? ????queue.push(p);?? ?????? ????while(!queue.empty()){?? ?????????? ????????p?=?queue.front();?? ?????????? ????????printf("%c?",p->data);?? ?????????? ????????queue.pop();?? ?????????? ????????if(p->lchild?!=?NULL){?? ????????????queue.push(p->lchild);?? ????????}?? ?????????? ????????if(p->rchild?!=?NULL){?? ????????????queue.push(p->rchild);?? ????????}?? ????}?? }?? int?main()?? {?? ????BiTree?T;?? ????CreateBiTree(T);?? ????printf("先序遍歷:\n");?? ????PreOrder(T);?? ????printf("\n");?? ????printf("先序遍歷(非遞歸):\n");?? ????PreOrder2(T);?? ????printf("\n");?? ????printf("中序遍歷:\n");?? ????InOrder(T);?? ????printf("\n");?? ????printf("中序遍歷(非遞歸):\n");?? ????InOrder2(T);?? ????printf("\n");?? ????printf("后序遍歷:\n");?? ????PostOrder(T);?? ????printf("\n");?? ????printf("后序遍歷(非遞歸):\n");?? ????PostOrder2(T);?? ????printf("\n");?? ????printf("層次遍歷:\n");?? ????LevelOrder(T);?? ????printf("\n");?? ????return?0;?? }?
出處:http://blog.csdn.net/sjf0115/article/details/8645991
總結
以上是生活随笔為你收集整理的二叉树的先序/中序/后序/层次遍历的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。