数据结构基础学习——栈的概念及代码实现

1栈的概念

栈和顺序表、链表一样是属于线性表的一种,栈的特性和顺序表及链表有很大的不同,其他两种结构都支持在头部和尾部还有中部的插入、删除和查找,但栈只能在线性表的一端进行插入数据和删除数据等操作。栈对数据的操作遵循==“后入先出”==原则,即先放入栈中的数据拿出来的时候顺序就靠后。这种概念通过画图更有助于理解,如图
在这里插入图片描述
数据从表的一段插入到表中,表的另一端不能进行任何操作,这一端称为栈的栈底,而放入数据的一端称为栈顶,插入数据称为压栈,也可以从栈顶不断的拿出数据直至空栈,拿出数据称为出栈。出栈如图示:

在这里插入图片描述
就像上面两幅图是,假定有数据元素1,2,3,4.当进栈顺序是1<-2<-3<-4时,那么依次出栈的顺序就是4<-3<-2<-1了。这种数据运行的规律就好像给一个弹夹装子弹一样,弹夹就是栈,子弹是一个个的数据,不断加入到弹夹中,子弹打出来的时候是后装入的先打出来,还比如老师改作业时的场景,先交的作业放在下面,后交的在上面,改作业时是从上面一本本拿出来改,生活中这种“后入先出”的场景还有很多,就不一一列举了。对栈的操作一次压入一个数据,或弹出一个数据,上面元素1,2,3,4,不改变进栈顺序,但可以有多种出栈顺序,出栈可以是2<-1<4-<3这里就是先连续压入1,2,再弹出来,然后压入3,4,再弹出来。

2.栈的代码实现

栈可以在顺序表或链表的基础上改进之后就实现了,因为栈跟这两种线性表相比就是少了好多的功能,栈只需在一端插入数据,删除数据即可。当用顺序表来实现栈时,只要实现顺序表的尾插和尾删这样的功能就行了,而且顺序表有可以随机访问的作用,比用链表来实现时效率要高,这里我用顺序表来实现栈。
先在头文件中定义一下栈的存储结构,显示要存的数据类型,容量和当前元素个数。

typedef int Datatype;
typedef struct STACK
{
	Datatype* a;
	int top;
	int capacity;
}ST;

在test.c文件中创建一个这种结构体类型的变量

ST Sta;

然后在头文件中声明要实现栈操作的各种函数。

void stackinit(ST* plist);       //对栈的初始化
void stackdestory(ST* plist);      //栈的销毁
void stackpush(ST* plist,Datatype);        //压入数据到栈中
void stackblus(ST* plist);        //增容函数
Datatype stackpop(ST* plist);     //从栈中弹出数据
int stacksize(ST* plist);    //  计算栈中的数据元素个数
void stackdelete(ST* plist);   //栈的元素删除
bool stackEmpty(ST* plist);    //判断栈是否为空

在stack.c源文件中定义头文件中声明的各个函数

#include"stack.h"
void stackinit(ST*plist)
{
	plist->a = NULL;
	plist->capacity = plist->top = 0;
}
void stackpush(ST* plist,Datatype x)
{
	if (plist->top == plist->capacity)
		stackblus(plist);
	plist->a[plist->top] = x;
	plist->top++;
}
void stackblus(ST* plist)
{
	int newcapacity = (plist->top == 0) ? 4 : (2 * (plist->top));
	Datatype* tem = (Datatype*)realloc(plist->a, newcapacity* sizeof(Datatype));
	assert(tem);
	plist->a = tem;
	plist->capacity = newcapacity;
}
void stackdestory(ST* plist)
{
	free(plist->a);
	plist->a = NULL;
	plist->capacity = plist->top = 0;
}
Datatype stackpop(ST* plist)
{
	assert(plist->top);     //空栈没有数据可以弹出
	Datatype tem = plist->a[plist->top-1];
	plist->top--;
	return tem;
}
int stacksize(ST* plist)
{
	return plist->top;
}
void stackdelete(ST* plist)
{
	assert(plist->top); //判断是否还有元素可删
	plist->top--;
}
bool stackEmpty(ST* plist)
{
	if (plist->top)
		return true;
	else
		return false;
}

最后就可以在test.c中测试栈的各种操作了

void test1()
{
	ST Sta;
	stackinit(&Sta);
	stackpush(&Sta, 1);
	stackpush(&Sta, 2);
	stackpush(&Sta, 3);
	Datatype a = stackpop(&Sta);
	printf("%d ", a);
	a = stackpop(&Sta);
	printf("%d ", a);
	a = stackpop(&Sta);
	printf("%d ", a);
}
int main()
{
	test1();
	return 0;
}

在这里插入图片描述

结束语

博客刚开始写,写的比较粗糙,不过也是一个不断学习的过程,我会向大佬看齐的,提高自己的表达能力,对知识总结更加到位,大家一起加油。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值