一棵二叉树:
树的先序遍历序列preorder:DBACEGF(根左右)
树的中序遍历序列inorder:ABCDEFG(左根右)
树的后序遍历序列postorder:ACBFGED(左右根)
树的层序遍历序列levelorder:DBEACGF(按行遍历)
输入一棵二叉树的先序遍历和中序遍历序列,输出它的后序遍历序列。
输入:DBACEGF ABCDEFG 输出:ACBFGED
思路:
已知先序遍历序列的第一个一定是本树的根节点,而后在中序遍历中找到该根节点的位置,中序遍历序列中根节点左边为左子树,右边为右子树,然后开始先左子树后右子树进行递归,因为要求的后序遍历序列是左右根,故在递归完左右子树后再输出根。
Code:
1 #include<bits/stdc++.h> 2 #define IO ios::sync_with_stdio(false) 3 using namespace std; 4 string preorder,inorder,aa;//分别为先序、中序、后序 5 int n,t; 6 void recover(int l,int r) 7 { 8 if(l>=r)return; 9 int root=preorder[t++];//先序遍历的第一个点一定是根节点 10 int m=distance(inorder.begin(),find(inorder.begin(),inorder.end(),root));//找到中序中的根节点位置 11 recover(l,m);//根节点的左子树 12 recover(m+1,r);//右子树 13 aa.push_back(root);//因为要求后序遍历,所以根最后输出 14 } 15 int main() 16 { 17 IO; 18 while(!(cin>>preorder>>inorder).eof()) 19 { 20 aa.clear(); 21 t=0; 22 recover(0,preorder.size()); 23 for(int i=0;i<aa.size();i++){ 24 cout<<aa[i]; 25 } 26 cout<<endl; 27 } 28 return 0; 29 }
输入一棵二叉树的中序遍历和后序遍历序列,输出它的先序遍历序列。
输入:ABCDEFG ACBFGED 输出:DBACEGF
思路:
已知后序遍历的最后一个一定是本树的根节点,所以先从后序中找到当前树的根并输出(因为所要求的先序遍历是根左右,故找到根后就输出),然后去中序里找该根的位置,将中序划为两棵子树(中序遍历中根节点左边为其左子树,右边为其右子树),之后开始进行递归。
Code:
1 #include<bits/stdc++.h> 2 using namespace std; 3 string preorder,inorder,postorder; 4 void recover(int l,int r) 5 { 6 string t(inorder,l,r-l+1);//将中序序列inorder的l位置起r-l+1位复制给数组t 7 int vis=postorder.find_last_of(t);//后序遍历所找到的最后一个一定当前序列t的根 8 preorder.push_back(postorder[vis]);//要求先序,故先输出根,下面再分左右子树去递归 9 int m=inorder.find(postorder[vis]);//根在中序遍历中的位置m,中序遍历中根左边为左子树,根右边为右子树 10 if(m!=l) 11 recover(l,m-1);//左子树递归 12 if(m!=r) 13 recover(m+1,r);//右子树递归 14 } 15 int main() 16 { 17 while(!(cin>>inorder>>postorder).eof())//输入中序遍历和后序遍历的序列 18 { 19 preorder.clear();//多测试用例故要清空 20 recover(0,inorder.size()-1); 21 cout<<preorder<<endl;//输出先序遍历序列 22 } 23 return 0; 24 }
1 #include<bits/stdc++.h> 2 using namespace std; 3 void recover(string zhong,string hou){ 4 if(zhong.size()>0){ 5 char root=hou[hou.size()-1];//后序的最后一个为根节点 6 cout<<root;//输出根 7 int vis=zhong.find(root);//该根在中序中的位置 8 recover(zhong.substr(0,vis),hou.substr(0,vis));//递归左子树 9 recover(zhong.substr(vis+1),hou.substr(vis,zhong.size()-vis-1));//递归右子树 10 } 11 } 12 int main() 13 { 14 string inorder,postorder; 15 while(cin>>inorder>>postorder) 16 { 17 recover(inorder,postorder); 18 cout<<endl; 19 } 20 return 0; 21 }
知道中序和后序遍历,画二叉树和写出前序遍历 输入一颗二叉树的先序遍历和中序遍历序列,输出它的层序遍历序列。 输入:DBACEGF ABCDEFG 输出:DBEACGF 层序遍历思路:
创建一个队列,先将根节点入队,输出根节点,将根节点的儿子先左后右入队,根节点出队,如此循环直到队列为空。
Code:
1 #include<bits/stdc++.h> 2 using namespace std; 3 struct TreeNode 4 { 5 TreeNode *l,*r; 6 char data; 7 }; 8 TreeNode *create(char *pre,char *mid,int len) //三个参数分别为先序序列,中序序列,序列长度 9 { 10 if(len<=0) 11 return NULL; //空节点 12 TreeNode *root; 13 root=new TreeNode; 14 root->data=pre[0]; //先序遍历的第一个一定是根节点,如此迭代 15 int i; 16 for(i=0;i<len;i++){ 17 if(mid[i]==pre[0]) //在中序遍历中找到该根节点的位置 18 break; 19 } 20 root->l=create(pre+1,mid,i); //递归左子树,左子树中先序遍历字串向后挪一位,中序不变,但i控制了长度 21 root->r=create(pre+i+1,mid+i+1,len-i-1);//递归右子树,右子树中先序遍历和中序遍历都向后挪i+1位,长度变成总长度减去前半部分的长度 22 return root; 23 } 24 void levelorder(TreeNode *root) //层序遍历 25 { 26 queue<TreeNode*>que;//注意是TreeNode* 27 if(root){ //一定要特判,不然会RE 28 que.push(root); 29 cout<<que.front()->data; 30 } 31 while(que.size()) 32 { 33 TreeNode *root=que.front(); 34 que.pop(); 35 if(root->l){ //依次找左右儿子输出 36 cout<<root->l->data; 37 que.push(root->l); 38 } 39 if(root->r){ 40 cout<<root->r->data; 41 que.push(root->r); 42 } 43 } 44 } 45 void postorder(TreeNode *root) //后序遍历 46 { 47 if(!root) 48 return; 49 postorder(root->l); 50 postorder(root->r); 51 cout<<root->data; 52 } 53 54 int main() 55 { 56 char preorder[1000],inorder[1000]; 57 while(!(cin>>preorder>>inorder).eof())//输入先序遍历序列和中序遍历序列 58 { 59 TreeNode *root; 60 int len=strlen(preorder); 61 root=create(preorder,inorder,len); 62 levelorder(root);cout<<endl; //输出层序遍历序列 63 postorder(root);cout<<endl; //输出后序遍历序列 64 } 65 return 0; 66 }