欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

栈的顺序存储及代码实现

程序员文章站 2022-06-05 13:47:21
...

栈是在数据结构中经常能遇到的,在我们平时也能遇到。比如当我们在打断点调试时,经常能遇到堆栈,先调用的后出来。或者网页的后退键也是栈的应用。

一.栈及其初始化

  • 栈是限定仅在表尾进行插入和删除操作的线性表。
  • 我们把允许插入的一端称为栈顶,另一端称为栈底。
  • 栈称为先进后出,简称FOLI
  • 栈也是线性表,也有前驱后继关系。线性表的表尾是栈顶
  • 栈插入操作叫进栈,入栈
  • 栈删除操作叫出栈

栈的结构
栈的顺序存储及代码实现
栈的顺序存储

#define MAXSIZE 7
typedef int SElemtype;
typedef struct{
	SElemtype data[MAXSIZE];
	int top;
}Stack;

栈的初始化

void Stack_Init(Stack *s,int n)
{
	int i; 
	s->top = n - 1;
	for(i = 0;i < n;i++)
	{
		s->data[i] = i + 10;
		printf("%d  ",s->data[i]);
	}
	printf("\n");
}

二.栈的操作(出栈,入栈)

2.1入栈

因为操作都在栈顶操作,所以时间复杂度都是O(1)

Status Push(Stack *s,SElemtype e)
{
	if(s->top == MAXSIZE - 1)
	return ERROR;
	s->data[++(s->top)] = e;
	return OK;
}

这里就是别忘了栈顶的移动和判断能否入栈

2.2出栈

Status Poll(Stack *s,SElemtype *e)
{
	if(s->top == -1)
	return ERROR;
	*e = s->data[(s->top)--];
	return OK;
}

2.3代码实现:

#include<stdio.h>
#include<stdlib.h>

#define MAXSIZE 7
typedef int SElemtype;
typedef int Status;
#define OK 1
#define ERROR 0
typedef struct{
	SElemtype data[MAXSIZE];
	int top;
}Stack;


void Stack_Init(Stack *s,int n)
{
	int i; 
	s->top = n - 1;
	for(i = 0;i < n;i++)
	{
		s->data[i] = i + 10;
		printf("%d  ",s->data[i]);
	}
	printf("\n");
}
Status Push(Stack *s,SElemtype e)
{
	if(s->top == MAXSIZE - 1)
	return ERROR;
	s->data[++(s->top)] = e;
	return OK;
}

Status Poll(Stack *s,SElemtype *e)
{
	if(s->top == 0)
	return ERROR;
	*e = s->data[(s->top)--];
	return OK;
}
int main(void)
{
	SElemtype e;
	Stack s;
	Stack_Init(&s,5);
	Push(&s,100);
	for(int i = 0;i < 6;i++)
	{
		printf("%d  ",s.data[i]);
	}
	Poll(&s,&e);
	printf("%d ",e);
	return 0;
}

三.两栈共享空间

栈的顺序存储很方便,但是必须知道存储空间大小,如果不够用那会是非常麻烦。
那么我们可以让两个栈共用。让一个栈的栈底为另一个的初始
栈的顺序存储及代码实现
共享的结构

typedef struct{
	SElemtype data[MAXSIZE];
	int top1;
	int top2;
}DoubleStack;

初始化

void DoubleStack_Init(DoubleStack *ds,int n1,int n2)
{
	int i;
	ds->top1 = 0;
	ds->top2 = MAXSIZE - 1;
	for(i = 0;i < MAXSIZE;i++)
	{
		ds->data[i] = 0;
	}
	for(i = ds->top1;i < n1;i++)
	{
		ds->data[(ds->top1)++] = 10 + i;
	}
	for(i = ds->top2;i > ds->top1 + n2;i--)
	{
		ds->data[(ds->top2)--] = 50 + i;
	}
}

