当前位置:   article > 正文

数据结构-栈及栈的应用_数据结构-栈的应用

数据结构-栈的应用

目录

栈的概述

部分算法分析

顺序栈的表示和实现

global.h

Stack.h

StackTest.cpp

运行结果

栈的应用

数的任意进制转换

括号匹配检验


栈的概述

  •  栈是一种重要的线性结构,属于一种操作受限的线性表
  • 栈(stack) 是限定仅在表尾进行插入或删除操作的线性表
  • 表尾端称为栈顶(top),表头端称为栈底(bottom)
  • 栈的元素遵循先进后出(后进先出),即最先进入栈的元素最后出栈


部分算法分析

  • 栈的初始化
  1. //栈的初始化(构造一个空的栈)
  2. Status InitStack(Stack& S) {
  3. //为栈开辟空间
  4. S.base = (SElemType*)malloc(STACK_INIT_SIZE * sizeof(SElemType));
  5. if (!S.base)
  6. return ERROR;
  7. //当top指针与base指针指向地址时,栈为空栈
  8. S.top = S.base;
  9. S.stacksize = STACK_INIT_SIZE;
  10. return OK;
  11. }

 顺序栈,即栈的顺序存储结构,利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素,注意:top指针所指的地址并不是存储栈顶数据元素的,而是栈顶数据元素的上一个空间地址

  •  数据入栈操作
  1. //数据元素data入栈操作
  2. Status PushStack(Stack& S, SElemType data) {
  3. //判断栈内的数据是否已满,已满追加新的存储空间
  4. if (S.top - S.base >= S.stacksize) {
  5. //为栈追加新的空间
  6. SElemType* newbase;
  7. newbase = (SElemType*)realloc(S.base,(S.stacksize + STACK_INCREMENT)*sizeof(SElemType));
  8. if (newbase)
  9. return ERROR;
  10. S.base = newbase;
  11. //防止出现新开辟的空间中存储了其它程序的数据被覆盖
  12. S.top = S.base + S.stacksize;
  13. S.stacksize += STACK_INCREMENT;
  14. }
  15. if(S.top != NULL)
  16. *(S.top++) = data;
  17. return OK;
  18. }

追加存储空间使用的是realloc(void *ptr, size_t size) 函数

ptr指针指向一个要重新分配内存的内存块,如果为空指针,则会分配一个新的内存块,且函数返回一个指向它的指针

size内存块的新的大小,以字节为单位。如果大小为 0,且 ptr 指向一个已存在的内存块,则 ptr 所指向的内存块会被释放,并返回一个空指针

 情况1

 情况2

 在空间扩大的过程中,如果在原地址后有足够的空间追加,则直接在原空间后扩大空间,如果原地址后没有足够的空间追加,则会在新的一块地址区域直接开辟一块size大小的地址空间


 顺序栈的表示和实现

  • global.h
  • Stack.h
  • StackTest.cpp

 global.h

相关头文件的引用,以及相应全局变量、常量的声明

  1. #pragma once
  2. #include<iostream>
  3. #include<string.h>
  4. #include<stdlib.h>
  5. #include<stdio.h>
  6. #include<windows.h>
  7. using namespace std;
  8. #define TRUE 1
  9. #define FALSE 0
  10. #define OK 1
  11. #define ERROR 0
  12. #define INFEASIBLE -1
  13. #define EQ(a,b) ((a) == (b))
  14. #define LT(a,b) ((a) < (b))
  15. #define LQ(a,b) ((a) <= (b))
  16. #define MT(a,b) ((a) > (b))
  17. #define MQ(a,b) ((a) >= (b))
  18. typedef int Status;

Stack.h

