当前位置:   article > 正文

数据结构-C语言代码 day6-栈及其应用_在c语言中栈的实现及应用代码

在c语言中栈的实现及应用代码

一、栈的定义

栈(stack)是限定仅在表尾进行插入或者删除的线性表。对于栈来说,表尾端称为栈顶(top),表头端称为栈低(bottom)。不含元素的空表称为空栈。因为栈限定在表尾进行插入或者删除,所以栈又被称为后进先出的线性表。

二、栈的基本操作

1.栈的结构体

  1. typedef struct CharStack
  2. {
  3. int top;
  4. int data[STACK_MAX_SIZE];
  5. } *CharStackPtr;

2.初始化

  1. CharStackPtr charStackInit()
  2. {
  3. CharStackPtr resultPtr = (CharStackPtr)malloc(sizeof(struct CharStack));
  4. resultPtr->top = -1;
  5. return resultPtr;
  6. }

3.打印

  1. void outputStack(CharStackPtr paraStack)
  2. {
  3. for (int i = 0; i <= paraStack->top; i ++)
  4. {
  5. printf("%c ", paraStack->data[i]);
  6. }
  7. printf("\r\n");
  8. }

4.压栈

  1. void push(CharStackPtr paraStackPtr, int paraValue)
  2. {
  3. // 空间检查(是否栈满)
  4. if (paraStackPtr->top >= STACK_MAX_SIZE - 1)
  5. {
  6. printf("堆栈已满,无法添加.\r\n");
  7. return;
  8. }
  9. // 顶部更新.
  10. paraStackPtr->top ++;
  11. // 入栈.
  12. paraStackPtr->data[paraStackPtr->top] = paraValue;
  13. }

5.弹栈 

  1. char pop(CharStackPtr paraStackPtr)
  2. {
  3. // 空间检查(判断空栈).
  4. if (paraStackPtr->top < 0)
  5. {
  6. printf("堆栈为空,无法弹出.\r\n");
  7. return '\0';
  8. }
  9. // 顶部更新.
  10. paraStackPtr->top --;
  11. return paraStackPtr->data[paraStackPtr->top + 1];
  12. }

 

6.功能测试

  1. void pushPopTest()
  2. {
  3. printf("栈的进出开始测试:\r\n");
  4. // 初始化
  5. CharStackPtr tempStack = charStackInit();
  6. printf("初始化后的栈: ");
  7. outputStack(tempStack);
  8. // 压栈
  9. for (char ch = 'a'; ch < 'n'; ch ++)
  10. {
  11. printf("添加 %c.\r\n", ch);
  12. push(tempStack, ch);
  13. outputStack(tempStack);
  14. }//Of for i
  15. // 弹栈
  16. for (int i = 0; i < 4; i ++)
  17. {
  18. char ch = pop(tempStack);
  19. printf("删除 %c.\r\n", ch);
  20. outputStack(tempStack);
  21. }
  22. printf("测试结束\r\n");
  23. }

测试结果

  1. 栈的进出开始测试:
  2. 初始化后的栈:
  3. 添加 a.
  4. a
  5. 添加 b.
  6. a b
  7. 添加 c.
  8. a b c
  9. 添加 d.
  10. a b c d
  11. 添加 e.
  12. a b c d e
  13. 添加 f.
  14. a b c d e f
  15. 添加 g.
  16. a b c d e f g
  17. 添加 h.
  18. a b c d e f g h
  19. 添加 i.
  20. a b c d e f g h i
  21. 添加 j.
  22. a b c d e f g h i j
  23. 添加 k.
  24. 堆栈已满,无法添加.
  25. a b c d e f g h i j
  26. 添加 l.
  27. 堆栈已满,无法添加.
  28. a b c d e f g h i j
  29. 添加 m.
  30. 堆栈已满,无法添加.
  31. a b c d e f g h i j
  32. 删除 j.
  33. a b c d e f g h i
  34. 删除 i.
  35. a b c d e f g h
  36. 删除 h.
  37. a b c d e f g
  38. 删除 g.
  39. a b c d e f
  40. 测试结束

三、括号匹配

 借助栈

  1. bool bracketMatching(char* paraString, int paraLength)
  2. {
  3. // 通过在底部压入“#”来初始化堆栈
  4. CharStackPtr tempStack = charStackInit();
  5. push(tempStack, '#');
  6. char tempChar, tempPopedChar;
  7. // 处理字符串
  8. for (int i = 0; i < paraLength; i++) {
  9. tempChar = paraString[i];
  10. switch (tempChar) {
  11. case '(':
  12. case '[':
  13. case '{':
  14. push(tempStack, tempChar);
  15. break;
  16. case ')':
  17. tempPopedChar = pop(tempStack);
  18. if (tempPopedChar != '(') {
  19. return false;
  20. }
  21. break;
  22. case ']':
  23. tempPopedChar = pop(tempStack);
  24. if (tempPopedChar != '[') {
  25. return false;
  26. } break;
  27. case '}':
  28. tempPopedChar = pop(tempStack);
  29. if (tempPopedChar != '{') {
  30. return false;
  31. }
  32. break;
  33. default:
  34. break;
  35. }
  36. }
  37. tempPopedChar = pop(tempStack);
  38. if (tempPopedChar != '#')
  39. {
  40. return true;
  41. }
  42. return true;
  43. }

