栈的实现:顺序栈

数据结构与算法 同时被 2 个专栏收录
50 篇文章 0 订阅
49 篇文章 63 订阅

栈(stack)是一种很常见的线性结构。它是只允许在一端进行插入和删除操作的线性表,这一端我们称为栈顶。栈的特点常被称为:先进后出(filo-first int last out),或者是后进先出(lifo-last in first out)。这个描述从它的操作特点可以看出,只许在一端进行插入,那么显然,先进的肯定后出。栈的应用,比如系统应用栈来实现递归,图的深度遍历使用了栈,递归要用到栈……。说到它的实现就有两种形式:顺序栈、链栈。其中以顺序栈最为常见。

栈的常见操作:

  1. push() 入栈
  2. pop() 出栈
  3. top() 获取栈顶元素
  4. size() 获取栈的大小
  5. empty() 判断栈是否为空

看下图:


其中 base 是栈底指针,top是栈顶指针,我们会发现,top指向栈中元素的下一个位置。若top为0,则表明栈为空。

在代码中我们用stop(stack top)代替top,因为top指针和top()函数命名有冲突。

说明:

  1. 我们对栈设置一个初始的大小 STACKSIZE。
  2. 当栈满了,我们得扩充大小,每次增加 INCREMENT,并且把原栈中的元素赋值过去。
  3. 常见操作的名称设计参考STL,要想使用STL提供的栈,使用#include<stack>。
  4. 栈的实现很多,不必要强调标准,根据实际问题特点设计即可。重点是,栈这种数据结构的特点的掌握。
  5. 栈为空时的判断,和栈为满时的判断,是重点。

类定义和类实现

#include<iostream>
#include<iomanip>
using namespace std;
typedef int ElemType;    //栈中数据类型  
#define STACKSIZE 10     //栈的默认大小  
#define INCREMENT 10     //增量  
//顺序栈定义  
class SqStack    //sequential stack  
{  
private:  
    ElemType *base;    //栈底指针  
    int stop;  //栈顶指针 stack top  
public:  
    SqStack();    //默认构造函数  
    ~SqStack();   //析构函数  
    void clear();  //栈清空  
    void push(ElemType value);   //进栈  
    void pop();    //出栈  
    ElemType top();     //获取栈顶元素  
    int size();     //获取栈的大小  
    bool empty();       //栈是否为空  
    void stackTraverse(void(*)(ElemType));   //遍历栈  
};  
//栈实现  
SqStack::SqStack()   //构造函数,初始化栈,分配默认空间大小  
{  
    /* c的写法 
    base = (ElemType*)malloc(sizeof(ElemType)*STACKSIZE); 
    */  
    base = new ElemType[STACKSIZE];  
    stop = 0;  
}  
SqStack::~SqStack()   //析构函数  
{  
    delete[]base;  
}  
void SqStack::clear()  //栈清空  
{  
    stop = 0;  
}  
void SqStack::push(ElemType value)  
{  
    //入栈前先检查栈是否满了  
    if (stop != 0 && (stop - STACKSIZE) % INCREMENT == 0)   //栈满,则扩大空间  
    {  
        /* c的写法 
        base = (ElemType*)realloc(base, sizeof(stop + INCREMENT)); 
        */  
        ElemType *b = new ElemType[stop + INCREMENT];  
        for (int i = 0; i < stop; i++)  
            b[i] = base[i];  
        delete[]base;  
        base = b;  
    }  
    base[stop++] = value;  
}  
void SqStack::pop()    //出栈  
{  
    //出栈前检查栈是否为空  
    if (empty())  
        return;  
    stop--;  
}  
ElemType SqStack::top()  //获取栈定元素  
{  
    if (stop == 0)  
        return NULL;  
    return base[--stop];  
}  
int SqStack::size()  //获取栈的大小  
{  
    return stop;  
}  
bool SqStack::empty()    //判断栈是否为空  
{  
    return stop == 0;  
}  
void SqStack::stackTraverse(void (*visit)(ElemType item))  
{  
    int p = stop;  
    while (p >= 1)  
    {     
        p--;  
        visit(base[p]);  
    }  
    cout << endl;  
}  
void visit(ElemType item)  
{  
    cout << setw(4)<<item;  
}


主函数

int main()     //主函数
{
	printf("顺序栈的演练\n");
	SqStack stack;
	ElemType value;
	cout << "输入栈中元素,0结束" << endl;
	while (cin >> value && value != 0)
		stack.push(value);
	cout << "栈遍历" << endl;
	stack.stackTraverse(visit);
	cout << "删除栈顶元素" << endl;
	stack.pop();
	cout << "栈遍历" << endl;
	stack.stackTraverse(visit);
	cout << "获取栈顶元素 " << stack.top() << endl;
	cout << "清空栈操作:";
	stack.clear();
	stack.empty() ? cout << "栈空!" <<endl: cout << "栈不为空!" << endl;
	cout << "重新入栈" << endl;
	while (cin >> value && value != 0)
		stack.push(value);
	cout << "栈遍历" << endl;
	stack.stackTraverse(visit);
	system("pause");
	return 0;
}
运行



完整代码下载:栈的实现:顺序栈


尝试:用栈实现进制转换,这个很简单,可以动手试试。参考看一楼。


至于链栈的写法,就和链表差不多了。唯一区别在于:head指针这头是栈顶,有且只能在这头进行插入和删除操作。链表是可以在任何地方进行插入和删除操作的,链栈这里就显得更加easy了。


专栏目录:


  • 6
    点赞
  • 1
    评论
  • 12
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值