顺序栈的定义,以及顺序栈的相关操作算法

  1. #pragma once
  2. #include"global.h"
  3. #define STACK_INIT_SIZE 100
  4. #define STACK_INCREMENT 10
  5. #define SElemType int
  6. //栈的定义
  7. typedef struct {
  8. SElemType* base; //栈底指针
  9. SElemType* top; //栈顶指针
  10. int stacksize; //栈的空间大小
  11. }Stack;
  12. //栈的初始化(构造一个空的栈)
  13. Status InitStack(Stack& S) {
  14. //为栈开辟空间
  15. S.base = (SElemType*)malloc(STACK_INIT_SIZE * sizeof(SElemType));
  16. if (!S.base)
  17. return ERROR;
  18. //当top指针与base指针指向地址时,栈为空栈
  19. S.top = S.base;
  20. S.stacksize = STACK_INIT_SIZE;
  21. return OK;
  22. }
  23. //空栈的数据赋值操作
  24. Status InitStackData(Stack& S) {
  25. //判断该栈是否为空栈
  26. if (S.top != S.base) {
  27. cout << "该栈不是空栈" << endl;
  28. return ERROR;
  29. }
  30. cout << "输入插入存储数据的个数:" << endl;
  31. int nums = 0;
  32. cin >> nums;
  33. cout << "输入" << nums << "个数据:" << endl;
  34. for (int i = 0; i < nums; i++) {
  35. cin >> *(S.top++);
  36. }
  37. return OK;
  38. }
  39. //栈的数据遍历
  40. void ShowStack(Stack S) {
  41. cout << "栈内的数据元素有:" << endl;
  42. while (S.top != S.base) {
  43. cout << *(--S.top) << " ";
  44. }
  45. cout << endl;
  46. }
  47. //判断栈是否为空栈
  48. Status StackEmpty(Stack S) {
  49. if (S.top == S.base)
  50. return OK;
  51. return ERROR;
  52. }
  53. //栈的销毁
  54. Status DestroyStack(Stack& S) {
  55. S.top = S.base;
  56. free(S.base);
  57. cout << "栈销毁成功" << endl;
  58. return OK;
  59. }
  60. //将栈置为空栈
  61. Status ClearStack(Stack& S) {
  62. S.top = S.base;
  63. cout << "栈置为空栈成功" << endl;
  64. return OK;
  65. }
  66. //输出栈内的数据个数
  67. int StackLength(Stack S) {
  68. int length = S.top - S.base;
  69. return length;
  70. }
  71. //获取栈顶的数据
  72. void GetTop(Stack S) {
  73. cout << "栈顶的数据为:" << *(S.top - 1) << endl;
  74. }
  75. //数据元素data入栈操作
  76. Status PushStack(Stack& S, SElemType data) {
  77. //判断栈内的数据是否已满,已满追加新的存储空间
  78. if (S.top - S.base >= S.stacksize) {
  79. //为栈追加新的空间
  80. SElemType* newbase;
  81. newbase = (SElemType*)realloc(S.base,(S.stacksize + STACK_INCREMENT)*sizeof(SElemType));
  82. if (newbase)
  83. return ERROR;
  84. S.base = newbase;
  85. //防止出现新开辟的空间中存储了其它程序的数据被覆盖
  86. S.top = S.base + S.stacksize;
  87. S.stacksize += STACK_INCREMENT;
  88. }
  89. if(S.top != NULL)
  90. *(S.top++) = data;
  91. return OK;
  92. }
  93. //将栈顶数据元素出栈,并记录出栈的数据元素
  94. Status PopStack(Stack& S, SElemType& data) {
  95. //判断栈是否为空,不为空则删除栈顶数据元素(出栈)
  96. if (S.top == S.base)
  97. return ERROR;
  98. data = *(--S.top);
  99. return OK;
  100. }

