二叉树操作

#include"stdio.h"
#include"stdlib.h"
#include<iostream>
#include<queue>
#include<cmath>
using namespace std;
typedef struct BiNode
{
    char data;
    struct BiNode *lchild,*rchild;
} BiTNode,*BiTree;
#define maxsize 100
int figure;
char result[1000]= {0};
char  menuselect()
{
    printf("******************************二叉树表功能菜单******************************\n");
    printf("*  a: 创建二叉树法1                           b:创建二叉树法2             *\n");
    printf("*  c: 创建二叉树法3                           d:创建二叉树法4             *\n");
    printf("*  e: 创建二叉树法5                           f:先序递归遍历              *\n");
    printf("*  g: 中序递归遍历                            h:后续递归遍历              *\n");
    printf("*  i: 层次遍历                                j:先续非递归遍历            *\n");
    printf("*  k: 中续非递归遍历                          l:后续非递归遍历            *\n");
    printf("*  m: 计算二叉树的高度                        n:计算二叉树中叶结点个数    *\n");
    printf("*  o: 交换二叉树的左右子树                    p:打印二叉树(凹入式)        *\n");
    printf("*  q: 打印二叉树(广义表)                      r:打印二叉树(树形)          *\n");
    printf("****************************************************************************\n");
    printf("请输入您的选择\n");
}
void CreateBiTree(BiTree &T)
{
    char ch;
    cin>>ch;
    if(ch=='#')
    {
        T=NULL;
        figure++;
    }
    else
    {
        T=(BiTNode *)malloc(sizeof(BiTNode));
        T->data=ch;
        figure++;
        CreateBiTree(T->lchild);
        CreateBiTree(T->rchild);
    }
}
int treecreate2(BiTree &bt)
{
    BiTree p,v[100];
    int i,j;
    char ch;
    cin>>i;
    cin>>ch;
    while(i!=0&&ch!='#')
    {
        p=(BiTree)malloc(sizeof(BiTNode));
        if(!(p))return 0;
        p->data=ch;
        p->lchild=NULL;
        p->rchild=NULL;
        v[i]=p;
        if(i==1)
            bt=p;
        else
        {
            j=i/2;
            if(i%2==0)v[j]->lchild=p;
            else
                v[j]->rchild=p;
        }
        cout<<"请继续输入二叉树各个结点的编号和对应的值,其中#为结束"<<endl;
        cin>>i;
        cin>>ch;
    }
    return 1;
}
//树创建法3--广义表利用括号嵌套的字符串建立二叉链表*/
void  treecreate3(BiTree &T,char *str)
{
    char ch;
    BiTree stack[10000];			/*定义栈,用于存放指向二叉树中结点的指针*/
    int top=-1;						/*初始化栈顶指针*/
    int flag,k;
    BiNode *p=NULL;
    T=NULL,k=0;
    ch=str[k];
    while(ch!='\0')					/*如果字符串没有结束*/
    {
        switch(ch)
        {
        case '(':
            stack[++top]=p;//把已创建的指针作为双亲结点入栈
            flag=1;//左孩子
            break;
        case ')'://左孩子和右孩子都处理完毕
            top--;
            break;
        case ','://右孩子
            flag=2;
            break;
        default://创建一个结点
            p=(BiTree)malloc(sizeof(BiNode));
            p->data=ch;
            p->lchild=NULL;
            p->rchild=NULL;
            if(T==NULL)		/*如果是第一个结点,表示是根结点*/
                T=p;
            else
            {
                switch(flag)
                {
                case 1:
                    stack[top]->lchild=p;
                    break;
                case 2:
                    stack[top]->rchild=p;
                    break;
                }
            }
        }//switch
        ch=str[++k];
    }//while

}//end
BiTree treecreate4(char *p,char *m,int len)        //根据先序序列和中序序列创建二叉树;
{
//*P存放先序序列,*m存放中序序列,len为m中字符个数;
    BiTree s;
    char *q;
    int k;
    if(len<=0)   return NULL;
    s=(BiTree)malloc(sizeof(BiNode));   //创建二叉树结点s;
    s->data=*p;
    for(q=m; q<m+len; q++)     //在中序序列中找等于*p的位置k;
    {
        if(*q==*p)
            break;
    }
    k=q-m;
    s->lchild=treecreate4(p+1,m,k);              //递归构造左子树;
    s->rchild=treecreate4(p+k+1,q+1,len-k-1);     //递归构造右子树;
    return s;
}
void PreOrderTraverse(BiTree T)
{
    if(T)
    {
        printf("%c",T->data);
        PreOrderTraverse(T->lchild);
        PreOrderTraverse(T->rchild);
    }
}
void  InOrderTraverse(BiTree T)
{
    if(T)
    {
        InOrderTraverse(T->lchild);
        printf("%c",T->data);
        InOrderTraverse(T->rchild);
    }
}
void  PostOrderTraverse(BiTree T)
{
    if(T)
    {
        PostOrderTraverse(T->lchild);
        PostOrderTraverse(T->rchild);
        printf("%c",T->data);
    }
}
void preOrderTraverse1(BiTree t)  /*非递归实现二叉树的前序遍历*/
{
    BiTree s[10000];			/*定义栈,用于存放指向二叉树中结点的指针*/
    int top=-1;
    while ((t) || (top!=-1))/*当前处理的子树不为空或栈不为空则循环*/
    {
        while (t)
        {
            cout<<t->data;
            top++;
            s[top]=t;
            t=t->lchild;
        }
        if (top>-1)
        {
            t=s[top];
            top--;
            t=t->rchild;
        }
    }
}
void preOrderTraverse2(BiTree t)  /*非递归实现二叉树的中序遍历*/
{
    BiTree s[10000];			/*定义栈,用于存放指向二叉树中结点的指针*/
    int top=-1;
    while ((t) || (top!=-1))/*当前处理的子树不为空或栈不为空则循环*/
    {
        while (t)
        {
            top++;
            s[top]=t;
            t=t->lchild;
        }
        if (top>-1)
        {
            t=s[top];
            cout<<t->data;
            top--;
            t=t->rchild;
        }
    }
}
void preOrderTraverse3(BiTree t)  /*非递归实现二叉树的后序遍历*/
{
    BiTree s[10000];			/*定义栈,用于存放指向二叉树中结点的指针*/
    int tag[100000]= {0},top=-1;
    while ((t) || (top!=-1))/*当前处理的子树不为空或栈不为空则循环*/
    {
        while (t)
        {
            top++;
            s[top]=t;
            tag[top]=0;
            t=t->lchild;
        }
        while((top>-1)&&(tag[top]==1))
        {
            t=s[top];
            cout<<t->data;
            top--;
        }
        if(top>-1)
        {
            t=s[top];
            t=t->rchild;
            tag[top]=1;
        }
        else
            t=NULL;
    }
}
void LevelOrderTraverse(BiTree T)
{
    queue<BiTree>que;
    BiTree p;
    p=T;
    que.push(p);
    while(!que.empty())
    {
        p=que.front();
        que.pop();
        cout<<p->data<<" ";
        if(p->lchild != NULL) que.push(p->lchild);
        if(p->rchild != NULL) que.push(p->rchild);
    }
}
int Height(BiTree t)
{
    if(!t)return 0;
    int hl,hr;
    hl=Height(t->lchild);
    hr=Height(t->rchild);
    return hl>hr?hl+1:hr+1;
}
//打印树(凹入式)
void print_btree1(BiTree r,int l)
{
    int i;

    if (r ==NULL) return ;

    print_btree1(r->rchild,l+1);

    for(i=0; i<l; i++)    cout<<"  ";
    if(l>=0)
    {
        cout<<"_";
        cout<<r->data<<endl;
    }
    print_btree1(r->lchild,l+1);

}
//打印树(广义表)
/*1)打印根节点,若其还有孩子,就输出(;
  2)若有左孩子,则递归左子树;
  3)若还有右孩子,则先打印“,”,区分左右孩子,再递归右子树,输出“)”,表示输出完毕*/
