数据结构之栈

栈是应用最广泛的数据结构之一,很有必要对其进行一些总结。

栈(stack)是限制插入和删除只能在一个位置上进行的表,该位置是表的末端,叫做栈的顶(top),它是后进先出(LIFO)的。

对栈的基本操作只有push(进栈)和pop(出栈)两种,前者相当于插入,后者相当于删除最后的元素。

栈本质上是一种受限制的表,所以可以使用任何一种表的形式来实现它,最常用的是使用链表数组

使用链表的特点:

不需要指定其大小,不会浪费空间;
进栈和出栈涉及到动态内存的申请释放,时间花销大;

使用数组的特点:

需要指定其大小,有可能浪费空间,也可能空间不够用;
进栈和出栈不涉及动态内存的申请释放,因此时间上几乎没有花销;
另外支持随机存取。

结论:
一般使用链表是首选,除非满足两个条件:
1.对运行时的效率要求极高;
2.能够预知栈需要的空间大小。

使用数组的完整代码:

//头文件
#ifndef STACK_H
#define STACK_H
#include <iostream>

using std::cout;
using std::endl;

class CStack
{
public:
    CStack();
    ~CStack();

    bool Empty(){ return top == -1; }

    bool Full(){ return top == MAXSIZE; }

    int GetTop(){ return Data[top]; }

    int GetSize(){ return (top + 1); }

    void Size_Increament();

    void Push(int x);
    void Pop();
    void Display();


private:
    int *Data;
    int top;
    int MAXSIZE;
    const int SizeIncreament = 50;

};//分号不可少


#endif


//实现文件
#include "stack.h"

CStack::CStack()
{
    Data = new int[MAXSIZE];
    top = -1;
    MAXSIZE = 100;
}

CStack::~CStack()
{
    delete []Data;
}

void CStack::Size_Increament()
{
    int *newData= new int[MAXSIZE + SizeIncreament];
    if (newData == NULL)
    {
        std::cerr << "存储分配失败!" << endl;
        exit(1);
    }
    for (int i = 0; i <= top; ++i)
        newData[i] = Data[i];

    MAXSIZE = MAXSIZE + SizeIncreament;

    delete []Data;
    Data = newData;
}

void CStack::Push(int x)
{
    if (Full())
    {
        cout << "栈已满!扩容!" << endl;
        Size_Increament();
    }

    else
    {
        top++;
        Data[top] = x;
    }
}

void CStack::Pop()
{
    if (Empty())
    {
        cout << "栈已空!" << endl;
        return;
    }
    else
    {
        cout << Data[top--] << endl;
    }
}

void CStack::Display()
{
    if (Empty())
    {
        cout << "栈已空!" << endl;
        return;
    }
    else
    {
        for (int i = 0; i <= top; ++i)
            cout << Data[i] << " ";
        cout << endl;
    }
}


//测试文件
#include "stack.h"

int main()
{
    CStack cstack;

    cout << "当前栈中元素有:" ;
    cstack.Display();

    cout << "弹出元素是:";
    cstack.Pop();

    for (int i = 0; i < 10;++i)
        cstack.Push(i);

    cout << "压入元素后:";
    cstack.Display();

    cout << "弹出元素是:";
    cstack.Pop();

    cout << "弹出元素后:";
    cstack.Display();

    cout << "当前栈顶元素:" <<cstack.GetTop();
    cout << endl;


    system("pause");
    return 0;
}

使用链表的完整代码:

//头文件
#ifndef LINKSTACK_H
#define LINKSTACK_H
#include <iostream>

struct Node
{
    int data;
    Node *next;

};

class LinkStack
{
public:
    LinkStack(){ top = NULL; }
    ~LinkStack();

    int GetTop(){ return top->data; }
    void Push(int x);
    int Pop();
    bool Empty(){ return (top == NULL) ? 1 : 0; }
    void Display();

private:
    Node *top;


};

#endif // !LINKSTACK_H

//实现文件

#include "linkstack.h"

LinkStack::~LinkStack()
{
    Node *p;
    while (top != NULL)
    {
        p = top;
        top = top->next;
        delete p;

    }
}

void LinkStack::Push(int x)
{
    Node *s = new Node;
    s->data = x;
    s->next = top;
    top = s;
}

int LinkStack::Pop()
{
    if (Empty())
    {
        std::cout << "链栈为空,不可删除!" << std::endl;
    }
    else
    {
        int x = top->data;
        Node *p = top;
        top = top->next;
        delete p;
        return x;
    }
}

void LinkStack::Display()
{
    Node *p = top;

    while (p != NULL)
    {
        std::cout << p->data << " ";
        p = p->next;
    }
}



//测试文件

#include "linkstack.h"

using std::cout;
using std::endl;

int main()
{
    LinkStack ls;
    for (int i = 0; i < 5; ++i)
        ls.Push(i);
    cout << "链栈的元素是:";
    ls.Display();
    cout << "栈顶元素是:";
    cout << ls.GetTop() << endl;
    cout << "删除的元素是:";
    cout << ls.Pop() << endl;
    cout << "栈顶元素是:";
    cout << ls.GetTop() << endl;

    system("pause");
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

posted @ 2015-09-17 17:07  taxue505  阅读(164)  评论(0编辑  收藏  举报