[关闭]
@yanglt7 2018-10-21T15:51:26.000000Z 字数 10626 阅读 703

04_栈

数据结构和算法


4.1 栈的定义

4.2 栈的插入和删除操作

4.3 栈的顺序存储结构

  1. typedef struct
  2. {
  3. ElemType *base; //指向栈底的指针变量
  4. ElemType *top; //指向栈顶的指针变量
  5. int stackSize; //栈的当前可用最大容量
  6. }sqStack;

4.3.1 创建一个栈

  1. #define STACK_INIT_SIZE 100
  2. initStack(sqStack *s)
  3. {
  4. s->base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));
  5. if ( !s->base )
  6. exit(0);
  7. s->top = s->base;
  8. s->stackSize = STACK_INIT_SIZE;
  9. }

4.3.2 入栈操作

  1. #define STACKINCREMENT 10
  2. Push(sqStack *s, ElemType e)
  3. {
  4. //如果栈满,追加空间
  5. if ( s->top - s->base >= stackSize )
  6. {
  7. s->base = (ElemType *)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(ElemType));
  8. if ( !s->base )
  9. exit(0);
  10. s->top = s->base + s->stackSize; //设置栈顶
  11. s->stackSize = s->stackSize + STACKINCREMENT; //设置栈的最大容量
  12. }
  13. *(s->top) = e;
  14. s->top++;
  15. }

4.3.3 出栈操作

  1. Pop(sqStack *s, ElemType *e)
  2. {
  3. if ( s->top == s->base )
  4. return;
  5. *e = *--(s->top);
  6. }

4.3.4 清空一个栈

  1. ClearStack(sqStack *s)
  2. {
  3. s->top = s->base;
  4. }

4.3.5 销毁一个栈

  1. DestoryStack(sqStack *s)
  2. {
  3. int i, len;
  4. len = s->stackSize;
  5. for ( i=0; i < len; i++ )
  6. {
  7. free( s->base );
  8. s->base++;
  9. }
  10. s->base = s->top = NULL;
  11. s->stackSize = 0;
  12. }

4.3.6 计算栈的当前容量

  1. int Stacklen(sqStack s)
  2. {
  3. return(s.top - s.base);
  4. }

4.3.7 实例分析

利用栈的数据结构特点,将二进制转换为十进制数。

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. #define STACK_INIT_SIZE 20
  5. #define STACKINCREMENT 10
  6. typedef char ElemType;
  7. typedef struct
  8. {
  9. ElemType *base;
  10. ElemType *top;
  11. int stackSize;
  12. }sqStack;
  13. void InitStack(sqStack *s)
  14. {
  15. s->base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));
  16. if ( ! s->base )
  17. exit(0);
  18. s->top = s->base;
  19. s->stackSize = STACK_INIT_SIZE;
  20. }
  21. void Push(sqStack *s, ElemType e)
  22. {
  23. if( s->top - s->base >= s->stackSize )
  24. {
  25. s->base = (ElemType *)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(ElemType));
  26. if ( ! s->base )
  27. exit(0);
  28. }
  29. *(s->top) = e;
  30. s->top++;
  31. }
  32. void Pop(sqStack *s, ElemType *e)
  33. {
  34. if ( s->top == s->base )
  35. return;
  36. *e = *--(s->top);
  37. }
  38. int StackLen(sqStack s)
  39. {
  40. return (s.top - s.base);
  41. }
  42. int main()
  43. {
  44. ElemType c;
  45. sqStack s;
  46. int len, i, sum = 0;
  47. InitStack(&s);
  48. printf("请输入二进制数,输入#符号表示结束!\n");
  49. scanf("%c", &c);
  50. while ( c != '#' )
  51. {
  52. Push(&s, c);
  53. scanf("%c", &c);
  54. }
  55. getchar(); //把'\n'从缓冲区去掉
  56. len = StackLen(s);
  57. printf("栈的当前容量是:%d\n", len);
  58. for (i=0; i<len; i++)
  59. {
  60. Pop(&s, &c);
  61. sum = sum + (c-48) * pow(2, i);
  62. }
  63. printf("转换为十进制数是:%d\n", sum);
  64. return 0;
  65. }

