栈结构:先进后出,后进先出,像叠盘子一样,先叠的后用。
代码github地址 https://github.com/hitskyer/course/tree/master/dataAlgorithm/chenmingming/stack
1.顺序栈(数组存储,需给定数组大小,到达容量需要copy转移数据)
1.1 头文件 arrStack.h
//
// Created by mingm on 2019/3/27.
//
#ifndef STACK_ARRSTACK_H
#define STACK_ARRSTACK_H
typedef unsigned int UINT;
template <class T>
class arrStack
{
public:arrStack(int capacity); // 初始化栈~arrStack(void); // 析构栈bool Empty() const; // 判断是否为空bool IsFull() const; //判断栈是否满了void Clear(); // 则清空栈T& GetTop() const; // 得到栈顶元素UINT GetLength() const; // 返回栈的长度void Push(T &data); //往栈中压入数据void Expand(); //栈扩容void Pop(); //将栈顶数据弹出void print(); //自己加的接口,打印输出stack内容
private:int m_pTop; // 栈顶指针UINT m_nStackLen; // 栈容量T* arr; //数组arr
};#endif //STACK_ARRSTACK_H
1.2 类实现文件 arrStack.cpp
//
// Created by mingm on 2019/3/27.
//
#include "arrStack.h"
#include <iostream>
using namespace std;
template <class T> arrStack<T>::arrStack(int capacity):m_pTop(-1),m_nStackLen(capacity)
{arr = new T[capacity];
}
template <class T> arrStack<T>::~arrStack()
{Clear();delete [] arr;arr = NULL;
}
template <class T> bool arrStack<T>::Empty() const
{return m_pTop == -1;
}
template <class T> bool arrStack<T>::IsFull() const
{return m_pTop == m_nStackLen - 1;
}
template <class T> void arrStack<T>::Clear()
{m_pTop = -1;
}
template <class T> void arrStack<T>::Push(T &data)
{if(IsFull()){
// cout << "overflow !" << endl;Expand();}arr[++m_pTop] = data;
}
template <class T> void arrStack<T>::Expand()
{m_nStackLen = 2 * m_nStackLen;T* temparr = new T[m_nStackLen];for(int i = 0; i <= m_pTop; ++i){temparr[i] = arr[i];}T* temp = arr;arr = temparr;temparr = temp;delete [] temparr;temparr = NULL;
}
template <class T> void arrStack<T>::Pop()
{if(!Empty())--m_pTop;
}
template <class T> T& arrStack<T>::GetTop() const
{if(!Empty())return arr[m_pTop];throw "no elem!"; //抛出异常
}
template <class T> UINT arrStack<T>::GetLength() const
{return m_nStackLen;
}
template <class T> void arrStack<T>::print()
{cout << "----arrstack top----" << endl;int i = m_pTop, j = m_pTop;while(m_pTop != -1 && j >= 0){cout << "No." << i-- << " elem " << arr[j--] << endl;}cout << "----arrstack bottom----" << endl;
}
1.3 测试程序及括号格式合法性检测 arrstack_testMain.cpp(练习了下try,catch)
//
// Created by mingm on 2019/3/27.
//
#include "arrStack.cpp"
#include <string>
#include <iostream>
using namespace std;
int main()
{for(int i = 0; i < 20; ++i){int k = 0;arrStack<int> int_arr_stack(8);int_arr_stack.print();cout << "the capacity of stack is " << int_arr_stack.GetLength() << endl;while(k < i){int_arr_stack.Push(k);++k;}try{cout << "top elem is " << int_arr_stack.GetTop() << endl;}catch(const char* str){cout << str << endl;}cout << "the capacity of stack is " << int_arr_stack.GetLength() << endl;int_arr_stack.print();int_arr_stack.Clear();cout << "---------------------------------" << endl;}cout << "以下测试一个字符串是否有非法格式的括号" << endl;char conti = 'y', str;while(conti == 'y'|| conti == 'Y'){bool legal = true;arrStack<char> charstack(100);cout << "please enter a string to check its brackets legal or not !" << endl;while(cin.get(str) && str != '\n') //不断地获取输入的字符{if(str == '{' || str == '[' || str == '(') //遇到左括号不断地压栈{charstack.Push(str);continue;}switch(str) //遇到非左括号{case '}':try{if(charstack.GetTop() && charstack.GetTop() == '{') //栈不为空且栈顶与右括号匹配charstack.Pop(); //删除左括号elselegal = false; //直接遇上右括号,非法;or 栈顶与当前右括号不匹配}catch(const char* str) //若捕获try内的异常,没有元素在栈内,则遇到右括号,非法{legal = false;}break;case ']':try{if(charstack.GetTop() && charstack.GetTop() == '[')charstack.Pop();elselegal = false;}catch(const char* str){legal = false;}break;case ')':try{if(charstack.GetTop() && charstack.GetTop() == '(')charstack.Pop();elselegal = false;}catch(const char* str){legal = false;}break;default:break;}if(!legal)break; //如果非法,不必循环了,直接退出}if(legal && charstack.Empty()) //如果合法,且符号都匹配了(栈为空)cout << "legal string !" << endl;else{cout << "illegal string !" << endl;cin.ignore(10000,'\n'); //清除非法字符后面尚未get的字符}cout << "continue? y/n: " ;cin >> conti;cin.get();}return 0;
}
2.链式栈(链表存储,无需给定长度)
2.1 头文件 stack.h
/*
* 概述: 栈
* 作者: dongyaxing
* 版本: 1.0
* 创建时间:2019/3/25 20:47
* 修改者: liuyanfu
* 修改时间: 2019/3/25 21:14
*/
#ifndef _STACK_H
#define _STACK_H
template <class T>
struct SNode
{T data;SNode *pNext;
};
template <class T>using StackNode = SNode<T>* ; //某些编译器不支持改语法
//template <class T> typedef SNode<T>* StackNode; //错误写法
typedef unsigned int UINT;
template <class T>
class Stack
{
public:Stack(void); // 初始化栈~Stack(void); // 析构栈bool Empty() const; // 判断是否为空void Clear(); // 则清空栈StackNode<T> GetTop() const; // 得到栈顶元素UINT GetLength() const; // 返回栈的长度void Push(T &data); //往栈中压入数据void Pop(); //将栈顶数据弹出void print(); //自己加的接口,打印输出stack内容
private:StackNode<T> m_pTop; // 栈顶元素UINT m_nStackLen; // 栈长度
};#endif //_STACK_H
2.2 类实现文件 stack.cpp
//
// Created by mingm on 2019/3/26.
//
#include "stack.h"
#include <iostream>
using namespace std;
template <class T> Stack<T>::Stack():m_pTop(NULL),m_nStackLen(0){}
template <class T> Stack<T>::~Stack() { Clear(); }
template <class T> bool Stack<T>::Empty() const
{return m_nStackLen == 0;
}
template <class T> void Stack<T>::Clear()
{while(m_pTop != NULL){Pop();}
}
template <class T> void Stack<T>::Push(T &data)
{StackNode<T> newNode = new SNode<T>;newNode->data = data;newNode->pNext = NULL;if(m_pTop == NULL){m_pTop = newNode;}else{newNode->pNext = m_pTop;m_pTop = newNode;}m_nStackLen++;
}
template <class T> void Stack<T>::Pop()
{if(m_pTop != NULL){StackNode<T> temp = m_pTop->pNext;delete m_pTop;m_pTop = temp;m_nStackLen--;}
}
template <class T> StackNode<T> Stack<T>::GetTop() const
{return m_pTop;
}
template <class T> UINT Stack<T>::GetLength() const
{return m_nStackLen;
}
template <class T> void Stack<T>::print()
{cout << "----stack top----" << endl;StackNode<T> temp = m_pTop;size_t i = 0;while(temp != NULL){cout << "No." << ++i << " elem " << temp->data << endl;temp = temp->pNext;}cout << "----stack bottom----" << endl;
}
2.3 链式栈 测试主程序
#include "stack.cpp"
#include <string>
#include <iostream>using namespace std;
int main()
{for(int i = 0; i < 10; ++i){int nums = 0;Stack<int> intstack;if(intstack.Empty())cout << "intstack is empty!" << endl;cout << "after push nums: " << endl;while(nums < i){intstack.Push(nums);nums++;}intstack.print();intstack.Pop();cout << "len of stack is " << intstack.GetLength() << endl;if(intstack.GetTop())cout << "top elem is " << intstack.GetTop()->data << endl;if(!intstack.Empty())cout << "intstack is not empty!" << endl;intstack.print();cout << "---------------------------------" << endl;}cout << "以下测试一个字符串是否有非法格式的括号" << endl;char conti = 'y', str;while(conti == 'y'|| conti == 'Y'){bool legal = true;Stack<char> charstack;cout << "please enter a string to check its brackets legal or not !" << endl;while(cin.get(str) && str != '\n') //不断地获取输入的字符{if(str == '{' || str == '[' || str == '(') //遇到左括号不断地压栈{charstack.Push(str);continue;}switch(str) //遇到非左括号{case '}':if(charstack.GetTop() && charstack.GetTop()->data == '{') //栈不为空且栈顶与右括号匹配charstack.Pop(); //删除左括号elselegal = false; //直接遇上右括号,非法;or 栈顶与当前右括号不匹配break;case ']':if(charstack.GetTop() && charstack.GetTop()->data == '[')charstack.Pop();elselegal = false;break;case ')':if(charstack.GetTop() && charstack.GetTop()->data == '(')charstack.Pop();elselegal = false;break;default:break;}if(!legal)break; //如果非法,不必循环了,直接退出}if(legal && charstack.Empty()) //如果合法,且符号都匹配了(栈为空)cout << "legal string !" << endl;else{cout << "illegal string !" << endl;cin.ignore(10000,'\n'); //清除非法字符后面尚未get的字符}cout << "continue? y/n: " ;cin >> conti;cin.get();}return 0;
}