数据结构之栈

来源:互联网 发布:樱井知香番号大全 编辑:程序博客网 时间:2024/06/15 10:32

一、栈的定义

  1.栈是一种特殊的线性表;
  
  2.栈只能在线性表的一端进行操作。即只允许在栈顶(Top)操作,而不允许在栈底(Bottom)操作。
  

二、栈的特性

  由于栈只允许在栈顶(Top)操作,故栈的特性为后进先出(Last In First Out)。如下图所示:
  这里写图片描述
(注:此图引用自狄泰软件学院唐老师ppt)

三、栈的操作

  • 创建栈(Stack())
  • 销毁栈(~Stack())
  • 清空栈(clear())
  • 进栈(push())
  • 出栈(pop())
  • 获取栈顶元素(top())
  • 获取栈的大小(size())

四、栈的实现

1.栈的抽象实现:

Stack.h

#ifndef STACK_H#define STACK_Hnamespace Stack {template <typename T>class Stack{public:    virtual void push(const T& e) = 0;    virtual void pop() = 0;    virtual T top() = 0;    virtual void clear() = 0;    virtual int size() const = 0;};}#endif // STACK_H

2.静态栈的实现:

设计要点:
  1.使用原生数组作为栈的存储空间;
  
  2.栈的存储空间在创建栈的时候指定(由模板参数指定),且不能动态的改变。

下面给出静态栈的具体实现:

StaticStack.h

#ifndef STATICSTACK_H#define STATICSTACK_H#include "Stack.h"#include "Exception.h"namespace Stack {template <typename T, int N>class StaticStack : public Stack<T>{protected:    T m_space[N];    int m_top;    int m_size;public:    StaticStack()    {        m_top = -1;        m_size = 0;    }    int capacity() const    {        return N;    }    void push(const T& e)    {        if (m_size < N) {            m_space[m_top + 1] = e;     // 先赋值,再改变m_top 和m_size,是为了异常安全            m_top ++;            m_size ++;        } else {            throw("No space in current stack ...");        }    }    void pop()    {        if (m_size > 0) {            m_top --;            m_size --;        } else {            throw("No element in current stack ...");        }    }    T top()    {        if (m_size > 0) {            return m_space[m_top];        } else {            throw("No element in current stack ...");        }    }    void clear()    {        m_top = -1;        m_size = 0;    }    int size() const    {        return m_size;    }};}#endif // STATICSTACK_H

3.链式栈的实现

  由于静态栈一次性创建指定大小的空间,如果栈的数据元素为类类型的话,就需要调用N次构造函数,故效率会比较低;另静态栈没法动态的改变栈的大小。
  
  基于以上两点,链式栈便可以解决上述两个问题。

设计要点:
  1.用类模板实现,是抽象父类Stack的直接子类;
  
  2.内部实现一个单链表;
  
  3.只在单链表成员对象的头部进行操作。

下面给出链式栈的具体实现:

LinkStack.h

#ifndef LINKSTACK_H#define LINKSTACK_H#include "Stack.h"namespace Stack {template <typename T>class LinkStack : public Stack<T>{protected:    struct Node {        T value;        struct Node* next;    };    // 为了防止泛指类型T在构造函数中抛出异常,导致栈初始化失败,故重新实现头结构    struct {        char reserved[sizeof(T)];        Node* next;    } m_header;    int m_length;public:    LinkStack()    {        m_length = 0;        m_header.next = NULL;    }    void push(const T& e)    {        Node* node = new Node();        if (node) {            node->value = e;            if (0 == m_length) {                m_header.next = node;            } else {                node->next = m_header.next;                m_header.next = node;            }            m_length ++;        } else {            throw("No memory to create node ...");        }    }    void pop()    {        if (m_length > 0) {            Node* toPop = m_header.next;            m_header.next = toPop->next;            m_length --;            delete toPop;        } else {            throw( "No element in current stack ...");        }    }    T top()    {        if (m_length > 0) {            return m_header.next->value;        } else {            throw( "No element in current stack ...");        }    }    void clear()    {        while (m_length > 0) {            pop();        }    }    int size() const    {        return m_length;    }};}#endif // LINKSTACK_H
原创粉丝点击