功能测试

  1. void bracketMatchingTest()
  2. {
  3. printf("括号匹配测试开始:\r\n");
  4. char* tempExpression = "{6+3-[1+2*(6-2)]}/2";
  5. bool tempMatch = bracketMatching(tempExpression, 17);
  6. printf("'%s'是否括号匹配? %d \r\n", tempExpression, tempMatch);
  7. tempExpression = "[1+2*8)(]";
  8. tempMatch = bracketMatching(tempExpression, 6);
  9. printf("'%s'是否括号匹配? %d \r\n", tempExpression, tempMatch);
  10. tempExpression = "({[]})";
  11. tempMatch = bracketMatching(tempExpression, 8);
  12. printf("'%s'是否括号匹配? %d \r\n", tempExpression, tempMatch);
  13. tempExpression = "()()[]";
  14. tempMatch = bracketMatching(tempExpression, 6);
  15. printf("'%s'是否括号匹配? %d \r\n", tempExpression, tempMatch);
  16. tempExpression = "{]()";
  17. tempMatch = bracketMatching(tempExpression, 2);
  18. printf("'%s'是否括号匹配? %d \r\n", tempExpression, tempMatch);
  19. printf("测试结束\r\n");
  20. }

测试结果

  1. 括号匹配测试开始:
  2. '{6+3-[1+2*(6-2)]}/2'是否括号匹配? 1
  3. '[1+2*8)(]'是否括号匹配? 1
  4. '({[]})'是否括号匹配? 1
  5. '()()[]'是否括号匹配? 1
  6. '{]()'是否括号匹配? 0
  7. 测试结束

四、表达式求值

//属实是难到了,C++还有很多不理解的地方,主要还是在观摩学习,以下为学长代码,只用了两个栈便实现了表达式求值的功能。

1.#include <cstring>:可以使用很多实用的字符串函数;

2.#include<algorithm>:algorithm意为"算法",是C++的标准模版库(STL)中最重要的头文件之一,提供了大量基于迭代器的非成员模版函数;

3.#include < stack > include < stack >为C++ STL栈stack的 头文件 ,是STL中实现的一个后进先出的容器:

stack<int>num//声明一个对象

str.size()//返回栈中元素个数于X

num.pop()//移除栈顶元素

num.push(x)//将X置于栈顶

op.top()//返回栈顶元素

4.unordered_map是一种关联容器,存储基于键值和映射组成的元素,即key-value。允许基于键快速查找元素。unordered_map中,键值唯一标识元素,映射的值是一个与该对象关联的内容的对象

5.auto是一个C/C++语言存储类型,仅在语句块内部使用,初始化可为任何表达式,其特点是当执行流程进入该语句块的时候初始化可为任何表达式。

  1. //202031061018 刘知鑫
  2. #include <iostream>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <stack>
  6. #include <unordered_map>
  7. using namespace std;
  8. stack<int> num;
  9. stack<char> op;
  10. void eval()
  11. {
  12. auto b = num.top();
  13. num.pop();
  14. auto a = num.top();
  15. num.pop();
  16. auto c = op.top();
  17. op.pop();
  18. int x;
  19. if (c == '+') x = a + b;
  20. else if (c == '-') x = a - b;
  21. else if (c == '*') x = a * b;
  22. else x = a / b;
  23. num.push(x);
  24. }
  25. int main()
  26. {
  27. unordered_map<char, int> pr{{'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}};
  28. string str;
  29. cin >> str;
  30. for (int i = 0; i < str.size(); i ++ )
  31. {
  32. auto c = str[i];
  33. if (isdigit(c))
  34. {
  35. int x = 0, j = i;
  36. while (j < str.size() && isdigit(str[j]))
  37. x = x * 10 + str[j ++ ] - '0';
  38. i = j - 1;
  39. num.push(x);
  40. }
  41. else if (c == '(') op.push(c);
  42. else if (c == ')')
  43. {
  44. while (op.top() != '(') eval();
  45. op.pop();
  46. }
  47. else
  48. {
  49. while (op.size() && op.top() != '(' && pr[op.top()] >= pr[c]) eval();
  50. op.push(c);
  51. }
  52. }
  53. while (op.size()) eval();
  54. cout << num.top() << endl;
  55. return 0;
  56. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/970352
推荐阅读
相关标签
  

闽ICP备14008679号