利用栈的数据结构特点,将二进制转换为八进制数。

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. #define STACK_INIT_SIZE 20
  5. #define STACKINCREMENT 10
  6. typedef char ElemType;
  7. typedef struct
  8. {
  9. ElemType *base;
  10. ElemType *top;
  11. int stackSize;
  12. }sqStack;
  13. void InitStack(sqStack *s)
  14. {
  15. s->base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));
  16. if ( ! s->base )
  17. exit(0);
  18. s->top = s->base;
  19. s->stackSize = STACK_INIT_SIZE;
  20. }
  21. void Push(sqStack *s, ElemType e)
  22. {
  23. if( s->top - s->base >= s->stackSize )
  24. {
  25. s->base = (ElemType *)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(ElemType));
  26. if ( ! s->base )
  27. exit(0);
  28. }
  29. *(s->top) = e;
  30. s->top++;
  31. }
  32. void Pop(sqStack *s, ElemType *e)
  33. {
  34. if ( s->top == s->base )
  35. return;
  36. *e = *--(s->top);
  37. }
  38. int StackLen(sqStack s)
  39. {
  40. return (s.top - s.base);
  41. }
  42. int main()
  43. {
  44. ElemType c,e;
  45. sqStack s, p;
  46. int len, len2, i, sum = 0;
  47. InitStack(&s);
  48. InitStack(&p);
  49. printf("请输入二进制数,输入#符号表示结束!\n");
  50. scanf("%c", &c);
  51. while ( c != '#' )
  52. {
  53. Push(&s, c);
  54. scanf("%c", &c);
  55. }
  56. getchar(); //把'\n'从缓冲区去掉
  57. len = StackLen(s);
  58. printf("栈的当前容量是:%d\n", len);
  59. int count = 0;
  60. int num = len/3;
  61. int j = 0;
  62. for (i=0; i<len; i++)
  63. {
  64. j = i%3;
  65. int l = len%3;
  66. if ( num > 0 )
  67. {
  68. Pop(&s, &c);
  69. sum = sum + (c-48) * pow(2, j);
  70. count++;
  71. if ( count == 3 )
  72. {
  73. num--;
  74. Push(&p, sum);
  75. sum = 0;
  76. count = 0;
  77. }
  78. }
  79. else
  80. {
  81. Pop(&s, &c);
  82. sum = sum + (c-48) * pow(2, j);
  83. count++;
  84. if ( count == l )
  85. {
  86. Push(&p, sum);
  87. }
  88. }
  89. }
  90. len2 = StackLen(p);
  91. printf("八进制栈的当前容量是:%d\n", len2);
  92. printf("转换为八进制数是:");
  93. int k;
  94. for ( k=0; k<len2; k++ )
  95. {
  96. Pop(&p, &sum);
  97. printf("%d", sum);
  98. }
  99. printf("\n");
  100. return 0;
  101. }

4.4 栈的链式存储结构

  1. typedef struct StackNode
  2. {
  3. ElemType data;//存放栈的数据
  4. struct StackNode *next;
  5. } StackNode, *LinkStackPtr;
  6. typedef struct LinkStack
  7. {
  8. LinkStackPtr top; //top指针
  9. int count; //栈元素计数器
  10. };

4.4.1 进栈操作

  1. Status Push(LinkStack *s, ElemType e)
  2. {
  3. LinkStackPtr p = (LinkStackPtr)malloc(sizeof(StackNode));
  4. p->data = e;
  5. p->next = s->top;
  6. s->top = p;
  7. s->count++;
  8. return OK;
  9. }

4.4.2 出栈操作

  1. Status Pop(LinkStack *s, ElemType *e)
  2. {
  3. LinkStackPtr p;
  4. if( StackEmpty(*s) ) //判断是否为空栈
  5. return ERROR;
  6. *e = s->top->data;
  7. p = s->top;
  8. s->top = s->top->next;
  9. free(p);
  10. s->count--;
  11. return OK;
  12. }

4.4.3 逆波兰表达式

(1-2) * (4+5) = -9

