数据结构-------栈

栈是一种特殊的线性表,仅能在线性表的一端操作,栈顶允许操作,栈底不允许操作。
栈的特性:后进先出。

1.顺序栈

(1)顺序栈的的存储结构(底层是数组实现的,就涉及到数组的容量问题;)

typedef int  ElemType;//便于修改要存储的数据类型;

typedef struct stack
{
	ElemType *data;
	int size;
	int top;
}Stack, *pStack;



(2)、栈的初始化(自定义默认给了一个合适的SiZE)

void InitStack(pStack stack)
{
    assert(stack != NULL);
 
    stack->data = (ElemType *)malloc(sizeof(ElemType)* SIZE);
    assert(stack->data != NULL);
 
    stack->size = SIZE;
    stack->top = 0; //  -1
}


(3)、栈的判空判满以及扩容

void Expand(pStack stack)   //扩容函数
{
    assert(stack != NULL);
 
    ElemType *s = (ElemType*)malloc(sizeof(ElemType)* stack->size * 2);
    assert(s != NULL);
 
    for (int i = 0; i < stack->top; ++i)//因为底层是数组,大小是确定的,扩容时要开辟更大的数组,把值拷贝过来,更不要忘记删除以前的数组,不然会导致内存泄漏。
    {
        s[i] = stack->data[i];
    }
 
    free(stack->data);
    stack->data = s;
    stack->size *= 2;
}


 

int IsFull(pStack stack)     //判满
{
    assert(stack != NULL);
 
    if (stack->top == stack->size)//栈顶指针等于栈的大小就满了
    {
        return TRUE;
    }
 
    return FALSE;
}


 

int IsEmpty(pStack stack)  //判空
{
    assert(stack != NULL);
 
    if (stack->top == 0)
    {
        return TRUE;
    }
 
    return FALSE;
}


当栈的top与size相等时即为栈满,这是我们需要对其进行扩容,增大栈的大小。

当栈的top为0时栈为空,此时不可删除栈中的数据。

 

4、入栈函数(push)

int Push(pStack stack, ElemType val)
{
    assert(stack != NULL);
 
    if (IsFull(stack))
    {
        Expand(stack);
        if (IsFull(stack))
        {
            return FALSE;
        }
    }
 
    stack->data[stack->top++] = val;
 
    return TRUE;
}


在向栈中插入数据时需要先进行判满,如果栈此时未满,则可以直接进行插入,否则,需要为其增加空间,注意极端值的判断。

 

(5)、出栈函数(pop)

int Pop(pStack stack, ElemType *res)
{
    assert(stack != NULL);
 
    if (IsEmpty(stack))
    {
        return FALSE;
    }
 
    *res = stack->data[--stack->top];
 
    return TRUE;
}


出栈时则需要对其进行判空,如果为空,则不允许进行出栈,若不为空,可直接出栈。

 

(6)、栈的销毁

void DestoryStack(pStack stack)
{
    assert(stack != NULL);
 
    free(stack->data);
    stack->data = NULL;
    stack->size = 0;
    stack->top = 0;
}


C++实现:

基本的储存储结构及一些方法

typedef int  ElemType;
 
class Stack
{
private:
    ElemType *_data;
    int _top;
    int _size;
    bool IsFull();    //判满
    bool IsEmpty();    //判空
    void Expand();    //扩容
public:
    Stack();
    Stack(const Stack &src);    //拷贝构造函数
    Stack& operator= (const Stack& src);    //等号运算符的重载
    ~Stack();  
    void Push(ElemType val);    //入栈
    bool Pop();    //出栈
    ElemType GetTop();    //取栈顶元素
    void show();    //打印整个栈
};
bool Stack::IsFull()
{
    assert(this != NULL);
    if (_top == _size)
    {
        return true;
    }
    return false;
}
bool Stack::IsEmpty()
{
    assert(this != NULL);
    if (_top == 0)
    {
        return true;
    }
    return false;
}
void Stack::Expand()
{
    assert(this != NULL);
    ElemType *s = new ElemType[SIZE * 2];
    assert(s != NULL);
 
    for (int i = 0; i < _top; ++i)
    {
        s[i] = _data[i];
    }
 
    delete[]_data;
    _data = s;
    _size *= 2;
}
Stack::Stack()
{
    assert(this != NULL);
    _data = new ElemType[SIZE];
    assert(_data != NULL);
    _top = 0;
    _size = SIZE;
}
Stack::Stack(const Stack &src)
{
    _data = new ElemType[sizeof(src._data)];
    for (int i = 0; i < src._top; i++)
    {
        _data[i] = src._data[i];
    }
    _top = src._top;
    _size = src._size;
}
Stack& Stack::operator= (const Stack& src)
{
    if (this == &src)
    {
        return *this;
    }
    if (_data != NULL)
    {
        delete[]_data;
    }
    _data = new ElemType[sizeof(src._data)];
    for (int i = 0; i < src._top; ++i)
    {
        _data[i] = src._data[i];
    }
    _top = src._top;
    _size = src._size;
 
    return *this;
}
Stack::~Stack()
{
    if (NULL != _data)
    {
        delete[]_data;
        _data = NULL;
        _top = 0;
        _size = 0;
    }
}
 
