数据结构与算法-栈(顺序栈 链式栈 共享空间栈 递归栈)

春风十里一枝花的小孱弱弱又来了,至此线性表的内容就结束了,这一篇文章我们讨论特殊的表——栈,这里的栈可不是我们学习内存管理中的堆区栈区那个栈,这里的栈是一种数据结构,向仔细了解,请继续往下阅读吧。
不知道大家有没有玩过羽毛球,装羽毛球的筒子,我们先放进取的羽毛球在筒子的最底下,我们随后一个放进去的在最上面,羽毛球全放进去了怎么往外拿呀,阵势明知故问哈哈哈,一个一个往外拿呗,此时不知道大家有没有发现,我们后放进去的是最先拿出来的,子一个放进去的,是最后一个拿出来的。这就是数据结构-栈的定义。
栈是仅在表尾进行删除和插入操作的特殊线性表。简称LIFO。
我们把允许插入的一端叫做栈顶top,另一端就做栈底。
栈的插入操作成为入栈或者压栈。
栈的删除操作成为出栈或者弹栈。
先说一下顺序栈,其实和顺序表极其类似,只不过插入和删除规定只能在表尾。
至于是链式栈,依然是一个节点指向一个节点,具体请去看表的单链表操作:
点击跳转单链表详解
我们先看代码,来人,上代码:

//顺序栈定义
typedef struct
{
	int  data[MAXN];
	
	int top;
}SqStack;
//增
int Push(SqStack *S,int e)
{
	if(S->top==MAXN-1)
		return false;
		
	S->top++;
	
	S->data[S->top]=e;
	
	return true;
	
	
 } 
//删
int Pop(SqStack *S,int *e)
{
	if(S->top==-1)
		return false;
		
	*e=S->data[S->top];
	
	S->top--;
	
	return true;
 } 
//共享空间栈 
typedef struct
{
	int data[MAXN];
	
	int top1;
	
	int top2;
	
	
 } SqDoubleStack;
//增
int Push(SqDoubleStack *S,int e,int stackNumber)
{
	if(S->top1+1==S->top2)
		return false;
		
	if(stackNumber==1)
		S->data[++S->top1]=e;
	else if(stackNumber==2)
	 S->data[++S->top2]=e;
	
	return true;
	
 } 
//删
int Pop(SqDoubleStack *S,int *e,int stackNumber)
{
	if(stackNumber ==1)
	{
		if(S->top1==-1)
			return false;
		*e=S->data[S->top1--];
	
	 } 
	else if(stackNumber==2)
	{
		if(S->top2==MAXN)
			return false;
		 
		*e=S->data[S->top2++];
		
	}
	
	return true;
}
//链式栈定义 (数据部分)
typedef struct StackNode
{
	int data;
	
	struct StackNode*next;

}StackNode,*LinkStackPtr;
typedef  struct LinkStack//(栈顶指针)
{
	LinkStackPtr top;	
	
	int count;

 } LinkStack;
//增(进栈)
int Push(LinkStack *S,int e)
{
	LinkStackPtr s=(LinkStackPtr)malloc(sizeof(StackNode));
	
	s->data=e;
	
	s->next=S->top;

	S->top=s;
	
	S->count++;
	
	return true;

 } //删(出栈)
 int  Pop(LinkStack *S,int *e)
 {
 	LinkStackPtr p;
 	
 	if(S->count<0)
 		return false;
 		
 	*e=S->top->data;
 	
 	p=S->top;
 	
 	S->top=S->top->next;
 	
 	free(p);
 	
 	S->count--;
 	
 	return true;
 	
 	
 	
  } 	 

无论是顺序栈还是链式栈,定义和操作像极了顺序表和单链表,其实链式栈就是特殊的单链表,顺序栈就是特殊的顺序表。
下面是栈的重要应用——递归:
由于栈只在表尾的操作,递归函数就是使用了这个原理,那什么是递归呢,递归其实就是函数调用自己,这里有注意点,递归必须有停下来的条件,而且递归次数不能太大。
为什么呢,一个递归函数,第一次调用时,将函数体压入栈内,我们的cpu的控制器跟进代码,执行到下一次调用时,在一个将函数体压入栈内,就这样一次次入栈,直到达成了不能调用的条件,递归调用停止,但是不要以为这就结束了,还有出栈呢,最后一次的递归函数结束,然后继续栈顶函数结束,一直到栈底最后一个函数结束,这个“大”递归函数才算是结束,这就是真实的计算机内存中调用递归函数的状态,当然,我们分享的是以逻辑内存层面说的,在瑞吉内存到真实的物理内存层面那是由我们的操作系统捣鼓了,就不关我们的事啦哈哈哈,当你继续学习学习到操作系统的时候会有深入了解,稍微透露一下,一般是段页式存储~

好了今天的数据结构栈的介绍就到尾声了,如果你对链表和顺序表理解的比较好,应该没问题,加油!!
小孱弱弱会陆陆续续发一些数据结构的高级应用,文章如果由不太对的地方,欢迎批评指教,一定虚心接受。

猜你喜欢

转载自blog.csdn.net/weixin_47644373/article/details/106163720
今日推荐