数据结构二叉树的遍历,给了个二叉树,前序、中序、后序写出来
1 #include<iostream> 2 #include<stdio.h> 3 #include<queue> 4 #include<stack> 5 #include<malloc.h> 6 using namespace std; 7 8 //二叉树结点的描述 9 typedef struct BiTNode 10 { 11 char data; 12 struct BiTNode *lchild, *rchild; //左右孩子 13 }BiTNode,*BiTree; 14 15 //按先序遍历创建二叉树 16 //BiTree *CreateBiTree() //返回结点指针类型 17 //void CreateBiTree(BiTree &root) //引用类型的参数 18 void CreateBiTree(BiTNode **root) //二级指针作为函数参数 19 { 20 char ch; //要插入的数据 21 scanf("\n%c", &ch); 22 //cin>>ch; 23 if(ch=='#') 24 *root = NULL; 25 else 26 { 27 *root = (BiTNode *)malloc(sizeof(BiTNode)); 28 (*root)->data = ch; 29 printf("请输入%c的左孩子:",ch); 30 CreateBiTree(&((*root)->lchild)); 31 printf("请输入%c的右孩子:",ch); 32 CreateBiTree(&((*root)->rchild)); 33 } 34 } 35 36 //前序遍历的算法程序 37 void PreOrder(BiTNode *root) 38 { 39 if(root==NULL) 40 return ; 41 printf("%c ", root->data); //输出数据 42 PreOrder(root->lchild); //递归调用,前序遍历左子树 43 PreOrder(root->rchild); //递归调用,前序遍历右子树 44 } 45 46 //中序遍历的算法程序 47 void InOrder(BiTNode *root) 48 { 49 if(root==NULL) 50 return ; 51 InOrder(root->lchild); //递归调用,前序遍历左子树 52 printf("%c ", root->data); //输出数据 53 InOrder(root->rchild); //递归调用,前序遍历右子树 54 } 55 56 //后序遍历的算法程序 57 void PostOrder(BiTNode *root) 58 { 59 if(root==NULL) 60 return ; 61 PostOrder(root->lchild); //递归调用,前序遍历左子树 62 PostOrder(root->rchild); //递归调用,前序遍历右子树 63 printf("%c ", root->data); //输出数据 64 } 65 66 /* 67 二叉树的非递归前序遍历,前序遍历思想:先让根进栈,只要栈不为空,就可以做弹出操作, 68 每次弹出一个结点,记得把它的左右结点都进栈,记得右子树先进栈,这样可以保证右子树在栈中总处于左子树的下面。 69 */ 70 void PreOrder_Nonrecursive(BiTree T) //先序遍历的非递归 71 { 72 if(!T) 73 return ; 74 75 stack<BiTree> s; 76 s.push(T); 77 78 while(!s.empty()) 79 { 80 BiTree temp = s.top(); 81 cout<<temp->data<<" "; 82 s.pop(); 83 if(temp->rchild) 84 s.push(temp->rchild); 85 if(temp->lchild) 86 s.push(temp->lchild); 87 } 88 } 89 90 void PreOrder_Nonrecursive1(BiTree T) //先序遍历的非递归 91 { 92 if(!T) 93 return ; 94 stack<BiTree> s; 95 BiTree curr = T; 96 while(curr != NULL || !s.empty()) 97 { 98 while(curr != NULL) 99 { 100 cout<<curr->data<<" "; 101 s.push(curr); 102 curr = curr->lchild; 103 } 104 if(!s.empty()) 105 { 106 curr = s.top(); 107 s.pop(); 108 curr = curr->rchild; 109 } 110 } 111 } 112 113 void PreOrder_Nonrecursive2(BiTree T) //先序遍历的非递归 114 { 115 if(!T) 116 return ; 117 118 stack<BiTree> s; 119 while(T) // 左子树上的节点全部压入到栈中 120 { 121 s.push(T); 122 cout<<T->data<<" "; 123 T = T->lchild; 124 } 125 126 while(!s.empty()) 127 { 128 BiTree temp = s.top()->rchild; // 栈顶元素的右子树 129 s.pop(); // 弹出栈顶元素 130 while(temp) // 栈顶元素存在右子树,则对右子树同样遍历到最下方 131 { 132 cout<<temp->data<<" "; 133 s.push(temp); 134 temp = temp->lchild; 135 } 136 } 137 } 138 139 void InOrderTraverse1(BiTree T) // 中序遍历的非递归 140 { 141 if(!T) 142 return ; 143 BiTree curr = T; // 指向当前要检查的节点 144 stack<BiTree> s; 145 while(curr != NULL || !s.empty()) 146 { 147 while(curr != NULL) 148 { 149 s.push(curr); 150 curr = curr->lchild; 151 }//while 152 if(!s.empty()) 153 { 154 curr = s.top(); 155 s.pop(); 156 cout<<curr->data<<" "; 157 curr = curr->rchild; 158 } 159 } 160 } 161 162 void InOrderTraverse(BiTree T) // 中序遍历的非递归 163 { 164 if(!T) 165 return ; 166 stack<BiTree> s; 167 BiTree curr = T->lchild; // 指向当前要检查的节点 168 s.push(T); 169 while(curr != NULL || !s.empty()) 170 { 171 while(curr != NULL) // 一直向左走 172 { 173 s.push(curr); 174 curr = curr->lchild; 175 } 176 curr = s.top(); 177 s.pop(); 178 cout<<curr->data<<" "; 179 curr = curr->rchild; 180 } 181 } 182 183 void PostOrder_Nonrecursive1(BiTree T) // 后序遍历的非递归 184 { 185 stack<BiTree> S; 186 BiTree curr = T ; // 指向当前要检查的节点 187 BiTree previsited = NULL; // 指向前一个被访问的节点 188 while(curr != NULL || !S.empty()) // 栈空时结束 189 { 190 while(curr != NULL) // 一直向左走直到为空 191 { 192 S.push(curr); 193 curr = curr->lchild; 194 } 195 curr = S.top(); 196 // 当前节点的右孩子如果为空或者已经被访问,则访问当前节点 197 if(curr->rchild == NULL || curr->rchild == previsited) 198 { 199 cout<<curr->data<<" "; 200 previsited = curr; 201 S.pop(); 202 curr = NULL; 203 } 204 else 205 curr = curr->rchild; // 否则访问右孩子 206 } 207 } 208 209 void PostOrder_Nonrecursive(BiTree T) // 后序遍历的非递归 双栈法 210 { 211 stack<BiTree> s1 , s2; 212 BiTree curr ; // 指向当前要检查的节点 213 s1.push(T); 214 while(!s1.empty()) // 栈空时结束 215 { 216 curr = s1.top(); 217 s1.pop(); 218 s2.push(curr); 219 if(curr->lchild) 220 s1.push(curr->lchild); 221 if(curr->rchild) 222 s1.push(curr->rchild); 223 } 224 while(!s2.empty()) 225 { 226 printf("%c ", s2.top()->data); 227 s2.pop(); 228 } 229 } 230 231 232 int visit(BiTree T) 233 { 234 if(T) 235 { 236 printf("%c ",T->data); 237 return 1; 238 } 239 else 240 return 0; 241 } 242 243 void LeverTraverse(BiTree T) //方法一、非递归层次遍历二叉树 244 { 245 queue <BiTree> Q; 246 BiTree p; 247 p = T; 248 if(visit(p)==1) 249 Q.push(p); 250 while(!Q.empty()) 251 { 252 p = Q.front(); 253 Q.pop( ); 254 if(visit(p->lchild) == 1) 255 Q.push(p->lchild); 256 if(visit(p->rchild) == 1) 257 Q.push(p->rchild); 258 } 259 } 260 void LevelOrder(BiTree BT) //方法二、非递归层次遍历二叉树 261 { 262 BiTNode *queue[10];//定义队列有十个空间 263 if (BT==NULL) 264 return; 265 int front,rear; 266 front=rear=0; 267 queue[rear++]=BT; 268 while(front!=rear)//如果队尾指针不等于对头指针时 269 { 270 cout<<queue[front]->data<<" "; //输出遍历结果 271 if(queue[front]->lchild!=NULL) //将队首结点的左孩子指针入队列 272 { 273 queue[rear]=queue[front]->lchild; 274 rear++; //队尾指针后移一位 275 } 276 if(queue[front]->rchild!=NULL) 277 { 278 queue[rear]=queue[front]->rchild; //将队首结点的右孩子指针入队列 279 rear++; //队尾指针后移一位 280 } 281 front++; //对头指针后移一位 282 } 283 } 284 285 int depth(BiTNode *T) //树的深度 286 { 287 if(!T) 288 return 0; 289 int d1,d2; 290 d1=depth(T->lchild); 291 d2=depth(T->rchild); 292 return (d1>d2?d1:d2)+1; 293 //return (depth(T->lchild)>depth(T->rchild)?depth(T->lchild):depth(T->rchild))+1; 294 } 295 int CountNode(BiTNode *T) 296 { 297 if(T == NULL) 298 return 0; 299 return 1+CountNode(T->lchild)+CountNode(T->rchild); 300 } 301 302 int main(void) 303 { 304 BiTNode *root=NULL; //定义一个根结点 305 int flag=1,k; 306 printf(" 本程序实现二叉树的基本操作。\n"); 307 printf("可以进行建立二叉树,递归先序、中序、后序遍历,非递归先序、中序遍历及非递归层序遍历等操作。\n"); 308 309 while(flag) 310 { 311 printf("\n"); 312 printf("|--------------------------------------------------------------|\n"); 313 printf("| 二叉树的基本操作如下: |\n"); 314 printf("| 0.创建二叉树 |\n"); 315 printf("| 1.递归先序遍历 |\n"); 316 printf("| 2.递归中序遍历 |\n"); 317 printf("| 3.递归后序遍历 |\n"); 318 printf("| 4.非递归先序遍历 |\n"); 319 printf("| 5.非递归中序遍历 |\n"); 320 printf("| 6.非递归后序遍历 |\n"); 321 printf("| 7.非递归层序遍历 |\n"); 322 printf("| 8.二叉树的深度 |\n"); 323 printf("| 9.二叉树的结点个数 |\n"); 324 printf("| 10.退出程序 |\n"); 325 printf("|--------------------------------------------------------------|\n"); 326 printf(" 请选择功能:"); 327 scanf("%d",&k); 328 switch(k) 329 { 330 case 0: 331 printf("请建立二叉树并输入二叉树的根节点:"); 332 CreateBiTree(&root); 333 break; 334 case 1: 335 if(root) 336 { 337 printf("递归先序遍历二叉树的结果为:"); 338 PreOrder(root); 339 printf("\n"); 340 } 341 else 342 printf(" 二叉树为空!\n"); 343 break; 344 case 2: 345 if(root) 346 { 347 printf("递归中序遍历二叉树的结果为:"); 348 InOrder(root); 349 printf("\n"); 350 } 351 else 352 printf(" 二叉树为空!\n"); 353 break; 354 case 3: 355 if(root) 356 { 357 printf("递归后序遍历二叉树的结果为:"); 358 PostOrder(root); 359 printf("\n"); 360 } 361 else 362 printf(" 二叉树为空!\n"); 363 break; 364 case 4: 365 if(root) 366 { 367 printf("非递归先序遍历二叉树:"); 368 PreOrder_Nonrecursive1(root); 369 printf("\n"); 370 } 371 else 372 printf(" 二叉树为空!\n"); 373 break; 374 case 5: 375 if(root) 376 { 377 printf("非递归中序遍历二叉树:"); 378 InOrderTraverse1(root); 379 printf("\n"); 380 } 381 else 382 printf(" 二叉树为空!\n"); 383 break; 384 case 6: 385 if(root) 386 { 387 printf("非递归后序遍历二叉树:"); 388 PostOrder_Nonrecursive(root); 389 printf("\n"); 390 } 391 else 392 printf(" 二叉树为空!\n"); 393 break; 394 case 7: 395 if(root) 396 { 397 printf("非递归层序遍历二叉树:"); 398 //LeverTraverse(root); 399 LevelOrder(root); 400 printf("\n"); 401 } 402 else 403 printf(" 二叉树为空!\n"); 404 break; 405 case 8: 406 if(root) 407 printf("这棵二叉树的深度为:%d\n",depth(root)); 408 else 409 printf(" 二叉树为空!\n"); 410 break; 411 case 9: 412 if(root) 413 printf("这棵二叉树的结点个数为:%d\n",CountNode(root)); 414 else 415 printf(" 二叉树为空!\n"); 416 break; 417 default: 418 flag=0; 419 printf("程序运行结束,按任意键退出!\n"); 420 } 421 } 422 system("pause"); 423 return 0; 424 }