今天集中把二叉树的各种遍历刷掉了。(虽然都写得很暴力,但是暴力有暴力的好处嘛)
P1305新二叉树
本来是应该用结构体然后指针指儿子建树的,可是一看只有26个字母,就直接一维数组存了,最坏情况也就2^26-1个节点,而且刚好用char存只占一个字节比int省了(爽到)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| #include<stdio.h> char tree[67108870]; int hash[300]={0}; void first(int rt){ if(tree[rt]=='*')return; printf("%c",tree[rt]); first(rt*2+1); first(rt*2+2); } int main(){ int n,i,j,rt; char t[10]; scanf("%d",&n); for(i=1;i<=n;i++){ scanf("%s",t); rt=hash[t[0]]; tree[rt]=t[0]; tree[rt*2+1]=t[1]; tree[rt*2+2]=t[2]; hash[t[0]]=rt; hash[t[1]]=rt*2+1; hash[t[2]]=rt*2+2; } first(0); return 0; }
|
P1030求先序排列
这题更暴力
根据遍历定义和二叉树的性质就知道应该是二分递归求解的。
中序:左根右
后序:左右根
先序:根左右
由此,方法就是
1 2 3 4 5 6 7
| f(中序,后序){ 输出根; 在中序中找到左右子树; 在后序中找到左右子树; f(左子树中序,左子树后序); f(右子树中序,右子树后序); }
|
中序只要找到根节点,左右子树马上就有了。后序呢?
后序就暴力了,枚举了中序的左子树找右边界或者枚举右子树找左边界……
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| #include<stdio.h> #include<string.h> char mid[100],last[100];
void first(int midl,int midr,int lastl,int lastr){ if(midl>midr||lastl>lastr)return; char t=last[lastr]; int i,j,mrt,max=-1,min=100; printf("%c",t); for(i=midl;i<=midr;i++) if(t==mid[i]){mrt=i;break;} for(i=midl;i<mrt;i++) for(j=lastl;j<lastr;j++) if(mid[i]==last[j]&&j>max)max=j; for(i=mrt+1;i<=midr;i++) for(j=lastl;j<lastr;j++) if(mid[i]==last[j]&&j<min)min=j; if(min!=100)max=min-1; else if(max!=-1)min=max+1; first(midl,mrt-1,lastl,max); first(mrt+1,midr,min,lastr-1); }
int main(){ int len; scanf("%s",mid); scanf("%s",last); len=strlen(mid); first(0,len-1,0,len-1); return 0; }
|
另外,一定要用scanf/printf,原因不明……