栈顶
2 --> 栈顶
1 -1
' 栈顶
栈顶 5 栈顶
2 --> 栈顶 --> 4 --> 9
1 -1 -1 -1
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <ctype.h>
  4. #define STACK_INIT_SIZE 30
  5. #define STACKINCREMENT 10
  6. #define MAXBUFFER 20
  7. typedef double ElemType;
  8. typedef struct
  9. {
  10. ElemType *base;
  11. ElemType *top;
  12. int stackSize;
  13. } sqStack;
  14. void InitStack(sqStack *s)
  15. {
  16. s->top = s->base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));
  17. if ( !s->base )
  18. {
  19. exit(0);
  20. }
  21. s->base = s->top;
  22. s->stackSize = STACK_INIT_SIZE;
  23. }
  24. void Push(sqStack *s, ElemType e)
  25. {
  26. if ( s->top - s->base >= s->stackSize )
  27. {
  28. s->base = (ElemType *)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(ElemType));
  29. if ( !s->base )
  30. {
  31. exit(0);
  32. }
  33. }
  34. *(s->top) = e;
  35. s->top++;
  36. }
  37. void Pop(sqStack *s, ElemType *e)
  38. {
  39. if( s->base == s->top )
  40. {
  41. return;
  42. }
  43. *e = *--(s->top);
  44. }
  45. int StackLen(sqStack s)
  46. {
  47. return (s.top - s.base);
  48. }
  49. int main()
  50. {
  51. sqStack s;
  52. char c;
  53. double d, e;
  54. int i = 0;
  55. char str[MAXBUFFER];
  56. InitStack( &s );
  57. printf("请按逆波兰表达式输入待计算数据,数据与运算符之间用空格隔开,以#作为结束标志: \n");
  58. scanf("%c", &c);
  59. while ( c != '#' )
  60. {
  61. while ( isdigit(c) || c == '.' ) //用于过滤数字
  62. {
  63. str[i++] = c;
  64. str[i] = '\0';
  65. if ( i >= 10 )
  66. {
  67. printf("出错:输入的单个数据过大!\n");
  68. return -1;
  69. }
  70. scanf("%c", &c);
  71. if ( c == ' ')
  72. {
  73. d = atof(str); //将字符串转换为浮点数
  74. Push(&s, d);
  75. i = 0;
  76. break;
  77. }
  78. }
  79. switch( c )
  80. {
  81. case '+':
  82. Pop(&s, &e);
  83. Pop(&s, &d);
  84. Push(&s, d+e);
  85. break;
  86. case '-':
  87. Pop(&s, &e);
  88. Pop(&s, &d);
  89. Push(&s, d-e);
  90. break;
  91. case '*':
  92. Pop(&s, &e);
  93. Pop(&s, &d);
  94. Push(&s, d*e);
  95. break;
  96. case '/':
  97. Pop(&s, &e);
  98. Pop(&s, &d);
  99. if ( e != 0)
  100. {
  101. Push(&s, d/e);
  102. }
  103. else
  104. {
  105. printf("出错:除数为零!\n");
  106. return -1;
  107. }
  108. break;
  109. }
  110. scanf("%c", &c);
  111. }
  112. Pop(&s, &d);
  113. printf("\n最终的计算结果为: %f\n", d);
  114. return 0;
  115. }

4.4.4 中缀表达式转换为后缀表达式

1 + (2-3) * 4 + 10/5 = -1

