swust oj 987
输出用先序遍历创建的二叉树是否为完全二叉树的判定结果
1000(ms)
10000(kb)
2553 / 5268
利用先序递归遍历算法创建二叉树并判断该二叉树是否为完全二叉树。完全二叉树只能是同深度的满二叉树缺少最后一层倒数连续个叶子结点。先序递归遍历建立二叉树的方法为:按照先序递归遍历的思想将对二叉树结点的抽象访问具体化为根据接收的数据决定是否产生该结点从而实现创建该二叉树的二叉链表存储结构。约定二叉树结点数据为单个大写英文字符。当接收的数据是字符"#"时表示该结点不需要创建,否则创建该结点。最后判断创建完成的二叉树度是否为完全二叉树。需要注意输入数据序列中的"#"字符和非"#"字符的序列及个数关系,这会最终决定创建的二叉树的形态。
输入
输入为接受键盘输入的由大写英文字符和"#"字符构成的一个字符串(用于创建对应的二叉树)。
输出
对应的二叉树是否为完全二叉树的判断结果。若是输出"Y",否则输出"N"。
样例输入
A## ABC#### AB##C## ABCD###EF##G### A##B## ABC##D##EG###
样例输出
Y N Y N Y Y
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cstdio> 6 typedef char Datetype; 7 using namespace std; 8 Datetype value; 9 int x; 10 11 typedef struct link{ 12 Datetype date; 13 struct link *lchild; 14 struct link *rchild; 15 }tree; 16 17 typedef struct queue{ 18 tree *data; 19 struct queue *next; 20 }que; 21 22 typedef struct { 23 que *front; 24 que *rear; 25 }lin; 26 27 void Initqueue(lin *&L) 28 { 29 L=(lin *)malloc(sizeof(lin)); 30 L->front=L->rear=NULL; 31 } 32 33 void destroyed(lin *&L) 34 { 35 que *p=NULL,*r=NULL; 36 p=L->front; 37 while(p!=NULL) 38 { 39 r=p; 40 p=p->next; 41 free(r); 42 } 43 free(L); 44 } 45 46 bool pop(lin *&L, tree *&e) 47 { 48 que *p; 49 if(L->rear==NULL) 50 return false; 51 p=L->front; 52 if(L->rear==L->front) 53 L->front=L->rear=NULL; 54 else 55 L->front=p->next; 56 e=p->data; 57 free(p); 58 return true; 59 } 60 61 int empty(lin *&L) 62 { 63 return (L->rear==NULL); 64 } 65 66 void push(lin *&L,tree *e) 67 { 68 que *p; 69 p = (que *)malloc(sizeof(que)); 70 p->data=e; 71 p->next=NULL; 72 if(L->rear==NULL) 73 { 74 L->front=p; 75 L->rear=p; 76 } 77 else 78 { 79 L->rear->next=p; 80 L->rear=p; 81 } 82 } 83 84 void creattree(tree *&L) //先序建立二叉树 85 { 86 char c; 87 cin>>c; 88 if(c=='#') 89 L=NULL; 90 else 91 { 92 L = (tree *)malloc(sizeof(tree)) ; 93 L->date=c; 94 creattree(L->lchild); 95 creattree(L->rchild); 96 } 97 } 98 99 void find(tree *L) //找树的棵树 100 { 101 if(L!=NULL) 102 { 103 x++; 104 find(L->rchild); 105 } 106 } 107 108 void destroytree(tree *&L) //销毁树 109 { 110 if(L!=NULL) 111 { 112 destroytree(L->lchild); 113 destroytree(L->rchild); 114 free(L); 115 } 116 } 117 118 int deep(tree *L) //深度 119 { 120 int ldep,rdep,max; 121 if(L!=NULL) 122 { 123 ldep=deep(L->lchild); 124 rdep=deep(L->rchild); 125 max=ldep>rdep?ldep+1:rdep+1; 126 return max; 127 } 128 else 129 return 0; 130 } 131 132 void finddegree(tree *&L, int n) //找最大度数 133 { 134 if(L!=NULL) 135 { 136 if(x<n) 137 x=n; 138 finddegree(L->lchild,n); 139 finddegree(L->rchild,n+1); 140 } 141 142 } 143 144 void run(tree *L) //层次遍历 145 { 146 tree *p=L; 147 lin *qu; 148 Initqueue(qu); 149 if(L!=NULL) 150 push(qu,p); 151 while(!empty(qu)) 152 { 153 pop(qu,p); 154 cout<<p->date; 155 if(p->lchild!=NULL) 156 push(qu,p->lchild); 157 if(p->rchild!=NULL) 158 push(qu,p->rchild); 159 } 160 destroyed(qu); 161 } 162 163 void displayhou(tree *&L) //后序输出 164 { 165 if(L!=NULL) 166 { 167 displayhou(L->lchild); 168 displayhou(L->rchild); 169 cout<<L->date; 170 } 171 } 172 173 void displaypre(tree *&L) //先序输出 174 { 175 if(L!=NULL) 176 { 177 cout<<L->date; 178 displaypre(L->lchild); 179 displaypre(L->rchild); 180 } 181 } 182 183 void creatinpre(tree *&L ,char *in,char *pre,int x)//根据中先序确定后序 184 { 185 int k=0; 186 char *p; 187 if(x<=0) 188 { 189 L=NULL; 190 return ; 191 } 192 L=(tree *)malloc(sizeof(tree)); 193 L->date = *pre; 194 for(p=in ; p<in+x; p++) 195 { 196 if(*p==*pre) 197 break; 198 } 199 k=p-in; 200 creatinpre(L->lchild,in,pre+1,k); 201 creatinpre(L->rchild,p+1,pre+k+1,x-k-1); 202 } 203 204 void creatinhou(tree *&L ,char *in,char *pre,int x) //根据中后序确定先序 205 { 206 int k=0; 207 char *p; 208 if(x<=0) 209 { 210 L=NULL; 211 return ; 212 } 213 L=(tree *)malloc(sizeof(tree)); 214 L->date = *pre; 215 for(p=in ; p>in-x; p--) 216 { 217 if(*p==*pre) 218 break; 219 } 220 k=in-p; 221 creatinhou(L->rchild,in,pre-1,k); 222 creatinhou(L->lchild,p-1,pre-k-1,x-k-1); 223 } 224 225 void findson(tree *&L) //找指定节点的儿子 226 { 227 if(L!=NULL) 228 { 229 if(L->date==x) 230 { 231 if(L->lchild==NULL) 232 cout<<"L:#"; 233 else 234 cout<<"L:"<<L->lchild->date; 235 if(L->rchild==NULL) 236 cout<<",R:#"; 237 else 238 cout<<",R:"<<L->rchild->date; 239 return ; 240 } 241 findson(L->lchild); 242 findson(L->rchild); 243 } 244 } 245 246 void finddad(tree *&L) //找指定节点的父亲节点 247 { 248 if(L!=NULL) 249 { 250 if(L->lchild!=NULL&&L->lchild->date==x||L->rchild!=NULL&&L->rchild->date==x) 251 { 252 cout<<L->date; 253 return ; 254 } 255 256 finddad(L->lchild); 257 finddad(L->rchild); 258 } 259 } 260 261 int find_the_one_degree(tree *&L) //找寻某指定节点的度 262 { 263 if(L!=NULL) 264 { 265 if(L->date==value) 266 { 267 if(L->lchild!=NULL&&L->rchild==NULL||L->lchild==NULL&&L->rchild!=NULL) 268 return 1; 269 else if(L->lchild==NULL&&L->rchild==NULL) 270 return 0; 271 else 272 return 2; 273 } 274 find_the_one_degree(L->lchild); 275 find_the_one_degree(L->rchild); 276 } 277 } 278 279 void exchange(tree *&L) //交换左右儿子的值 280 { 281 if(L!=NULL) 282 { 283 tree *p; 284 p=L->lchild; 285 L->lchild=L->rchild; 286 L->rchild=p; 287 exchange(L->lchild); 288 exchange(L->rchild); 289 } 290 } 291 292 void displayin(tree *&L) //中序输出 293 { 294 if(L!=NULL) 295 { 296 displayin(L->lchild); 297 cout<<L->date; 298 displayin(L->rchild); 299 } 300 } 301 302 bool banlancetree(tree *&L) //平衡树 303 { 304 if(L==NULL) 305 return true; 306 int left=deep(L->lchild); 307 int right=deep(L->rchild); 308 int gas=left-right; 309 if(gas>1||gas<-1) 310 return false; 311 return banlancetree(L->lchild)&&banlancetree(L->rchild); 312 } 313 314 bool perfecttree(tree *&L,int deepth) //完全二叉树的判定 315 { 316 if(L==NULL) 317 return true; 318 if(L->rchild!=NULL&&L->lchild==NULL) 319 return false; 320 if(x-deepth>1&&L->rchild==NULL) 321 return false; 322 return perfecttree(L->lchild,deepth+1)&&perfecttree(L->rchild,deepth+1); 323 } 324 325 int main() 326 { 327 tree *L = NULL; 328 creattree(L); 329 x=deep(L); 330 if(perfecttree(L,1)) 331 cout<<"Y"; 332 else 333 cout<<"N"; 334 destroytree(L); 335 return 0; 336 }