数据结构之栈

栈是限定仅在表尾进行插入和删除操作的线性表。栈又可以称为后进先出(Last In First Out)的线性表,简称LIFO结构。我们把允许插入和删除的一端称为栈顶,另一端称为栈底。

由栈的定义可知,首先,它是一个线性表,也就是说,栈的元素具有线性关系,即前驱后继的关系。只不过它是一种特殊的线性表而已。定义中所谓的在线性表的表尾进行插入和删除操作,此表尾指的是栈顶,而不是栈底。说栈是一种特殊的线性表,其特殊之处就在于限制了线性表的插入和删除位置,始终只能在栈顶进行操作。于是便能理解后进先出的意思了。

栈的顺序存储——顺序栈,即线性表顺序存储的简化。定义一个top变量来指示栈顶元素在数组中的位置,top的变化就代表着顺序栈中数据的变化。规定:栈顶位置的top值必须小于MAXSIZE(栈容量),当栈中只存在一个元素时,top=0,因此通常把栈空的判定条件定为top==-1。栈满的判定条件则为top==MAXSIZE-1。

常见的顺序栈的几种操作:插入、删除、计算长度、判空等

1.插入操作,即入栈操作,又称压栈。

//压栈操作,即插入数据
bool Push(SqStack* s, ElemType e)
{
    //栈满
    if (s->top == MAXSIZE - 1)
    {
    	return false;
    }
    //如果栈未满,先让s->top++,之后再将元素e赋值给s->data[]
    s->data[++s->top] = e;
    return true;
}

2.删除操作,即弹栈。

//弹栈操作,即删除元素
bool Pop(SqStack* s, ElemType* e)
{
    //若栈为空,则s->top==-1
    if (s->top == -1)
    {
	return false;
    }
    //将要删除的元素赋值给e,之后再将栈顶元素减1
    *e = s->data[s->top--];
    return true;
}

3.计算长度。

//求栈中元素个数
int StackLength(SqStack* s)
{
    return s->top+1;
}

4.判空。

//判空操作
void StackEmpty(SqStack* s)
{
    if (s->top == -1)
    {
	printf("栈为空!\n");
    }
    else
    {
	if (s->top == MAXSIZE - 1)
	{
	    printf("栈满!\n");
	}
	else
	{
	    printf("栈不为空!\n");
	}
    }
}

5.打印。

//打印
void ShowStack(SqStack* s)
{
    for (int i = 0; i <= s->top; i++)
    {
	printf("%d ", s->data[i]);
    }
    printf("\n");
}

测试函数和声明部分:

#include<stdio.h>
#define MAXSIZE 10			//设置栈容量为10
typedef int ElemType;
typedef struct
{
    ElemType data[MAXSIZE];	//数组存储数据元素,最大容量为MAXSIZE
    int top;				//栈顶
}SqStack;

int main()
{
    //初始化top=-1
    SqStack s = { { 0 }, -1 };
    StackEmpty(&s);
    Push(&s, 0);
    Push(&s, 1);
    Push(&s, 2);
    Push(&s, 3);
    Push(&s, 4);
    Push(&s, 5);
    Push(&s, 6);
    ShowStack(&s);
    StackEmpty(&s);
    int len = StackLength(&s);
    printf("%d\n", len);
    return 0;
}

除了顺序栈之外,还有一种特殊的栈,即两个栈共享一段空间。具体可理解为:两个栈有两个栈底,让一个栈的栈底作为栈的始端,即下标为0处,另一个栈底为栈的末端,即下标为n-1处。如此一来,两个栈如果增加元素,就是两个端点向中间延伸。如此可得栈1为空时,top1=-1,当top2等于n时,即是栈2为空。栈满的判定条件就变成了top1+1==top2了。

共享空间的两个栈的常见操作和顺序栈相同,只是在定义时需要两个栈顶指针,以及压栈的时候需要多传一个参数来标记栈1和栈2.

1.插入,即压栈。

//压栈操作
bool Push(SqStack* s, ElemType e, int StackNum)
{
	//栈满
	if (s->top2 - s->top1 == 1)
	{
		return false;
	}
	//1号栈,top1加1
	if (1 == StackNum)
	{
		s->data[++s->top1] = e;
	}
	else
	{
		s->data[--s->top2] = e;
	}
	return true;
}

2.删除,即弹栈。

//弹栈操作
bool Pop(SqStack* s, ElemType* e, int StackNum)
{
	if (1 == StackNum)
	{
		//1号栈空栈
		if (s->top1 == -1)
		{
			return false;
		}
		*e = s->data[s->top1--];
	}
	else
	{
		//2号栈空栈
		if (s->top2 == MAXSIZE)
		{
			return false;
		}
		*e = s->data[s->top2++];
	}
	return true;
}

3.计算长度。

//求栈中元素长度
int StackLength(SqStack* s)
{
	int len = s->top1 + 1 + MAXSIZE - s->top2;
	return len;
}

4.判空。

//判空
void StackEmpty(SqStack* s)
{
	if (s->top1 == -1 && s->top2 == MAXSIZE)
	{
		printf("栈为空!\n");
	}
	else
	{
		if (s->top2 - s->top1 == 1)
		{
			printf("栈满!\n");
		}
		else
		{
			printf("栈不为空!\n");
		}
	}
}

5.打印。

//打印
void ShowStack(SqStack* s)
{
	for (int i = 0; i <= s->top1; i++)
	{
		printf("%d ", s->data[i]);
	}
	for (int j = s->top2; j < MAXSIZE; j++)
	{
		printf("%d ", s->data[j]);
	}
	printf("\n");
}

测试函数和声明部分:

int main()
{
	//数据域为0,1号栈栈顶为-1,2号栈栈顶为MAXSIZE
	SqStack s = { { 0 }, -1, MAXSIZE };
	Push(&s, 0, 1);
	Push(&s, 1, 1);
	Push(&s, 2, 1);
	Push(&s, 3, 1);
	Push(&s, 4, 1);
	Push(&s, 5, 2);
	Push(&s, 6, 2);
	Push(&s, 7, 2);
	Push(&s, 8, 2);
	Push(&s, 9, 2);
	ShowStack(&s);
	int len = StackLength(&s);
	printf("%d\n", len);
	StackEmpty(&s);
	return 0;
}

//声明
typedef int ElemType;
typedef struct
{
	ElemType data[MAXSIZE];		//数组存储数据元素最大容量为MAXSIZE
	int top1;					//1号栈栈顶
	int top2;					//2号栈栈顶
}SqStack;

以上即是栈的顺序存储的相关内容~~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值