棧是一種只允許在一端進行插入或刪除操作的線性表.其特點爲:先進後出(FILO)/後進先出(LIFO);
棧 VS. 隊列
棧和隊列都是動態集合, 但在棧中, 可以去掉的是最近插入的那一個,:棧實現了一種後進先出(last-in, first-out)的策略;類似的, 在隊列中, 可以去掉的元素總是在集合中存在時間最長的那一個:隊列實現了先進先出(first-in, first-out)的策略[下一篇我們着重複習隊列].
棧的示意圖:
- //順序棧的實現與解析
- template <typename Type>
- class MyStack
- {
- template <typename T>
- friend ostream &operator<<(std::ostream &os, const MyStack<T> &stack);
- public:
- MyStack(int stackCapacity = 16);
- ~MyStack();
- bool isEmpty() const;
- void push(const Type &item);
- void pop() throw (std::range_error);
- const Type &top() const throw(std::range_error);
- private:
- Type *m_stack;
- int m_top;
- int m_capacity;
- };
- template <typename Type>
- MyStack<Type>::MyStack(int stackCapacity):m_capacity(stackCapacity)
- {
- if (m_capacity < 1)
- throw std::range_error("new size must >= 1");
- //申請內存並構造對象
- m_stack = new Type[m_capacity];
- if (m_stack == NULL)
- throw std::bad_alloc();
- m_top = -1;
- }
- template <typename Type>
- MyStack<Type>::~MyStack()
- {
- //析構對象並釋放內存
- delete []m_stack;
- m_stack = NULL;
- m_top = -1; //將top指針指向無效
- m_capacity = 0;
- }
- //全局函數:數組放大/縮小
- template <typename Type>
- static void changeSize1D(Type *&array, int oldSize, int newSize)
- throw (std::range_error, std::bad_alloc)
- {
- if (newSize < 0)
- throw std::range_error("new size must >= 0");
- Type *tmp = new Type[newSize];
- if (tmp == NULL)
- throw std::bad_alloc();
- int minSize = std::min(oldSize, newSize);
- std::copy(array, array+minSize, tmp);
- delete []array; //將原數組釋放掉
- array = tmp; //將原指針指向新申請的數組
- }
- template <typename Type>
- void MyStack<Type>::push(const Type &item)
- {
- //數組最大容量爲m_capacity, 因此數組的最大下標爲m_capacity-1
- if (m_top >= m_capacity-1)
- {
- changeSize1D(m_stack, m_capacity, m_capacity * 2); //一次擴容2倍
- m_capacity *= 2;
- }
- //將元素插入棧頂
- m_stack[++ m_top] = item;
- }
- //棧是否爲空
- template <typename Type>
- inline bool MyStack<Type>::isEmpty() const
- {
- return -1 == m_top;
- }
- template <typename Type>
- inline const Type &MyStack<Type>::top() const
- throw (std::range_error)
- {
- if (isEmpty())
- throw std::range_error("stack is empty");
- return m_stack[m_top]; //返回棧頂元素
- }
- template <typename Type>
- inline void MyStack<Type>::pop()
- throw (std::range_error)
- {
- if (isEmpty())
- throw std::range_error("stack is empty");
- //注意:如果該棧保存的對象類型的元素, 則需要顯示調用其析構函數,
- //同時還需要將棧頂指針下移
- m_stack[m_top --].~Type();
- }
- //輸出棧的所有內容,以便測試
- template <typename Type>
- ostream &operator<<(ostream &os, const MyStack<Type> &stack)
- {
- os << stack.m_stack[0];
- for (int i = 1; i <= stack.m_top; ++i)
- os << ' ' << stack.m_stack[i];
- return os;
- }
附-測試代碼
- int main()
- {
- MyStack<int> iStack;
- iStack.push(10);
- iStack.push(22);
- iStack.push(15);
- cout << iStack << endl;
- try
- {
- cout << "Top = " << iStack.top() << endl;
- iStack.pop();
- cout << "Top = " << iStack.top() << endl;
- iStack.pop();
- cout << "Top = " << iStack.top() << endl;
- iStack.pop();
- cout << "Top = " << iStack.top() << endl;
- }
- catch (const std::exception &e)
- {
- cout << e.what() << endl;
- }
- }
原文地址:http://blog.csdn.net/zjf280441589/article/details/42367201