void Stack::Push(ElemType val)
{
    assert(this != NULL);
    if (IsFull())
    {
        Expand();
    }
    _data[_top++] = val;
}
bool Stack::Pop()
{
    assert(this != NULL);
 
    if (IsEmpty())
    {
        return 0;
    }
    _top--;
    return 1;
}
ElemType Stack::GetTop()
{
    assert(this != NULL);
 
    if (IsEmpty())
    {
        return 0;
    }
 
    return _data[_top - 1];
}
void Stack::show()
{
    assert(this != NULL);
 
    for (int i = 0; i < _top; i++)
    {
        cout << _data[i] << " ";
    }
    cout << endl;
}


二、链式栈


链式栈是一种数据存储结构,可以通过单链表的方式来实现,使用链式栈的优点在于它能够克服用数组实现的顺序栈空间利用率不高的特点,但是需要为每个栈元素分配额外的指针空间用来存放指针域。

链式栈就是将栈的先进后出的特性与链表相结合起来,顺序栈是利用数组进行的,这样就有一个缺陷,它的大小是固定的,当出现栈满的时候就要进行对栈的扩容,而链式栈有了链表的不是固定内存的好处,这样就不必每次都进行判满来判断是否需要进行扩容。

c++:

#include<iostream>
using namespace std;
 
 
template<typename T>
class Mstack
{
public:
    class Node;
 
    Mstack()
    {
        _head = NULL;
        _top = NULL;
    }
 
    ~Mstack()
    {
        if (_head == NULL)
        {
            return;
        }
 
        while (_top != _head)
        {
            pop();
        }
        delete _head;
        _head = _top = NULL;
    }
 
    void push(T val)
    {
        Node *p = new Node;
        p->_val = val;
        p->_next = NULL;
        if (_head == NULL && _top == NULL)
        {
            _head = p;
            _top = p;
        }
        else
        {
            _top->_next = p;
            _top = p;
        }
    }
 
    int pop()
    {
        if (_head == NULL)
        {
            return -1;
        }
        Node *p = _head;
        while (p->_next != _top)
        {
            p = p->_next;
        }
        delete _top;
        _top = p;
        _top->_next = NULL;
 
    }
 
    T top()
    {
        return _top->_val;
    }
 
    void show()
    {
        Node *p = _head;
        while (p != NULL)
        {
            cout << p->_val << "   ";
            p = p->_next;
        }
        cout << endl;
    }
private:
    class space
    {
    public:
        static space* getSpace()
        {
            if (NULL == _space)
            {
                m.lock();
                if (NULL == _space)
                {
                    _space = new space();
                }
                m.unlock();
            }
 
            return _space;
        }
 
    private:
        space()
        {
            Node *tmp = new Node[LEN];
 
            int i = 0;
            for (; i < LEN - 1; i++)
            {
                tmp[i]._next = &tmp[i + 1];
            }
            tmp[i]._next = NULL;
 
            _pool = &tmp[0];
        }
 
        static space* _space;
        Node* _pool;
 
        friend class Node;
    };
 
 
    class Node
    {
    private:
        T _val;
        Node *_next;
        static space* _space;
    public:
        Node()
        {
            _next = NULL;
        }
 
        Node(T val)
        {
            _val = val;
            _next = NULL;
        }
 
        void *operator new(size_t size)
        {
            cout << "void *operator new(size_t size)" << endl;
            if (_space->_pool == NULL)
            {
                m.lock();
                if (_space->_pool == NULL)
                {
                    Node *tmp = new Node[LEN];
 
                    int i = 0;
                    for (; i < LEN - 1; i++)
                    {
                        tmp[i]._next = &tmp[i + 1];
                    }
                    tmp[i]._next = NULL;
 
                    _space->_pool = &tmp[0];
                }
                m.unlock();
            }
            Node* mem = _space->_pool;
            _space->_pool = _space->_pool->_next;
 
            return mem;
        }
 
        void operator delete(void *p)
        {
            Node *tmp = (Node*)p;
 
            tmp->_next = _space->_pool;
            _space->_pool = tmp;
        }
 
        friend class Mstack;
    };
    Node* _head;
    Node* _top;
};
 
template<typename T>
typename Mstack<T>::space*  Mstack<T>::Node::_space = Mstack<T>::space::getSpace();
 
template<typename T>
typename Mstack<T>::space* Mstack<T>::space::_space = NULL;
 
 
int main()
{
    Mstack<int> s;
    for (int i = 0; i < 10; i++)
    {
        s.push(i);
    }
    s.pop();
    cout << s.top() << endl;
    s.show();
 
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值