@yanglt7
2018-10-21T15:51:26.000000Z
字数 10626
阅读 792
数据结构和算法
typedef struct{ElemType *base; //指向栈底的指针变量ElemType *top; //指向栈顶的指针变量int stackSize; //栈的当前可用最大容量}sqStack;
#define STACK_INIT_SIZE 100initStack(sqStack *s){s->base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));if ( !s->base )exit(0);s->top = s->base;s->stackSize = STACK_INIT_SIZE;}
#define STACKINCREMENT 10Push(sqStack *s, ElemType e){//如果栈满,追加空间if ( s->top - s->base >= stackSize ){s->base = (ElemType *)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(ElemType));if ( !s->base )exit(0);s->top = s->base + s->stackSize; //设置栈顶s->stackSize = s->stackSize + STACKINCREMENT; //设置栈的最大容量}*(s->top) = e;s->top++;}
Pop(sqStack *s, ElemType *e){if ( s->top == s->base )return;*e = *--(s->top);}
ClearStack(sqStack *s){s->top = s->base;}
DestoryStack(sqStack *s){int i, len;len = s->stackSize;for ( i=0; i < len; i++ ){free( s->base );s->base++;}s->base = s->top = NULL;s->stackSize = 0;}
int Stacklen(sqStack s){return(s.top - s.base);}
例利用栈的数据结构特点,将二进制转换为十进制数。
#include <stdio.h>#include <stdlib.h>#include <math.h>#define STACK_INIT_SIZE 20#define STACKINCREMENT 10typedef char ElemType;typedef struct{ElemType *base;ElemType *top;int stackSize;}sqStack;void InitStack(sqStack *s){s->base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));if ( ! s->base )exit(0);s->top = s->base;s->stackSize = STACK_INIT_SIZE;}void Push(sqStack *s, ElemType e){if( s->top - s->base >= s->stackSize ){s->base = (ElemType *)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(ElemType));if ( ! s->base )exit(0);}*(s->top) = e;s->top++;}void Pop(sqStack *s, ElemType *e){if ( s->top == s->base )return;*e = *--(s->top);}int StackLen(sqStack s){return (s.top - s.base);}int main(){ElemType c;sqStack s;int len, i, sum = 0;InitStack(&s);printf("请输入二进制数,输入#符号表示结束!\n");scanf("%c", &c);while ( c != '#' ){Push(&s, c);scanf("%c", &c);}getchar(); //把'\n'从缓冲区去掉len = StackLen(s);printf("栈的当前容量是:%d\n", len);for (i=0; i<len; i++){Pop(&s, &c);sum = sum + (c-48) * pow(2, i);}printf("转换为十进制数是:%d\n", sum);return 0;}
例利用栈的数据结构特点,将二进制转换为八进制数。
#include <stdio.h>#include <stdlib.h>#include <math.h>#define STACK_INIT_SIZE 20#define STACKINCREMENT 10typedef char ElemType;typedef struct{ElemType *base;ElemType *top;int stackSize;}sqStack;void InitStack(sqStack *s){s->base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));if ( ! s->base )exit(0);s->top = s->base;s->stackSize = STACK_INIT_SIZE;}void Push(sqStack *s, ElemType e){if( s->top - s->base >= s->stackSize ){s->base = (ElemType *)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(ElemType));if ( ! s->base )exit(0);}*(s->top) = e;s->top++;}void Pop(sqStack *s, ElemType *e){if ( s->top == s->base )return;*e = *--(s->top);}int StackLen(sqStack s){return (s.top - s.base);}int main(){ElemType c,e;sqStack s, p;int len, len2, i, sum = 0;InitStack(&s);InitStack(&p);printf("请输入二进制数,输入#符号表示结束!\n");scanf("%c", &c);while ( c != '#' ){Push(&s, c);scanf("%c", &c);}getchar(); //把'\n'从缓冲区去掉len = StackLen(s);printf("栈的当前容量是:%d\n", len);int count = 0;int num = len/3;int j = 0;for (i=0; i<len; i++){j = i%3;int l = len%3;if ( num > 0 ){Pop(&s, &c);sum = sum + (c-48) * pow(2, j);count++;if ( count == 3 ){num--;Push(&p, sum);sum = 0;count = 0;}}else{Pop(&s, &c);sum = sum + (c-48) * pow(2, j);count++;if ( count == l ){Push(&p, sum);}}}len2 = StackLen(p);printf("八进制栈的当前容量是:%d\n", len2);printf("转换为八进制数是:");int k;for ( k=0; k<len2; k++ ){Pop(&p, &sum);printf("%d", sum);}printf("\n");return 0;}
typedef struct StackNode{ElemType data;//存放栈的数据struct StackNode *next;} StackNode, *LinkStackPtr;typedef struct LinkStack{LinkStackPtr top; //top指针int count; //栈元素计数器};
Status Push(LinkStack *s, ElemType e){LinkStackPtr p = (LinkStackPtr)malloc(sizeof(StackNode));p->data = e;p->next = s->top;s->top = p;s->count++;return OK;}
Status Pop(LinkStack *s, ElemType *e){LinkStackPtr p;if( StackEmpty(*s) ) //判断是否为空栈return ERROR;*e = s->top->data;p = s->top;s->top = s->top->next;free(p);s->count--;return OK;}
例 (1-2) * (4+5) = -9
| 栈顶 | ||
|---|---|---|
| 2 | --> | 栈顶 |
| 1 | -1 |
| ' | 栈顶 | |||||
|---|---|---|---|---|---|---|
| 栈顶 | 5 | 栈顶 | ||||
| 2 | --> | 栈顶 | --> | 4 | --> | 9 |
| 1 | -1 | -1 | -1 |
#include <stdio.h>#include <stdlib.h>#include <ctype.h>#define STACK_INIT_SIZE 30#define STACKINCREMENT 10#define MAXBUFFER 20typedef double ElemType;typedef struct{ElemType *base;ElemType *top;int stackSize;} sqStack;void InitStack(sqStack *s){s->top = s->base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));if ( !s->base ){exit(0);}s->base = s->top;s->stackSize = STACK_INIT_SIZE;}void Push(sqStack *s, ElemType e){if ( s->top - s->base >= s->stackSize ){s->base = (ElemType *)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(ElemType));if ( !s->base ){exit(0);}}*(s->top) = e;s->top++;}void Pop(sqStack *s, ElemType *e){if( s->base == s->top ){return;}*e = *--(s->top);}int StackLen(sqStack s){return (s.top - s.base);}int main(){sqStack s;char c;double d, e;int i = 0;char str[MAXBUFFER];InitStack( &s );printf("请按逆波兰表达式输入待计算数据,数据与运算符之间用空格隔开,以#作为结束标志: \n");scanf("%c", &c);while ( c != '#' ){while ( isdigit(c) || c == '.' ) //用于过滤数字{str[i++] = c;str[i] = '\0';if ( i >= 10 ){printf("出错:输入的单个数据过大!\n");return -1;}scanf("%c", &c);if ( c == ' '){d = atof(str); //将字符串转换为浮点数Push(&s, d);i = 0;break;}}switch( c ){case '+':Pop(&s, &e);Pop(&s, &d);Push(&s, d+e);break;case '-':Pop(&s, &e);Pop(&s, &d);Push(&s, d-e);break;case '*':Pop(&s, &e);Pop(&s, &d);Push(&s, d*e);break;case '/':Pop(&s, &e);Pop(&s, &d);if ( e != 0){Push(&s, d/e);}else{printf("出错:除数为零!\n");return -1;}break;}scanf("%c", &c);}Pop(&s, &d);printf("\n最终的计算结果为: %f\n", d);return 0;}
例 1 + (2-3) * 4 + 10/5 = -1
最后一个数字5,输出,所有的输入处理完毕,但是栈中仍有数据,所以将栈中符号依次出栈
总结规则:从左到右遍历中缀表达式的每个数字和符号,若是数字则直接输出,若是符号,则判断其与栈顶符号的优先级,是右括号或者优先级低于栈顶符号,则栈顶元素依次出栈并输出,直到遇到左括号或栈空才将后来的符号入栈。
| 输出 | 1 | 2 | 3 | - | 4 | * | + | 10 | 5 | / | + |
|---|
| ' | 栈顶 | ||||
|---|---|---|---|---|---|
| - | 栈顶 | 栈顶 | |||
| 栈顶 | ( | 栈顶 | * | 栈顶 | / |
| + | + | + | + | + | + |
#include <stdio.h>#include <stdlib.h>#define STACK_INIT_SIZE 20#define STACKINCREMENT 10typedef char ElemType;typedef struct{ElemType *base;ElemType *top;int stackSize;} sqStack;void InitStack(sqStack *s){s->top = s->base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));if( !s->base )exit(0);s->top = s->base;s->stackSize = STACK_INIT_SIZE;}void Push(sqStack *s, ElemType e){if( s->top - s->base >= STACK_INIT_SIZE ){s->base = (ElemType *)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(ElemType));if( !s->base )exit(0);}*(s->top) = e;s->top++;}void Pop(sqStack *s, ElemType *e){if( s->base == s->top )return;*e = *--(s->top);}int StackLen(sqStack s){return (s.top - s.base);}int main(){sqStack s;char c, e;InitStack( &s );printf("请输入中缀表达式,以#作为结束标志: ");scanf("%c", &c);while( c != '#' ){while( c >= '0' && c <= '9' ){printf("%c", c);scanf("%c", &c);if( c < '0' || c > '9'){printf(" ");}}if( ')' == c ){Pop(&s, &e);while( '(' != e ){printf("%c ", e);Pop(&s, &e);}}else if( '+' == c || '-' == c ){if ( !StackLen(s) ){Push(&s, c);}else{do{Pop(&s, &e);if( '(' == e ){Push(&s, e);}else{printf("%c ", e);}}while( StackLen(s) && '(' !=e );Push(&s, c);}}else if( '(' ==c || '*' == c || '/' == c ){Push(&s, c);}else if( '#' == c ){break;}else{printf("\n出错:输入格式错误!\n");return -1;}scanf("%c", &c);}while( StackLen(s) ){Pop(&s, &e);printf("%c ", e);}return 0;}
#include <stdio.h>#include <stdlib.h>#include <ctype.h>#define STACK_INIT_SIZE 30#define STACKINCREMENT 10#define MAXBUFFER 20typedef double ElemTypes;typedef char ElemType;typedef struct{ElemType *base;ElemType *top;int stackSize;} sqStack;typedef struct{ElemTypes *base;ElemTypes *top;int stackSize;} sqStacks;void InitStack(sqStack *s){s->top = s->base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));// memset(s->top, 0, STACK_INIT_SIZE * sizeof(ElemType));if ( !s->base ){exit(0);}s->base = s->top;s->stackSize = STACK_INIT_SIZE;}void InitStacks(sqStacks *s){s->top = s->base = (ElemTypes *)malloc(STACK_INIT_SIZE * sizeof(ElemTypes));// memset(s->top, 0, STACK_INIT_SIZE * sizeof(ElemTypes));if ( !s->base ){exit(0);}s->base = s->top;s->stackSize = STACK_INIT_SIZE;}void Push(sqStack *s, ElemType e){if ( s->top - s->base >= s->stackSize ){s->base = (ElemType *)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(ElemType));if ( !s->base ){exit(0);}}*(s->top) = e;s->top++;}void Pushs(sqStacks *s, ElemTypes e){if ( s->top - s->base >= s->stackSize ){s->base = (ElemTypes *)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(ElemTypes));if ( !s->base ){exit(0);}}*(s->top) = e;s->top++;}void Pop(sqStack *s, ElemType *e){if( s->base == s->top ){return;}*e = *--(s->top);}void Popp(sqStack *s, ElemType *e){if( s->base == s->top ){return;}*e = *(s->base);s->base++;}void Pops(sqStacks *s, ElemTypes *e){if( s->base == s->top ){return;}*e = *--(s->top);}int StackLen(sqStack s){return (s.top - s.base);}int StackLens(sqStacks s){return (s.top - s.base);}int main(){sqStack s, p;sqStacks q;char c, e;double d, f;char str[MAXBUFFER];InitStack( &s );InitStack( &p );InitStacks( &q );int i = 0;printf("请输入中缀表达式,以#作为结束标志: ");scanf("%c", &c);while( c != '#' ){while( c >= '0' && c <= '9' ){printf("%c", c);Push(&p, c);scanf("%c", &c);if( c < '0' || c > '9'){printf(" ");Push(&p, ' ');}}if( ')' == c ){Pop(&s, &e);while( '(' != e ){printf("%c ", e);Push(&p, e);Push(&p, ' ');Pop(&s, &e);}}else if( '+' == c || '-' == c ){if ( !StackLen(s) ){Push(&s, c);}else{do{Pop(&s, &e);if( '(' == e ){Push(&s, e);}else{printf("%c ", e);Push(&p, e);Push(&p, ' ');}}while( StackLen(s) && '(' !=e );Push(&s, c);}}else if( '(' ==c || '*' == c || '/' == c ){Push(&s, c);}else if( '#' == c ){break;}else{printf("\n出错:输入格式错误!\n");return -1;}scanf("%c", &c);}while( StackLen(s) ){Pop(&s, &e);printf("%c ", e);Push(&p, e);Push(&p, ' ');}Popp(&p, &c);int flag = 0;while ( StackLen(p) ){while ( c >= '0' && c <= '9' ){str[i++] = c;Popp(&p, &c);flag = 1;}if (flag){str[i] = '\0';d = atof(str);Pushs(&q, d);// printf("d=%f", d);i = 0;flag = 0;}switch( c ){case '+':Pops(&q, &f);Pops(&q, &d);Pushs(&q, d+f);// printf("d+f=%f ", d+f);break;case '-':Pops(&q, &f);Pops(&q, &d);Pushs(&q, d-f);// printf("d-f=%f ", d-f);break;case '*':Pops(&q, &f);Pops(&q, &d);Pushs(&q, d*f);// printf("d*f=%f ", d*f);break;case '/':Pops(&q, &f);Pops(&q, &d);if ( f != 0 ){Pushs(&q, d/f);// printf("d/f=%f ", d/f);}else{printf("出错:除数为零!\n");return -1;}break;}Popp(&p, &c);}Pops(&q, &d);printf("\n最终的计算结果为: %f\n", d);return 0;}