后缀表达式与二叉树

<span style="font-family: Arial, Helvetica, sans-serif;">#include<stdio.h></span>
#include<stdlib.h>

#define STACK_INIT_SIZE 100
#define STACKINCREMENT  10

typedef struct TreeNode{
    char *c;
    struct TreeNode *Left;
    struct TreeNode *Right;
}TreeNode;

typedef struct {
    struct TreeNode *base;
    struct TreeNode *top;
    int stacksize;
}SqStack;

SqStack InitStack(SqStack S){
    S.base = (TreeNode *)malloc(STACK_INIT_SIZE*sizeof(TreeNode));
    if(!S.base)exit(1);
    S.top = S.base;
    S.stacksize = STACK_INIT_SIZE;
    return S;
}

TreeNode GetTop(SqStack S){
    TreeNode T;
    if (S.base == S.top)return T;
    TreeNode e = *(S.top-1);
    return e ;
}

SqStack Push(SqStack S,TreeNode *e){
    if (S.top - S.base>=S.stacksize){
        S.base = (TreeNode *)realloc(S.base,(S.stacksize+STACKINCREMENT)*(sizeof(TreeNode)));
        if (!S.base)exit(1);
    }
    *(S.top) = *e;
    S.top = S.top+1;
    return S;
}

SqStack Pop(SqStack S){
    if(S.top == S.base)return S;
    S.top = S.top-1;
    return S;
}




//ab+cde+**
void MakeEmpty_tree(TreeNode *T){
    if (T!=NULL)
    {
        MakeEmpty_tree(T->Left);
        MakeEmpty_tree(T->Right);
        free(T);
    }
}

//创建某个二叉树子树
TreeNode *CreatChildTree(TreeNode *pt,TreeNode rct,TreeNode lct)
{
    printf("======创建子树========\n");
    TreeNode *RCT = (TreeNode *)malloc(STACK_INIT_SIZE*sizeof(TreeNode));
    TreeNode *LCT = (TreeNode *)malloc(STACK_INIT_SIZE*sizeof(TreeNode));
    *RCT = rct;
    *LCT = lct;
    pt->Left = LCT ;
    pt->Right = RCT;
    printf("======创建子树========\n");
    return pt;
}
//问题出在新建节点的时候,最开始把每个空的左右节点都设置为NULL了,以至于后边在赋值的时候赋值出现错乱,具体错乱成什么样子我也没有去考证,
//解决方案就是在创建一个结构体指针的时候不能根java一样设置成NULL在需要赋值的时候再直接赋值,赋值符号(=)两边的类型不符就会出错,应该是直接给他们分配一个存储空间的方式来创建空的结构体指针。(我在这里纠结了半天)。

//创建新的二叉树节点
TreeNode *CreatNewNode(char ch)
{

    TreeNode *T = (TreeNode *)malloc(STACK_INIT_SIZE*sizeof(TreeNode));;
     T->c = (char *)malloc(STACK_INIT_SIZE*sizeof(char));
     *(T->c) = ch;
     T->Left = (TreeNode *)malloc(STACK_INIT_SIZE*sizeof(TreeNode));
     T->Right = (TreeNode *)malloc(STACK_INIT_SIZE*sizeof(TreeNode));
     return T;
}

//创建表达式二叉树的实体
TreeNode *CreatNewTree(SqStack S,char *c,int n){
    int i = 0;
    int sum = 0;
    char *jia = "+";
    char *jian = "-";
    char *cheng = "*";
    char *chu = "/";
    for(i;i<n;i++,c++)
    {
        char *ch = c;
        printf("%c\n",*ch);
        sum++;
        if((*c!=*jia)&&(*c!=*jian)&&(*c!=*cheng)&&(*c!=*chu))
        {
            printf(">>>>>>>>>>>>>>>>\n");
            TreeNode *T1 ;
            T1 = CreatNewNode(*c);
            S = Push(S,T1);
            printf("栈的长度是%ld\n",S.top-S.base);
            printf("<<<<<<<<<<<<<<<<\n");
        }
        else
        {
            if((S.top-S.base)>=2)
            {
                printf(">>>>>>>>>>>>>>>>\n");
                TreeNode *PT ;
                TreeNode *PPT;
                PT = CreatNewNode(*c);
                PPT = PT;
                TreeNode CTR = GetTop(S);
                S = Pop(S);
                printf("1栈的长度是%ld\n",S.top-S.base);
                TreeNode CTL = GetTop(S);
                S = Pop(S);
                printf("2栈的长度是%ld\n",S.top-S.base);
                TreeNode *T = CreatChildTree(PPT,CTR,CTL);
                printf("子树的根节点的值是%c,左节点的值是%c,右节点的值是%c\n",*(T->c),*(T->Left->c),*(T->Right->c));
                S = Push(S,T);
                printf("3栈的长度是%ld\n",S.top-S.base);
                printf("<<<<<<<<<<<<<<<<\n");
                
                
            }
            else
            {
                printf("后缀表达式不合法\n");
                return (S.base);
            }
        }
    }
    return (S.base);
}

//经过测试创建后缀表达式的二叉树成功,这里没有考虑时间复杂度的设计,估算是O(N)级别
int main(void)
{
    int i = 9;
    char *c = "ab+cde+**";
    SqStack S ;
    S = InitStack(S);
    TreeNode *T = CreatNewTree(S,c,i);
    printf("%c\n",*(T->Right->Right->Right->c));
    system("PAUSE");
    return 0;
}

暗红色部分是有关二叉树操作的部分,黑色部分是栈操作,这里对后缀表达式和二叉树以及为什么用到栈来做一个说明


后缀表达式的概念我就不说了,就是一个表达式二叉树后续遍历的结果,这里只是集中对栈的作用说明一下,这里利用了栈的后进先出的特性。


将后缀表达式从左到右一个一个的进栈,当发现将要进栈的字符是运算符的时候,就将之前放进栈中的两个元素拿出来与那个符号组成一个子树,然后将子树进栈,这样依次类推,其实是个for循环,最后栈中只有一个元素,也就是一个TreeNode指针指向整个树


这里用的后缀表达式例子是ab+cde+**

就是(a+b)*(C*(d+e))


使用后缀表达式的一个好处就是不用考虑优先级的问题


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值