输出 1 2 3 - 4 * + 10 5 / +
' 栈顶
- 栈顶 栈顶
栈顶 ( 栈顶 * 栈顶 /
+ + + + + +
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define STACK_INIT_SIZE 20
  4. #define STACKINCREMENT 10
  5. typedef char ElemType;
  6. typedef struct
  7. {
  8. ElemType *base;
  9. ElemType *top;
  10. int stackSize;
  11. } sqStack;
  12. void InitStack(sqStack *s)
  13. {
  14. s->top = s->base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));
  15. if( !s->base )
  16. exit(0);
  17. s->top = s->base;
  18. s->stackSize = STACK_INIT_SIZE;
  19. }
  20. void Push(sqStack *s, ElemType e)
  21. {
  22. if( s->top - s->base >= STACK_INIT_SIZE )
  23. {
  24. s->base = (ElemType *)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(ElemType));
  25. if( !s->base )
  26. exit(0);
  27. }
  28. *(s->top) = e;
  29. s->top++;
  30. }
  31. void Pop(sqStack *s, ElemType *e)
  32. {
  33. if( s->base == s->top )
  34. return;
  35. *e = *--(s->top);
  36. }
  37. int StackLen(sqStack s)
  38. {
  39. return (s.top - s.base);
  40. }
  41. int main()
  42. {
  43. sqStack s;
  44. char c, e;
  45. InitStack( &s );
  46. printf("请输入中缀表达式,以#作为结束标志: ");
  47. scanf("%c", &c);
  48. while( c != '#' )
  49. {
  50. while( c >= '0' && c <= '9' )
  51. {
  52. printf("%c", c);
  53. scanf("%c", &c);
  54. if( c < '0' || c > '9')
  55. {
  56. printf(" ");
  57. }
  58. }
  59. if( ')' == c )
  60. {
  61. Pop(&s, &e);
  62. while( '(' != e )
  63. {
  64. printf("%c ", e);
  65. Pop(&s, &e);
  66. }
  67. }
  68. else if( '+' == c || '-' == c )
  69. {
  70. if ( !StackLen(s) )
  71. {
  72. Push(&s, c);
  73. }
  74. else
  75. {
  76. do
  77. {
  78. Pop(&s, &e);
  79. if( '(' == e )
  80. {
  81. Push(&s, e);
  82. }
  83. else
  84. {
  85. printf("%c ", e);
  86. }
  87. }while( StackLen(s) && '(' !=e );
  88. Push(&s, c);
  89. }
  90. }
  91. else if( '(' ==c || '*' == c || '/' == c )
  92. {
  93. Push(&s, c);
  94. }
  95. else if( '#' == c )
  96. {
  97. break;
  98. }
  99. else
  100. {
  101. printf("\n出错:输入格式错误!\n");
  102. return -1;
  103. }
  104. scanf("%c", &c);
  105. }
  106. while( StackLen(s) )
  107. {
  108. Pop(&s, &e);
  109. printf("%c ", e);
  110. }
  111. return 0;
  112. }

