二叉树操作

来源:互联网 发布:mmd undefined动作数据 编辑:程序博客网 时间:2024/06/05 16:58
#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 100int 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}//endBiTree 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();}

原创粉丝点击