void print_btree2(BiTree bt)
{
    if(bt!=NULL)
    {
        cout<<bt->data;
        if(bt->lchild!=NULL||bt->rchild!=NULL)
        {
            cout<<"(";
            print_btree2(bt->lchild);
            if(bt->rchild!=NULL)		cout<<",";
            print_btree2(bt->rchild);
            cout<<")";
        }
    }
}
//打印树(树形)
void print_btree3(BiTree t)//画二叉树实现
{
    BiTree s[maxsize];
    int f,r;
    f=r=-1;
    BiTree p,q;
    q=(BiTree)malloc(sizeof(BiNode));
    q->data='#';
    q->lchild=q->rchild=NULL;
    p=t;
    if(p)
    {
        r=(r+1)%maxsize;
        s[r]=p;
    }//入队
    for(int i=0; i<figure; i++)
    {
        {
            f=(f+1)%maxsize;
            p=s[f];
        }//出队;
        result[i]=p->data;
        if(p)
        {
            if(p->lchild)
            {
                r=(r+1)%maxsize;
                s[r]=p->lchild;
            }//入队
            else
            {
                r=(r+1)%maxsize;
                s[r]=q;
            }//入队
            if(p->rchild)
            {
                r=(r+1)%maxsize;
                s[r]=p->rchild;
            }//入队
            else
            {
                r=(r+1)%maxsize;
                s[r]=q;
            }//入队
        }//if
    }//for
}
int lever=1,r=0;
void menu(void)
{
    BiTree T;
    T=NULL;
    char str[100000];
    char k;
    for(;;)
    {
        menuselect();
        cin>>k;
        switch (k)
        {
        case 'a':
        {
            cout<<"请按照先序遍历输入二叉树各个结点值,其中'#'代表空ABCD###EF##G##HIJ##K##L#M##"<<endl;
            CreateBiTree(T);
        }
        break;
        case 'b':
        {
            cout<<"请输入二叉树各个结点的编号和对应的值,其中0 #为结束1A2B3C4D5E8F"<<endl;
            treecreate2(T);
        }
        break;
        case 'c':
        {
            cout<<"请按照广义表输入二叉树各个结点值(a(b(c,d),e(f(,g),h(i)))"<<endl;
            cin>>str;
            treecreate3(T,str);
        }
        break;
        case 'f':
        {
            printf("前序遍历结果:\n");
            PreOrderTraverse(T);
            printf("\n");
        }
        break;
        case 'g':
            printf("中序遍历结果:\n");
            {
                InOrderTraverse(T);
                printf("\n");
            }
            break;
        case 'h':
        {
            printf("后序遍历结果:\n");
            PostOrderTraverse(T);
            printf("\n");
        }
        break;
        case 'i':
        {
            printf("层次遍历结果:\n");
            LevelOrderTraverse(T);
            printf("\n");
        }
        break;
        case 'j':
        {
            printf("前序遍历结果:\n");
            preOrderTraverse1(T);
            printf("\n");
        }
        break;
        case 'k':
            printf("中序遍历结果:\n");
            {
                preOrderTraverse2(T);
                printf("\n");
            }
            break;
        case 'l':
        {
            printf("后序遍历结果:\n");
            preOrderTraverse3(T);
            printf("\n");
        }
        break;
        case 'm':
        {
            printf("二叉树的高度为:\n");
            int h=Height(T);
            printf("%d",h);
            printf("\n");
        }
        break;
        case 'n':
        {
            printf("二叉树的高度为:\n");
            int h=Height(T);
            printf("%d",h);
            printf("\n");
        }
        break;
        case 'o':
        {
            printf("二叉树的高度为:\n");
            int h=Height(T);
            printf("%d",h);
            printf("\n");
        }
        break;
        case 'p':
        {
            cout<<"打印树(凹入式):"<<endl;
            printf("\n");
            print_btree1(T,0);
            printf("\n");
        }
        break;
        case 'q':
        {
            print_btree2(T);
            printf("\n");
            break;
        }
        break;
        case 'r':
        {
            print_btree3(T);
            int h=Height(T);
            cout<<"建立完全二叉树的顺序存储结构为"<<endl;
            cout<<result<<endl;
            while(lever<=h)//控制输出
            {
                for(int i=0; i<pow((float)2,h-lever); i++)
                    cout<<" ";//控制每行开头的空格
                for(int j=0; j<pow((float)2,lever-1); j++,r++) //控制每行输出个数
                {
                    if(result[r]!='#')
                        cout<<result[r];
                    else
                        cout<<" ";
                    for(int k=0; k<pow((float)2,h-lever+1)-1; k++)
                        cout<<" ";//每行内部空格控制
                }
                cout<<endl;
                lever++;
            }
            break;
        }
        break;
        case 'z':
            cout<<" 再见!"<<endl;
            return ;
        }
    }
}
int main()
{
    int k;
    menu();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值