这里我的栈顶是提前了一个,就是本来应该是5,结果是6了,忘了改了,但是下面结果没错,我下面的做了适当修改

3.1插入元素

在这里我们就需要判断是栈1还是栈2

Status DoubleStack_Push(DoubleStack *ds,SElemtype e,int stackNumber)
{
	if(ds->top1 + 1 == ds->top2)
	return ERROR;
	if(stackNumber == 1)
	   ds->data[(ds->top1)++] = e;
	else if(stackNumber == 2)
	   ds->data[(ds->top2)--] = e;
	return OK;
}

这里需要注意是怎么判断栈是否是满。就是当两个相遇时候,因为一个是在前面,一个是在后面。

3.2删除元素

Status DoubleStack_Poll(DoubleStack *ds,SElemtype *e,int stackNumber)
{
	if(stackNumber == 1 )
	{
		if(ds->top1 == -1)
		    return ERROR;
		*e = ds->data[ds->top1 - 1];
		ds->data[ds->top1] = 0;
		ds->top1--;
	}
	else if(stackNumber == 2 )
	{
		if(ds->top1 == MAXSIZE)
		    return ERROR;
		*e = ds->data[ds->top2 + 1];
		ds->data[ds->top2 + 1] = 0;
		printf("%d   ",ds->top2);
		ds->top2++;
	}
	return OK;
}

这里为了适应我之前错误,进行修改了,结果是对的

总体代码

#include<stdio.h>
#include<stdlib.h>

#define MAXSIZE 20
typedef int SElemtype;
typedef int Status;
#define OK 1
#define ERROR 0
typedef struct{
	SElemtype data[MAXSIZE];
	int top1;
	int top2;
}DoubleStack;

void DoubleStack_Init(DoubleStack *ds,int n1,int n2)
{
	int i;
	ds->top1 = 0;
	ds->top2 = MAXSIZE - 1;
	for(i = 0;i < MAXSIZE;i++)
	{
		ds->data[i] = 0;
	}
	for(i = ds->top1;i < n1;i++)
	{
		ds->data[(ds->top1)++] = 10 + i;
	}
	for(i = ds->top2;i > ds->top1 + n2;i--)
	{
		ds->data[(ds->top2)--] = 50 + i;
	}
}

Status DoubleStack_Push(DoubleStack *ds,SElemtype e,int stackNumber)
{
	if(ds->top1 + 1 == ds->top2)
	return ERROR;
	if(stackNumber == 1)
	   ds->data[(ds->top1)++] = e;
	else if(stackNumber == 2)
	   ds->data[(ds->top2)--] = e;
	return OK;
}

Status DoubleStack_Poll(DoubleStack *ds,SElemtype *e,int stackNumber)
{
	if(stackNumber == 1 )
	{
		if(ds->top1 == -1)
		    return ERROR;
		*e = ds->data[ds->top1 - 1];
		ds->data[ds->top1] = 0;
		ds->top1--;
	}
	else if(stackNumber == 2 )
	{
		if(ds->top1 == MAXSIZE)
		    return ERROR;
		*e = ds->data[ds->top2 + 1];
		ds->data[ds->top2 + 1] = 0;
		printf("%d   ",ds->top2);
		ds->top2++;
	}
	return OK;
}

int main(void)
{
	SElemtype e;
	DoubleStack ds;
	DoubleStack_Init(&ds,7,4);
	DoubleStack_Push(&ds,1000,2);
	for(int i = 0;i < MAXSIZE;i++)
	printf("%d  ",ds.data[i]);
	printf("\n");
	DoubleStack_Poll(&ds,&e,2);
	for(int i = 0;i < MAXSIZE;i++)
	printf("%d  ",ds.data[i]);
	return 0;
}

四.结尾

栈的共享就像一个会移动的盒子,就是两端无论怎么动,大小还是那么大,而且两端都增加,很快空间就会满了。为了能更好的放更多元素,其实可以使用栈的链式存储。