二叉树递归遍历(先,中,后),非递归遍历(先,中,后) (数据结构作业)


数据结构实验:


(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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值