栈的应用非常的广泛,在C++的STL中,提供了用数组实现的栈。把线性表的插入和删除操作都限制在同一端,就得到栈的数据结构。是一个后进先出的数据结构。

因为栈是一种特殊的线性表,所以可以从线性表类派生出stack类。通过派生的方法可以降低栈的开发难度,但是代码的执行效率也会降低。

定义和应用:

栈:一种特殊的线性表,插入和删除操作都限制在表的同一端进行,这端称为栈顶,另一端称为栈底。

应用: 计算机执行递归函数就用到了栈。

1.直接创建基于数组的栈:
arrayStack类:

arraystack.h文件

#ifndef ARRAY_STACK_H
#define ARRAY_STACK_H
#include <iostream>
#include "E:\back_up\code\c_plus_code\sparseMatrix\external_file\stackemptyException.h"   // 异常类
using namespace std;template<typename T=int>
class arrayStack
{private:T* element;int elem_number;    // 栈中元素的个数 int capacity;     // 栈的容量 void ensureCaoacity();// stack ADTpublic:arrayStack(int init_capacity=10);~arrayStack();arrayStack(const arrayStack& stack);   // 拷贝构造函数bool empty() const;int size() const;    // 返回栈中元素的个数 T top() const;   // 返回栈顶元素的值void pop();      // 删除栈顶元素void push(T x);  // 入栈 void print_stack() const;// 定义友元函数; };// arrayStack实现
template<typename T>
arrayStack<T>::arrayStack(int init_capacity)
{elem_number = 0;capacity = init_capacity;element = new T[capacity];
} template<typename T>
arrayStack<T>::~arrayStack()
{delete []element;
}template<typename T>
arrayStack<T>::arrayStack(const arrayStack& stack)
{elem_number = stack.elem_number;   // 栈中的元素个数capacity = stack.capacity;element = new T[capacity];// 赋值元素for(int i=0; i<elem_number; i++){element[i] = stack.element[i];}
}template<typename T>
void arrayStack<T>::ensureCaoacity()
{if(elem_number>=capacity){T* old = element;// delete element;   // delete的本质是: delete之后,下次再重新申请的时候可以// 再申请这块内存地址,对于这块地址的内容,没有进行清空处理(也没有必要) capacity = elem_number*2;element = new T[capacity];for(int i=0; i<elem_number; i++){element[i] = old[i];   }delete []old;}// 还可以添加栈中数组大小动态减小的代码
}template<typename T>
bool arrayStack<T>::empty() const
{return elem_number==0;
} template<typename T>
int arrayStack<T>::size() const   // 返回栈中元素的个数
{return elem_number;
}template<typename T>
T arrayStack<T>::top() const
{if(empty())throw stack_empty_exception(0); return element[elem_number-1];    // 返回栈顶元素的值
}template<typename T>
void arrayStack<T>::pop()
{if(empty())throw stack_empty_exception(0);elem_number--;
} template<typename T>
void arrayStack<T>::push(T x)
{ensureCaoacity();element[elem_number++] = x;
} template<typename T>
void arrayStack<T>::print_stack() const
{if(empty()){cout << "The stack is empty" << endl;}else{for(int i=0; i<elem_number; i++){cout << element[i] << " ";}cout << endl;}
}#endif

在栈为空的时候,不能进行出栈操作,这一功能由异常类实现:

stackemptyException.h文件

// 自定义异常类:
#ifndef STACK_EMPTY_EXCEPTION
#define STACK_EMPTY_EXCEPTION
#include <stdexcept>
using namespace std;    // 因为stdexcept
class stack_empty_exception : public runtime_error
{private:int current_stack_size;public:stack_empty_exception(int stack_size):runtime_error("Stack is empty"){this->current_stack_size = stack_size;}void display_error_info(){cout << "----------------------------" << endl;cout << "The stack size is " << current_stack_size << endl;cout << "----------------------------" << endl;}
};
#endif

测试文件

main.cpp

#include <iostream>
#include "E:\back_up\code\c_plus_code\sparseMatrix\external_file\arraystack.h"
using namespace std;int main(int argc, char *argv[])
{arrayStack<int> stack(10);try    // 异常测试 {stack.pop();}catch(stack_empty_exception& ex){cout << ex.what() << endl;ex.display_error_info();}try    // 异常测试 {stack.pop();}catch(stack_empty_exception& ex){cout << ex.what() << endl;ex.display_error_info();}stack.print_stack(); for(int i=0; i<13; i++){stack.push(i+1);}stack.print_stack();cout << "stack size: " << stack.size() << endl;while(!stack.empty())   // 出栈 {cout << stack.top() << " ";stack.pop();}cout << endl;
}

运行结果:

2

添加新的方法,将stack中的数据分为a,b两部分:

template<typename T>
void arrayStack<T>::split_stack(arrayStack& stack_a, arrayStack& stack_b)
{if(elem_number<2)throw stack_empty_exception(2); int criterion = elem_number/2;int count = 0;while(elem_number>0){if(count < criterion){stack_a.push(element[elem_number-1]);count++;elem_number--;}else{stack_b.push(element[elem_number-1]);count++;elem_number--;}}
}

测试函数:

main.cpp

#include <iostream>
#include "E:\back_up\code\c_plus_code\sparseMatrix\external_file\arraystack.h"
using namespace std;int main(int argc, char *argv[])
{arrayStack<int> stack(10);//stack.print_stack(); for(int i=0; i<10; i++){stack.push(i+1);}stack.print_stack();arrayStack<int> a;arrayStack<int> b;try{stack.split_stack(a, b);cout << "split stack into two parts" << endl;cout << "stack_a: ";a.print_stack();cout << "stack_b: ";b.print_stack();}catch(stack_empty_exception& ex){cout << ex.what() << endl;ex.display_error_info();}
}

运行结果:

2. 此外栈和可以由线性表的类派生而来,如arrayLIst类和chain类

3.栈的应用:

(a). 括号匹配:

例如:(a*(b+c)+d)进行括号匹配:从左到右扫描字符串,没哟个右括号都与最近扫描到的未匹配的左括号进行匹配

#include <iostream>
#include "E:\back_up\code\c_plus_code\sparseMatrix\external_file\arraystack.h"
#include <string>
using namespace std;void printMatchedPairs(string expr)
{arrayStack<int> s;int expr_length = (int)expr.size();// 扫描表达式for(int i=0; i<expr_length; i++){if(expr.at(i)=='('){s.push(i);    // 左括号的位置 }else{if(expr.at(i)==')')    // 如果是右括号,则进行匹配 try{cout << s.top() << " " << i << endl;s.pop();}catch(stack_empty_exception& ex){cout << "NO match for ) at " << i << endl;}} } while(!s.empty()){cout << "NO match for left bracket" << s.top() << endl;s.pop();}}int main(int argc, char *argv[])
{string expression("((a+b)*2)+3");printMatchedPairs(expression);}

输出:
1 5

0 8

数据结构与算法(七) 栈以及栈的应用相关推荐

  1. 数据结构与算法(C++)– 栈(Stack)

    数据结构与算法(C++)– 栈(Stack) 1.栈是什么 后进先出(Last in, First out) push 入栈,pop 出栈,top栈顶 2.栈的实现 单链表:在单链表的前端插入实现 p ...

  2. 数据结构和算法(五)--栈(Stack)

    数据结构和算法(五)–栈(Stack) 什么是栈 栈是一种特殊的线性表,只能在一端进行操作 往栈中添加元素,一般叫做push,入栈 往栈中移除元素,一般叫做pop,弹栈/出栈(只能移除栈顶元素) 栈遵 ...

  3. 03_JavaScript数据结构与算法(三)栈

    JavaScript 数据结构与算法(三)栈 数组是一个线性结构,并且可以在数组的任意位置插入和删除元素. 但是有时候,我们为了实现某些功能,必须对这种任意性加以限制. 栈和队列就是比较常见的受限的线 ...

  4. Java数据结构和算法(四)——栈

    前面我们讲解了数组,数组更多的是用来进行数据的存储,纯粹用来存储数据的数据结构,我们期望的是插入.删除和查找性能都比较好.对于无序数组,插入快,但是删除和查找都很慢,为了解决这些问题,后面我们会讲解比 ...

  5. 数据结构与算法--举例分析法- 栈的压入弹出序列

    举例分析 与上两篇问中画图方法一样,我们可以用举例模拟的方法思考分析复杂问题.当一眼不能看出问题的规律的时候,我们可以用几个具体的例子来模拟一下问题的过程.这样就和我们在程序出现问题时候的debug一 ...

  6. Python数据结构与算法(二)栈和队列

    本系列总结了python常用的数据结构和算法,以及一些编程实现. 参考书籍:<数据结构与算法 Python语言实现> [美]Michael T.Goodrich, Roberto Tama ...

  7. 数据结构与算法学习笔记——链栈

    数据结构与算法学习笔记(C语言) 链栈 在开始链栈的学习之前,我们先实现一下上一篇文章中提到的检查括号匹配的小程序,鉴于水平有限,本人就随便写一下代码好了,目标仅限于对功能的实现. /*用顺序栈这种数 ...

  8. 数据结构和算法(03)---栈和队列(c++)

    文章目录 目录 一.栈 1.栈的基本操作 2.使用C++模板类实现栈 二.队列 1.队列的基本操作 2.循环队列 **循环队列顺序存储** **循环队列链式存储** 3.双端队列 目录 数据结构: 逻 ...

  9. 数据结构与算法(3-1)栈(顺序栈、两栈共享空间、链栈、栈的计算器)

    目录 一.顺序栈 存储结构 总代码 二.两栈共享空间 存储结构: 总代码: 三.链栈 存储结构: 总代码: 一.顺序栈 存储结构: 栈特点:先进后出,后进先出.(特殊的线性表) 入栈时在栈顶添加元素, ...

  10. 常考数据结构与算法:用两个栈实现队列

    题目描述 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 分析    队列的特性是:"先入先出",栈的特性是:"先入后出" ...

最新文章

  1. 千万别中招!手把手教你复现Log4j2漏洞!
  2. Sublime Text 3 史上最性感的编辑器
  3. 理解JavaScript原型链
  4. 蓝桥杯-送分啦(java)
  5. MacBook刷机勘错篇
  6. oracle倒导数的条件过滤参数,oracle exp导出加上过滤条件
  7. 教学管理系统java_Java 实现简易教务管理系统的代码
  8. 学习C语言——字母金字塔
  9. 20155236 《信息安全概论》实验二(Windows系统口令破解)实验报告
  10. LiveZilla 详细 配置 设置 (四) 查看成果及总结
  11. 软路由虚拟服务器,VMware虚拟机安装软路由(OpenWrt)详细教程
  12. edge bing搜索响应缓慢
  13. DOJP1520星门跳跃题解
  14. js报错“TypeError: ‘stepUp‘ called on an object that does not implement interface HTMLInputElement”
  15. 第六届高分子材料国际研讨会(PMS-BT 2019)
  16. c++ getline()详解
  17. Python人工智能基础到实战课程-北方网视频
  18. Linux系统下如何在防火墙开放指定端口
  19. 关于在linux测试启动盘命令(qemu的使用)
  20. MySQL测试工具之-TPCC(业界通用的压测工具)

热门文章

  1. 数据库工作笔记017---还记得Oracle悲观锁和乐观锁嘛?以及hibernate对乐观悲观锁的封装
  2. openoffice使用总结001---版本匹配问题unknown document format for file: E:\apache-tomcat-8.5.23\webapps\ZcnsDms\
  3. MongoDB 我的学习笔记
  4. 腾讯笔试:把两个数和告诉A,积告诉B,求这两个数是什么
  5. linux底层文件io,学习Rust 文件与 IO
  6. 随想录(rt-patch和linux)
  7. 精简版_翻译软件,基于百度翻译api
  8. 微信小程序傻瓜制作_傻瓜式教程:做一个带优惠券的微信小程序
  9. 优化模型实验报告_BERT微调效果不佳?试试这种大规模预训练模型新范式
  10. nodejs虚拟服务器,NodeJs本地搭建服务器,模拟接口请求,获取json数据