二叉树遍历
1.1、先序遍历 根结点-左子树-右子树
//---指针 void preorder(node* root) { if(root==NULL) return; //空树,递归边界 printf("%d\n",root->data); preoder(root->lchild); preoder(root->rchild); } //---数组 void preorder(int root) { if(root==-1) return; printf("%d\n",Node[root].data); preorder(Node[root].lchild); preorder(Node[root].rchild); }
1.2、中序遍历 左子树-根结点-右子树
//---指针 void inorder(node* root) { if(root==NULL) return; inorder(root->lchild); printf("%d\n",root->data); inorder(root->rchild); } //---数组 void inorder(int root) { if(root==-1) return; inorder(Node[root].lchild); printf("%d\n",Node[root].data); inorder(Node[root].rchild); }
1.3、后序遍历 左子树-右子树-根结点
//---指针 void postorder(node* root) { if(root==NULL) return; postorder(root->lchild); postorder(root->rchild); printf("%d\n",root->data); } //---数组 void postorder(int root) { if(root==-1) return; postorder(Node[root].lchild); postorder(Node[root].rchild); printf("%d\n",Node[root].data); }
1.4、层次遍历
//层次遍历 //---指针 void Layerorder(node* root) { queue<node*> que; root->layer=1; que.push(root); while(!que.empty()) { node* one=que.front(); que.pop(); printf("%d ",one->data); if(one->lchild!=NULL) { one->lchild->layer=one->layer+1; que.push(one->lchild); } if(one->rchild!=NULL) { one->rchild->layer=one->layer+1; que.push(one->rchild); } } } //---数组 void Layerorder(int root){ queue<int> que; que.push(root); while(!que.empty()){ int now=que.front(); que.pop(); printf("%d ",Node[now].data); //访问队首元素 if(Node[now].lchild!=-1) que.push(Node[now].lchild); if(Node[now].rchild!=-1) que.push(Node[now].rchild); } }
2.1 依据先序遍历和中序遍历构造二叉树
/* 先序遍历区间[preL,preR] 中序遍历区间[inL,inR] numleft=k-inL 左子树 先序区间:[preL+1,preL+numLeft] 中序区间:[inL,K-1] 右子树 先序区间:[preL+numLeft+1,preR] 中序遍历区间:[k+1,inR] */ node* create(int preL,int preR,int inL,int inR) { if(preL>preR) return NULL; node* root=new node; root->data=pre[preL]; int k; for(k=inL,k<=inR;k++) { if(in[k]==pre[preL]) break; } int numLeft=k-inL; //返回左子树的根结点地址,赋值给root的左指针 root->lchild=create(preL+1,preL+numLeft,inL,k-1); root->rchild=create(preL+numLeft+1,preR,k+1,inR); return root; }
3、练习题
3.1 PTA A1020 Tree Traversals
https://pintia.cn/problem-sets/994805342720868352/problems/994805485033603072
依据后序遍历和中序遍历构造二叉树,并输出该二叉树的层次遍历序列
/* 后序遍历区间:[postL,postR] 中序遍历区间:[inL,inR] numLeft=k-inL 左子树 后序区间:[postL,postL+numLeft-1] 中序区间:[inL,k-1] 右子树 后序区间:[postL+numLeft,postR-1] 中序区间:[k+1,inR] */ #include <cstdio> #include <iostream> #include <queue> using namespace std; #define maxn 35 int pos[maxn]; //存放后序遍历结点的数据值 int in[maxn]; //存放中序遍历结点的数据值 int numLeft; //二叉链表结构 typedef struct node{ int data; // int layer; node* lchild; node* rchild; }; node* create(int postL,int postR,int inL,int inR); void Layerorder(node* root); int main() { int n; // while(cin>>n){ cin>>n; node* root=new node; pos[maxn]={0}; in[maxn]={0}; numLeft=0; for(int i=0;i<n;i++) cin>>pos[i]; for(int i=0;i<n;i++) cin>>in[i]; root=create(0,n-1,0,n-1); Layerorder(root); // } return 0; } //create函数返回构建出的二叉树的根结点地址 node* create(int postL,int postR,int inL,int inR) { if(postL>postR) return NULL; node* root=new node; //新建一个新结点 root->data=pos[postR]; int k; for(k=inL;k<=inR;k++) { if(in[k]==pos[postR]) break; } int numLeft=k-inL; //将左子树的根结点赋值给root的左指针 root->lchild=create(postL,postL+numLeft-1,inL,k-1); //将右子树的根结点赋值给root的右指针 root->rchild=create(postL+numLeft,postR-1,k+1,inR); return root; } void Layerorder(node* root) { bool flag=true; queue<node*> que; que.push(root); while(!que.empty()) { node* one=que.front(); if(flag) { printf("%d",one->data); flag=false; } else printf(" %d",one->data); que.pop(); if(one->lchild!=NULL) que.push(one->lchild); if(one->rchild!=NULL) que.push(one->rchild); } printf("\n"); } /* 7 2 3 1 5 7 6 4 1 2 3 4 5 6 7 4 1 6 3 5 7 2 8 4 8 5 2 7 6 3 1 4 2 8 5 1 6 7 3 1 2 3 4 5 6 8 7 */
3.2、复原二叉树
http://codeup.cn/problem.php?cid=100000611&pid=0
给定二叉树的前序遍历和中序遍历,写出二叉树的后序遍历结果
#include <cstdio> #include <cstring> #include <iostream> #include <queue> using namespace std; #define maxn 100 typedef struct node{ char data; struct node* lchild; struct node* rchild; }; char pre[maxn],in[maxn]; node* create(int preL,int preR,int inL,int inR); void postOrder(node* root); void LayerOrder(node* root); int main() { string str1,str2; while(cin>>str1>>str2){ node* root=new node; int len=str1.length(); for(int i=0;i<len;i++) pre[i]=str1[i]; for(int i=0;i<len;i++) in[i]=str2[i]; root=create(0,len-1,0,len-1); postOrder(root); cout<<endl; // LayerOrder(root); } return 0; } node* create(int preL,int preR,int inL,int inR) { if(preL>preR) return NULL; node* root=new node; root->data=pre[preL]; //!!! int k; for(k=inL;k<=inR;k++){ if(in[k]==pre[preL]) break; } int numLeft=k-inL; root->lchild=create(preL+1,preL+numLeft,inL,k-1); root->rchild=create(preL+numLeft+1,preR,k+1,inR); return root; } void postOrder(node* root) { if(root==NULL){ return; } postOrder(root->lchild); postOrder(root->rchild); cout<<root->data; } void LayerOrder(node* root) { queue<node*> que; que.push(root); while(!que.empty()){ node* one=que.front(); cout<<one->data; que.pop(); if(one->lchild!=NULL) que.push(one->lchild); if(one->rchild!=NULL) que.push(one->rchild); } cout<<endl; } /* DBACEGF ABCDEFG ACBFGED BCAD CBAD CDAB */
3.3、问题B:二叉树
http://codeup.cn/problem.php?cid=100000611&pid=1
①AC代码,数学处理 内存:2176KB 耗时:3ms
#include <cstdio> #include <iostream> using namespace std; int main() { int m,n; int left,right; int cnt=0; while(cin>>m>>n) { if(m==0&&n==0) break; cnt=0; left=right=m; while(left<=n) { cnt+=(right-left+1); left=left*2; right=right*2+1; if(right>n) right=n; } cout<<cnt<<endl; } return 0; }
② 递归,时间超限 内存:2176KB 耗时:1142ms
#include <cstdio> #include <iostream> using namespace std; int m,n; int ans=0; void func(int m) { if(m>n) return; func(2*m); func(2*m+1); ans++; } int main() { while(scanf("%d%d",&m,&n)) { if(m==0&&n==0) break; ans=0; func(m); printf("%d\n",ans); } return 0; }
③ 队列 ,内存超限 内存:32876KB 耗时:487ms
#include <cstdio> #include <iostream> #include <queue> using namespace std; int main() { int m,n; while(cin>>m>>n) { int cou=0; if(m==0&&n==0) break; queue<int> que; que.push(m); while(!que.empty()) { int value=que.front(); if(value<=n) cou++; que.pop(); if(2*value<=n) que.push(2*value); if(2*value+1<=n) que.push(2*value+1); } cout<<cou<<endl; } return 0; }
3.4 、问题D:二叉树遍历
http://codeup.cn/problem.php?cid=100000611&pid=3
递归
#include <cstdio> #include <iostream> #include <stack> using namespace std; #define maxn 105 typedef struct node{ char data; struct node* lchild; struct node* rchild; }; int i=0; char pre[maxn]; stack<node*> sta; node* create(); void inOrder(node* root); int main() { string str; int len; while(gets(pre)) { i=0; node* root=new node; root=create(); inOrder(root); cout<<endl; } return 0; } node* create() { node* root=new node; if(pre[i]=='#') { i++; return NULL; } root->data=pre[i]; i++; root->lchild=create(); root->rchild=create(); return root; } void inOrder(node* root) { if(root==NULL) return; inOrder(root->lchild); cout<<root->data<<" "; inOrder(root->rchild); }
天晴了,起飞吧