快速入门数据结构之栈

数据结构之栈

程序等于数据结构加算法。
所以,在计算机里面,算法和数据结构相当于最重要的两门课了。以前上课没怎么上心,正好借着写博客的机会好好把数据结构这部分内容整理一下。
栈(stack)是限定仅在表尾进行插入或者删除操作的线性表。
不含元素的空表称为空栈。
在这里插入图片描述

对栈来说,表尾端为栈顶(top),也就是我画的图中的an部分为栈顶元素。表头端称为栈底(bottom),也就是a1部分为栈底元素

栈有另外一种说法是 后进先出 的线性表(简称LIFO结构)。
也就是栈中元素按照a1,a2,a3,…,an的顺序进栈。当出栈的时候再按照an,…,a2,a1的顺序出栈。
所以我们就能看出栈这种数据结构具有后进先出的明显特点。

栈的表示与实现。

与线性表类似,栈也有两种存储表示方法。分别是顺序栈链栈

顺序栈

顺序栈,即栈的顺序储存结构是利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素,也就是本例中存放a1到an的元素,同时附设指针top指示栈顶元素(本例中an)在顺序栈中的位置。
当top=0时,就是an的位置为0,意味着这是一个空栈。
因为像在c语言,Java中的数组下标都是从0开始,所以所以用c或Java作语言时,就不方便。
还因为栈在使用过程中所需要的最大空间的的大小不便估计,所以,一般初始化设空栈时不限定栈的最大容量。

一个合理的做法是,先为栈分配一个基本容量,当我们在应用的时候,如果栈的空间不够使用时再逐步扩大。
我们可以先设定两个常量:
STACK_INT_SIZE(纯纯空间初始分配量)
STACKINCREMENT(储存空间分配增量)
以下类型作为程序栈的定义;

typedef struct{
SElemType *base;
SElemType *top;
int stacksize;
}SqStack;

其中stacksize为栈当前可使用的最大的容量,*base为指向栈底部的指针,*top为指向栈顶部的指针。

*base:

在顺序栈中,始终指向栈底的位置,如果base指向值为NULL,则表示栈结构不存在

*top:

在顺序栈中,*top是变化的,开始时会指向栈底。**如果top=base时,即是栈空的标记。**当插入新的栈顶元素时,指针top就会加1。删除栈顶元素时,指针top就会减1。
在栈中,非空栈中的栈顶指针始终指向栈顶的元素的下一个位置上。
下图表示数据元素和栈顶指针之间的对应关系。
在这里插入图片描述

下面是一些栈的基本操作的算法部分

构造一个空栈
Status InitStack(SqStack &S){
//构造一个空栈
S.base = (SElemType * )malloc(STACK_INIT_SIZE * sizeof(SElemType));
if(!S.base) exit (OVERFLOW);//存储分配失败的情况
S.top=S.base;//栈顶等于栈底
S.stacksize = STACK_INIT_SIZE;//STACK_INIT_SIZE为储存空间初始分配量
return OK;
}
得到栈顶元素
Status GetTop(SqStack S,SElemType &e){
//如果栈不空,则用e返回S的栈顶元素,并且返回OK,否则返回ERROR
if(S.top==S.base) return ERROR;//如果空栈返回error
e =*(S.top-1);//栈顶元素如上图,在top指针下面一个
return OK;
}
插入
Status Push(SqStack &S,SElemType e){
//在栈中插入值为e的新栈顶元素
if(S.top-S.base>=S.stacksize){
S.base = (SElemType *)realloc (S.base,(S.stacksize + STACKINCREMENT) * sizeof(SElemType));
if(!S.base) exit (OVERFLOW);//储存分配失败
S.top = S.base + S.stacksize;
S.stacksize += STACKINCREMENT;//新储存空间等于旧的加要加的
 }
 *S.top++ =e;//指针上移
 return OK;
}
删除栈顶元素
Status Pop(SqStack &S,SElemType e){
//若栈不空,则删除S的栈顶元素,用e返回值,
if(S.top==S.base) return ERROR;
e = * --S.top;
return OK;
}

链栈

链栈也是栈。
链栈是指采用链接存储的结构实现的栈。看上去与列表相像。下面是我手画的图。
在这里插入图片描述

其中data为数据,next为下一个数据的指针。
就这样把数据链接起来。
需要注意的是链栈不存在栈满的情况,不用像正常的顺序栈一样去判断是否栈满。

链栈置空算法
LinkStack * SetStack(){
    LinkStack *LS;
    LS=NULL;
    return LS;
}
链栈取顶
datatype GetTop(LinkStack *LS,ELemType &e){
    if(LS!=NULL) e=LS->data;
    return OK;
    else
       return ERROR;
}


栈被经常用到是因为具有后进先出的特点。所以当我们在编程时,如果目标需要这个特点,那么就往栈方面去考虑吧。下次再写一篇博客探讨栈的实际应用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数据结构与算法是计算机科学中非常重要的一部分,学习好它们对于程序员来说是非常有益的。以下是我推荐的一些快速入门数据结构与算法的方法: 1. 学习基本概念和术语:在学习数据结构和算法之前,我们需要了解基本概念和术语,例如数组、链表、、队列、图、树等等,同时也需要掌握一些基本的算法概念,例如排序、查找、递归等等。 2. 选择合适的学习资源:可以选择一些经典的教材或者在线课程来学习,例如《算法导论》、《数据结构与算法分析》、LeetCode、Coursera等等,这些资源都可以帮助您快速入门数据结构与算法。 3. 刷题:刷题是学习算法的最好方法之一,可以通过一些在线刷题平台,例如LeetCode、LintCode、牛客网等等来练习算法。 4. 参加编程竞赛:参加编程竞赛可以让您更快地掌握数据结构与算法,例如ACM、ICPC等等,这些竞赛都需要掌握一定的算法和数据结构知识。 5. 实践项目:在实际项目中,我们也会用到一些数据结构和算法,例如搜索、排序、图像处理等等,因此在实践项目中掌握数据结构和算法也是非常有益的。 总之,学习数据结构与算法需要持续的练习和实践,通过不断的刷题和参加编程竞赛来增强自己的算法和数据结构能力,同时也需要选择合适的学习资源来深入了解算法和数据结构的原理和应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值