4.4.5 输入中缀表达式计算出结果

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <ctype.h>
  4. #define STACK_INIT_SIZE 30
  5. #define STACKINCREMENT 10
  6. #define MAXBUFFER 20
  7. typedef double ElemTypes;
  8. typedef char ElemType;
  9. typedef struct
  10. {
  11. ElemType *base;
  12. ElemType *top;
  13. int stackSize;
  14. } sqStack;
  15. typedef struct
  16. {
  17. ElemTypes *base;
  18. ElemTypes *top;
  19. int stackSize;
  20. } sqStacks;
  21. void InitStack(sqStack *s)
  22. {
  23. s->top = s->base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));
  24. // memset(s->top, 0, STACK_INIT_SIZE * sizeof(ElemType));
  25. if ( !s->base )
  26. {
  27. exit(0);
  28. }
  29. s->base = s->top;
  30. s->stackSize = STACK_INIT_SIZE;
  31. }
  32. void InitStacks(sqStacks *s)
  33. {
  34. s->top = s->base = (ElemTypes *)malloc(STACK_INIT_SIZE * sizeof(ElemTypes));
  35. // memset(s->top, 0, STACK_INIT_SIZE * sizeof(ElemTypes));
  36. if ( !s->base )
  37. {
  38. exit(0);
  39. }
  40. s->base = s->top;
  41. s->stackSize = STACK_INIT_SIZE;
  42. }
  43. void Push(sqStack *s, ElemType e)
  44. {
  45. if ( s->top - s->base >= s->stackSize )
  46. {
  47. s->base = (ElemType *)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(ElemType));
  48. if ( !s->base )
  49. {
  50. exit(0);
  51. }
  52. }
  53. *(s->top) = e;
  54. s->top++;
  55. }
  56. void Pushs(sqStacks *s, ElemTypes e)
  57. {
  58. if ( s->top - s->base >= s->stackSize )
  59. {
  60. s->base = (ElemTypes *)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(ElemTypes));
  61. if ( !s->base )
  62. {
  63. exit(0);
  64. }
  65. }
  66. *(s->top) = e;
  67. s->top++;
  68. }
  69. void Pop(sqStack *s, ElemType *e)
  70. {
  71. if( s->base == s->top )
  72. {
  73. return;
  74. }
  75. *e = *--(s->top);
  76. }
  77. void Popp(sqStack *s, ElemType *e)
  78. {
  79. if( s->base == s->top )
  80. {
  81. return;
  82. }
  83. *e = *(s->base);
  84. s->base++;
  85. }
  86. void Pops(sqStacks *s, ElemTypes *e)
  87. {
  88. if( s->base == s->top )
  89. {
  90. return;
  91. }
  92. *e = *--(s->top);
  93. }
  94. int StackLen(sqStack s)
  95. {
  96. return (s.top - s.base);
  97. }
  98. int StackLens(sqStacks s)
  99. {
  100. return (s.top - s.base);
  101. }
  102. int main()
  103. {
  104. sqStack s, p;
  105. sqStacks q;
  106. char c, e;
  107. double d, f;
  108. char str[MAXBUFFER];
  109. InitStack( &s );
  110. InitStack( &p );
  111. InitStacks( &q );
  112. int i = 0;
  113. printf("请输入中缀表达式,以#作为结束标志: ");
  114. scanf("%c", &c);
  115. while( c != '#' )
  116. {
  117. while( c >= '0' && c <= '9' )
  118. {
  119. printf("%c", c);
  120. Push(&p, c);
  121. scanf("%c", &c);
  122. if( c < '0' || c > '9')
  123. {
  124. printf(" ");
  125. Push(&p, ' ');
  126. }
  127. }
  128. if( ')' == c )
  129. {
  130. Pop(&s, &e);
  131. while( '(' != e )
  132. {
  133. printf("%c ", e);
  134. Push(&p, e);
  135. Push(&p, ' ');
  136. Pop(&s, &e);
  137. }
  138. }
  139. else if( '+' == c || '-' == c )
  140. {
  141. if ( !StackLen(s) )
  142. {
  143. Push(&s, c);
  144. }
  145. else
  146. {
  147. do
  148. {
  149. Pop(&s, &e);
  150. if( '(' == e )
  151. {
  152. Push(&s, e);
  153. }
  154. else
  155. {
  156. printf("%c ", e);
  157. Push(&p, e);
  158. Push(&p, ' ');
  159. }
  160. }while( StackLen(s) && '(' !=e );
  161. Push(&s, c);
  162. }
  163. }
  164. else if( '(' ==c || '*' == c || '/' == c )
  165. {
  166. Push(&s, c);
  167. }
  168. else if( '#' == c )
  169. {
  170. break;
  171. }
  172. else
  173. {
  174. printf("\n出错:输入格式错误!\n");
  175. return -1;
  176. }
  177. scanf("%c", &c);
  178. }
  179. while( StackLen(s) )
  180. {
  181. Pop(&s, &e);
  182. printf("%c ", e);
  183. Push(&p, e);
  184. Push(&p, ' ');
  185. }
  186. Popp(&p, &c);
  187. int flag = 0;
  188. while ( StackLen(p) )
  189. {
  190. while ( c >= '0' && c <= '9' )
  191. {
  192. str[i++] = c;
  193. Popp(&p, &c);
  194. flag = 1;
  195. }
  196. if (flag)
  197. {
  198. str[i] = '\0';
  199. d = atof(str);
  200. Pushs(&q, d);
  201. // printf("d=%f", d);
  202. i = 0;
  203. flag = 0;
  204. }
  205. switch( c )
  206. {
  207. case '+':
  208. Pops(&q, &f);
  209. Pops(&q, &d);
  210. Pushs(&q, d+f);
  211. // printf("d+f=%f ", d+f);
  212. break;
  213. case '-':
  214. Pops(&q, &f);
  215. Pops(&q, &d);
  216. Pushs(&q, d-f);
  217. // printf("d-f=%f ", d-f);
  218. break;
  219. case '*':
  220. Pops(&q, &f);
  221. Pops(&q, &d);
  222. Pushs(&q, d*f);
  223. // printf("d*f=%f ", d*f);
  224. break;
  225. case '/':
  226. Pops(&q, &f);
  227. Pops(&q, &d);
  228. if ( f != 0 )
  229. {
  230. Pushs(&q, d/f);
  231. // printf("d/f=%f ", d/f);
  232. }
  233. else
  234. {
  235. printf("出错:除数为零!\n");
  236. return -1;
  237. }
  238. break;
  239. }
  240. Popp(&p, &c);
  241. }
  242. Pops(&q, &d);
  243. printf("\n最终的计算结果为: %f\n", d);
  244. return 0;
  245. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注