StackTest.cpp

  1. #include"Stack.h"
  2. int main() {
  3. Stack stack;
  4. InitStack(stack);
  5. InitStackData(stack);
  6. ShowStack(stack);
  7. int length = StackLength(stack);
  8. cout << "栈内的元素个数为:" << length << endl;
  9. SElemType data;
  10. GetTop(stack);
  11. cout << "入栈操作,请输入入栈的数据:" << endl;
  12. cin >> data;
  13. PushStack(stack,data);
  14. ShowStack(stack);
  15. cout << "------出栈操作------" << endl;
  16. PopStack(stack, data);
  17. cout << "出栈的数据是:" << data << endl;
  18. ShowStack(stack);
  19. }

运行结果

输入插入存储数据的个数:
5
输入5个数据:
12 23 43 21 56
栈内的数据元素有:
56 21 43 23 12
栈内的元素个数为:5
栈顶的数据为:56
入栈操作,请输入入栈的数据:
87
栈内的数据元素有:
87 56 21 43 23 12
------出栈操作------
出栈的数据是:87
栈内的数据元素有:
56 21 43 23 12

F:\DataStructureForC++\Project\Debug\Project1.exe (process 5248) exited with code 0.


 栈的应用

  • 数的任意进制转换
  • 括号匹配检验
  • 表达式求值

 数的任意进制转换

将一个十进制数N与其他d进制数转换,基于下列原理

N = (N div d) × d + N mod d (div为整除运算,mod为求余运算)

  1. /*
  2. * 数的任意进制转换
  3. * 用户输入任意非负正整数,再输入一个进制数
  4. */
  5. void NumberConversion(int number,int baseNumber) {
  6. //判断输入的数是否为正整数
  7. if (number < 0) {
  8. cout << "输入的数不能为负数" << endl;
  9. exit(0);
  10. }
  11. Stack stack;
  12. SElemType data;
  13. InitStack(stack);
  14. cout << number << "转化" << baseNumber << "进制后的数为:" << endl;
  15. while (number) {
  16. PushStack(stack, number % baseNumber);
  17. number = number / baseNumber;
  18. }
  19. while (!StackEmpty(stack)) {
  20. PopStack(stack, data);
  21. cout << data;
  22. }
  23. cout << endl;
  24. }

 运行结果

 请输入一个非负的十进制整数
8
请输入一个进制数:
2
8转化2进制后的数为:
1000


请输入一个非负的十进制整数
89
请输入一个进制数:
8
89转化8进制后的数为:
131

括号匹配检验

假设表达式中允许包含两种括号:圆括号()和方括号 [ ] ,其嵌套顺序随意,检验括号嵌套的格式是否正确

  1. /*
  2. * 括号匹配检验
  3. * 用户输入方括号和圆括号,检验括号是否匹配
  4. * charArray数组以'#'作为最后一个数据元素(循环终止条件)
  5. */
  6. void BracketMatch(char charArray[]) {
  7. Stack stack;
  8. InitStack(stack);
  9. SElemType c;
  10. while (*charArray != '#') {
  11. switch ((*charArray)) {
  12. case ')':
  13. PopStack(stack, c);
  14. if (c != '(') {
  15. cout << ") 括号不匹配" << endl;
  16. exit(0);
  17. }
  18. break;
  19. case ']':
  20. PopStack(stack, c);
  21. if (c != '[') {
  22. cout << "] 括号不匹配" << endl;
  23. exit(0);
  24. }
  25. break;
  26. default:
  27. //如果不是右括号,将该括号进栈
  28. PushStack(stack, *(charArray));
  29. }
  30. charArray++;
  31. }
  32. cout << "括号匹配成功" << endl;
  33. }

 运行结果

输入的括号为:
( [ ] ) 括号匹配成功


输入的括号为:
( [ ( ] ] ) ] 括号不匹配

F:\DataStructureForC++\Project\Debug\Project1.exe (process 2124) exited with code 0.

注意:将Stack.h头文件中的#define SElemType int改为char

 括号匹配函数中,如果遇到左括号则入栈,遇到右括号则进入switch( )语句,将栈内的栈顶元素出栈(该元素为最内层的括号),检查括号是否匹配

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

闽ICP备14008679号