<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))
使用后缀表达式的一个好处就是不用考虑优先级的问题