二叉树递归遍历(先,中,后),非递归遍历(先,中,后) (数据结构作业)
数据结构实验:
(1)采用下列方法之一建立二叉树的二叉链表:
① 输入完全二叉树的先序序列,用#代表虚结点(空指针),如ABD###CE##F##,建立二叉树的二叉链表。
② 已知二叉树的先序遍历序列和中序遍历序列,或者已知二叉树的中序遍历序列和后序遍历序列,建立二叉树的二叉链表。
③ 将一棵二叉树的所有结点存储在一维数组中,虚结点用#表示,利用二叉树的性质5,建立二叉树的二叉链表。例如用数组a存储的二叉树的结点如下(0单元不用):
(2)写出对用二叉链表存储的二叉树进行先序、中序和后序遍历的递归和非递归算法。
(3)写出对用二叉链表存储的二叉树进行层次遍历算法。
(4)求二叉树的所有叶子及结点总数。
【持续更新 ing】
【已完成】:先序建立二叉树, 已知先序和中序建立二叉树
对二叉树进行 递归非递归遍历
【思路】
递归思路很清晰l; 对于非递归和层次遍历,自己构造 栈和队列 模拟实现, 后序非递归 较麻烦
【代码实现】
FIN 文件 input 里面的内容为:
ABD###CE##F##
ABDCEF
DBAECF
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <queue> #include <stack> #include <string.h> #include <bits/stdc++.h> #include <algorithm> #define FIN freopen("input.txt","r",stdin) #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; /* (1)采用下列方法之一建立二叉树的二叉链表: ① 输入完全二叉树的先序序列,用#代表虚结点(空指针),如ABD###CE##F##,建立二叉树的二叉链表。 ② 已知二叉树的先序遍历序列和中序遍历序列,或者已知二叉树的中序遍历序列和后序遍历序列,建立二叉树的二叉链表。 ③ 将一棵二叉树的所有结点存储在一维数组中,虚结点用#表示,利用二叉树的性质5,建立二叉树的二叉链表。例如用数组a存储的二叉树的结点如下(0单元不用): (2)写出对用二叉链表存储的二叉树进行先序、中序和后序遍历的递归和非递归算法。 (3)写出对用二叉链表存储的二叉树进行层次遍历算法。 (4)求二叉树的所有叶子及结点总数。 */ const int MAX=1200; const int n=120; const int nn=120; typedef struct Node{ char x; struct Node *lson,*rson; }Tree,*BiTree; typedef struct Queue{ //自己构造队列 char a[12000]; int front; int rear; void Initqueue() { front=rear=0; } int length() { return (rear-front +MAX)%MAX; } bool emptys() { if(front==rear) return 1; return 0; } void Push_back(char str) { if((rear+1)%MAX==front) return; a[rear]=str; rear=(rear+1)%MAX; } char Getfront() { if(front==rear) return '?'; char st; st= a[front]; front=(front+1)%MAX; return st; } }queues; typedef struct Stack{ // 自己构造栈 BiTree *tt; int top; int size; void InitStack() { tt= ( BiTree *)malloc(n*sizeof(Tree)); top=0; size=n; } bool emptys() { if(top==0) return true; return false; } void Push_back(BiTree num) { tt[top++]=num; } void Pop() { if(top==0)return; top--; //num=x[--top]; } BiTree Gettop() { if(top==0) return NULL; return tt[top-1];// top } }stacks; void build_frist(BiTree &T) // 先序建立 { char ch; scanf("%c",&ch); if(ch=='#') T=NULL; else { T= new Tree ; T->x=ch; build_frist(T->lson); build_frist(T->rson); } } void query(BiTree T,int oper) {// 三种递归 先序中序与后序 if(T) { if(oper==1) printf("%c ",T->x); query(T->lson,oper); if(oper==2) printf("%c ",T->x); query(T->rson,oper); if(oper==3) printf("%c ",T->x); } } void build(BiTree &T,char *Fi,char *In,int n) // 已知先序和中序 建立二叉树 { if(n<1) { T=NULL; return; } int i=0,l1=0,l2=0,p=0,m=0; char lson[120],rson[120]; char str1[120],str2[120]; mem(lson,0); mem(rson,0); T= new Tree; T->x=Fi[0]; while(In[i]!=Fi[0]) i++; l1=i; l2=n-i-1; int temp=i; for(int j=1;j<=temp;j++) lson[j-1]=Fi[j]; for(int j=temp+1;j<n;j++) { rson[j-temp-1]=Fi[j]; str2[j-temp-1]=In[j]; } for(int j=0;j<temp;j++) str1[j]=In[j]; if(!lson[0]) T->lson=NULL; else build(T->lson,lson,str1,l1); if(!rson[0]) T->rson=NULL; else build(T->rson,rson,str2,l2); } void query_frist(BiTree T) // 非递归先序 { stacks S; S.InitStack(); S.Push_back(T); while(!S.emptys()) { while(S.Gettop()!=NULL) { printf("%c ",S.Gettop()->x); S.Push_back(S.Gettop()->lson); } S.Pop(); if(!S.emptys()) { BiTree Temp; Temp=S.Gettop(); S.Pop(); S.Push_back(Temp->rson); } } } void query_mid(BiTree T) // 非递归中序 { stacks S; S.InitStack(); S.Push_back(T); while(!S.emptys()) { while(S.Gettop()!=NULL) { S.Push_back(S.Gettop()->lson); } S.Pop(); if(!S.emptys()) { BiTree Temp; Temp=S.Gettop(); printf("%c ",Temp->x); S.Pop(); S.Push_back(Temp->rson); } } } void query_last(BiTree T) // 非递归后序 { stacks S; S.InitStack(); S.Push_back(T); while(!S.emptys()) { while(S.Gettop()!=NULL) { S.Push_back(S.Gettop()->lson); } S.Pop(); if(!S.emptys()) { if(S.Gettop()->rson) S.Push_back(S.Gettop()->rson); else { BiTree Temp; Temp=S.Gettop(); printf("%c ",Temp->x); S.Pop(); while(S.Gettop()!=NULL&&!S.emptys()&&S.Gettop()->rson==Temp) { printf("%c ",S.Gettop()->x); Temp=S.Gettop(); S.Pop(); } if(!S.emptys()) { S.Push_back(S.Gettop()->rson); } } } } } void frist_and_mid() // 已知先序和中序 调用函数 构造二叉树 { cout<<"*****************************"<<endl; BiTree T2; char str1[120],str2[120],str3[120]; printf("input of the first :\n"); scanf("%s",str1); printf("input of the mid :\n"); scanf("%s",str2); int len=strlen(str1); build(T2,str1,str2,len); printf("构造的二叉树 后序遍历为: \n"); query(T2,3); cout<<"\n*****************************"<<endl; } int main() { FIN; BiTree T; build_frist(T); printf("递归遍历 先序 中序 后序 依次为:\n"); for(int i=1;i<=3;i++) { query(T,i);//1 先序,2中序,3后序 cout<<endl; } frist_and_mid(); printf("非递归先序:\n"); query_frist(T); printf("\n非递归中序:\n"); query_mid(T); printf("\n非递归后序:\n"); query_last(T); return 0; }
【测试结果】
FIN input 文件内容为:
ABD###CE##F##
ABDCEF
DBAECF
岂曰无衣?与子同袍。王于兴师,修我戈矛。与子同仇!
岂曰无衣?与子同泽。王于兴师,修我矛戟。与子偕作!
岂曰无衣?与子同裳。王于兴师,修我甲兵。与子偕行!