栈--线性结构的两种常见线性结构之一

栈的由来

之前的文章中我们介绍了两种线性储存结构的特点,并且实践了两种不同存储结构实现同一功能之间的的实战,并且体会到了他之间的异同,最后我们得到一个启发,就是在线性储存结构中,无论他的储存形式是连续或者非连续,他们都是从头到尾以某一种方式连接着,这种方式可能是存储单元紧挨在一起的个体,也有可能是存储单元之间指针,他们都通过线性的这种方式来展示的,这很好的模拟了内存的物理结构,而正式这种特殊的结构,引发了关于存储单元之间顺序的思考。通过不同的产生,排列,组合所产生的顺序,总结出了在线性结构基础上的遵循不同数组操作顺序的两种特殊的存储结构,其中一种就是今天要介绍的栈

栈的定义和举例

栈的定义:
互联网:栈(Stack)是n个元素a1,a2,…an,组成的有限序列,记作S =(a1,a2,…,an),并且只能在一端插入和删除元素,n=0时称为空栈。
这是我在网上所搜到的答案,我认为这并不是很易于理解并且他概括的概念特超出栈的本质
自己总结:一种可以实现“先进后出”的存储结构
当然对于栈我还有自己的其他理解,但是现在不是和盘托出的时候
在这里插入图片描述

举例
栈类似于箱子,羽毛球桶。上面的东西不拿出来无法拿出下面的东西,先放进去的东西自动在底部
在这里插入图片描述

栈的分类

栈主要可以分类静态栈和动态栈,静态动态如果看过我之前的博客应该很好理解吧
说白了就是内存分配的方式对吧。

栈的算法

主要有两种,一种是压栈(没有夫人),一种是出栈。
压栈:类似于芳羽毛球桶种放东西
出栈:类似于从羽毛球桶中拿东西

实战-----栈(小刀拉屁股的时候到了)

实战目标:展示动态栈的构造构成,出栈和入栈的过程,对栈进行遍历的过程

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
typedef struct Node
{
	int data;
	struct Node* pNext;
}*pnode,node;
typedef struct stack //栈 这是我们来定义我们需要的栈的储存单元
{
	pnode ptop;
	pnode pbottom;
}stack,*pstack;
//函数声明
void initstack(pstack ps);
void pushstack(pstack ps, int val);
void traverse(pstack ps);
bool pop(pstack ps, int* pval);
bool empty(pstack ps);//判断是否为空
void clear(pstack ps);
int main(void)
{
	int val;
	stack s;//等价于struct stack 
	initstack(&s);//目的制造出一个空栈
	pushstack(&s,1);//压栈
	pushstack(&s,2);
	pushstack(&s, 99);
	pushstack(&s, 7);
	pushstack(&s, 6);
	pushstack(&s, 2);
	traverse(&s);//遍历

	
	if (pop(&s, &val))
	{
		printf("出栈成功,出栈的元素是%d\n", val);
	}
	else
	{
		printf("出栈失败");
	}
	traverse(&s);//遍历

	clear(&s);
	traverse(&s);//遍历
	return 0;
}
void initstack(pstack ps)
{
	ps->ptop=(pnode)malloc(sizeof(Node));
	if (NULL == ps->ptop)
	{
		printf("动态内存分配失败");
		exit(-1);
	}
	else
	{
		ps->pbottom = ps->ptop;
		ps->ptop->pNext = NULL;//等价于ps->pbotom->pNext = NULL   这个节点是头结点,所以pNext得空
	}
	return;
}
void pushstack(pstack ps, int val)
{
	pnode pnew = (pnode)malloc(sizeof(node));
	pnew->data = val;
	pnew->pNext = ps->ptop;//ps->ptop
	ps->ptop = pnew;
	return;
}
void traverse(pstack ps)
{
	pnode p=ps->ptop;
	while (ps->ptop!=ps->pbottom)
	{
		printf("%d ",ps->ptop->data);
		ps->ptop = ps->ptop->pNext;
	}
	ps->ptop = p;
	return;
}
//把ps所指向的栈出栈一次,并把出栈的元素存入pval形参所指向的变量中,
														//如果出栈失败返回false出栈成功放回true
bool empty(pstack ps)
{
	if (ps->ptop == ps->pbottom)
		return true;
	else
		return false;
}
bool pop(pstack ps, int *pval)
{
	if (empty(ps))//ps本身存放的就是s的地址
	{
		return false;
	}
	else
	{
		pnode f = ps->ptop;
		*pval = ps->ptop->data;
		ps->ptop = ps->ptop->pNext;
		free(f);
		f = NULL;
		return true;
	}
}
//clear清空
void clear(pstack ps)
{
	if (empty(ps))
		return;
	else
	{
		pnode p = ps->ptop;
		pnode q = NULL;
		while (p!=ps->pbottom)
		{
			q = p->pNext;
			free(p);
			p = q;
		}
		p = NULL;
		q = NULL;
		ps->ptop = ps->pbottom;
	}

}

栈的总结

看完整个栈的程序实战演示,不男发现,栈其实就是一种被砍掉一部分功能的的链表。而为什么要砍掉部分功能形成一个栈呢?这其实是为了更好的对数句进行操作的原因,链表会本省存在一定的弊端,太发达也不是什么好事是吗。任何事情都是两面的,这个我们以后再讲。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值