顺序栈(栈的顺序储存结构)

      对于栈来讲,理论上线性表的操作特性它都具备,可由于它的特殊性,所以在操作上会有一些变化,特别是插入和删除操作(可以理解为子弹压入和弹出)

      1.首先我们来看栈的结构定义:

typedef struct
{
	SElemType* data;
	int top;//一直记录栈顶所用的游标
}SqStack;

      对比顺序表我们这里定义的int类型的top变量用于记录栈顶下标

      2.然后我们构造一个空栈:

int InitStack(SqStack* S)//构造一个空栈
{
	S->data = new SElemType[MAXSIZE];
	if (!(S->data))
		return 0;
	S->top = -1;//让栈的游标初始化
	return 1;
}

      和顺序表相同用new开辟空间,不同之处在于在构造空栈时要把top的值初始化为-1代表栈中没有数据(初始化为-1便于之后输入数据的同时自增top即可让top记录此时栈顶的下标)

      3.为了便于调试我们之后需要输入数的情况都用系统产生的随机数,接下来我们向栈中输入数据:

void CreatStack(SqStack* S)//向栈传入数据
{
	int i;
	for (i = 0; i < CONTENT; i++)
	{
		S->data[i] = rand() % 100 + 1;//随机赋给栈1-100的CONTENT个数字
		S->top++;
	}
}

      这里可以说说随机数的产生:首先我们要定义头文件#include<ctime>,为了让随机数真的是随机的我们要添加随机数种子srand((unsigned int)time(NULL));(目的是利用当前系统时间生成随机数),然后便可以通过rand()%100+1随机生成1-100的数字赋给栈

      4.我们定义一个输出栈中数据的函数便于检验对栈的操作是否正确:

void PrintStack(SqStack* S)//输出栈中的数据
{
	int i;
	for (i = S->top; i >= 0; i--)
	{
		cout << S->data[i] << " ";
	}
	cout << endl;
}

      由于栈底是首先输入到栈中的下标为0的数据,所以我们在输出时要从栈顶输出就要从游标top记录的下标开始输出到下标为0时的数据

      5.接下来就是栈与顺序表很不相同的进栈操作:

void Push(SqStack* S, SElemType e)//进栈操作
{
	if (S->top == MAXSIZE - 1)
	{
		cout << "栈已满" << endl;
		return;
	}
	cout << "向栈中插入随机数" << e << endl;
	S->data[++S->top] = e;
	cout << "成功插入" << endl;
}

      首先判断栈此时是否满了,如果游标top此时记录的是最后一个位置的下标则说明栈已经满了,就无法再插入数据。向栈中插入数据只能在栈顶插入,所以插入的时候只需将游标top指向当前栈顶的上方后再向其中输入数据,输入的数便成了新的栈顶(top不是指针,但用指针的说法比较好理解)

      6.下来就是栈与顺序表很不相同的出栈操作:

void Pop(SqStack* S)//出栈操作
{
	if (S->top == -1)
	{
		cout << "栈中已没有数据" << endl;
		return;
	}
	cout << "出栈的数据为:" << S->data[S->top] << endl;
	S->top--;
}

      首先我们要判断此时栈是否为空,在定义空栈的时候我们便知道当游标top记录的下标为-1时便说明栈是空栈。出栈游标的变化就与进栈有些许不同我们在出栈时先将游标top指向的当前栈顶的数据记录下来,然后再将游标top向下指(实践如果不是为了检验,直接将游标top--,将游标向下指便完成了出栈操作)

      ps:这里有一个个人理解,栈在出栈的时候不需要像链表一样删除数据后将空间释放,因为栈类似于数组,一开始储存空间是确定的,而链表是动态分配内存空间的,所以栈在进行删除操作时只需要将游标top向下指然后虽然top原来指向的栈顶内还有数据但由于top的限制,在对栈进行的操作都是无法作用于里面的数据的,在进行进栈操作时便会重新给其中的数据赋值,所以以前的那个值在游标top向下指时就已经是无效的状态了,而链表在删除了以后,重新添加结点时是重新开辟的空间,所以之前那个空间就属于是无效空间了,所以链表在删除时要进行释放。

      接下来展示程序代码:

1.头文件FUNC.h

#pragma once
#include <iostream>
#include<ctime>
using namespace std;
typedef int SElemType;//要储存的数据类型
#define MAXSIZE 20
#define CONTENT 10

typedef struct
{
	SElemType* data;
	int top;//一直记录栈顶所用的游标
}SqStack;

int InitStack(SqStack* S);//构造一个空栈

void CreatStack(SqStack* S);//向栈传入数据

void PrintStack(SqStack* S);//输出栈中的数据

void Push(SqStack* S, SElemType e);//进栈操作

void Pop(SqStack* S);//出栈操作

2.源文件FUNC.cpp

#include"FUNC.h"
int InitStack(SqStack* S)//构造一个空栈
{
	S->data = new SElemType[MAXSIZE];
	if (!(S->data))
		return 0;
	S->top = -1;//让栈的游标初始化
	return 1;
}


void CreatStack(SqStack* S)//向栈传入数据
{
	int i;
	for (i = 0; i < CONTENT; i++)
	{
		S->data[i] = rand() % 100 + 1;//随机赋给栈1-100的CONTENT个数字
		S->top++;
	}
}


void PrintStack(SqStack* S)//输出栈中的数据
{
	int i;
	for (i = S->top; i >= 0; i--)
	{
		cout << S->data[i] << " ";
	}
	cout << endl;
}


void Push(SqStack* S, SElemType e)//进栈操作
{
	if (S->top == MAXSIZE - 1)
	{
		cout << "栈已满" << endl;
		return;
	}
	cout << "向栈中插入随机数" << e << endl;
	S->data[++S->top] = e;
	cout << "成功插入" << endl;
}


void Pop(SqStack* S)//出栈操作
{
	if (S->top == -1)
	{
		cout << "栈中已没有数据" << endl;
		return;
	}
	cout << "出栈的数据为:" << S->data[S->top] << endl;
	S->top--;
}

3.源文件text.cpp

#include"FUNC.h"
int main()
{
	int n;
	int DBD=1;
	srand((unsigned int)time(NULL));//添加随机数种子
	cout << "欢迎来到顺序栈储存结构" << endl;
	SqStack S;//定义一个栈S
	if (InitStack(&S) == 1)
	{
		cout << "空栈创建成功" << endl;
	}
	else
		cout<< "空栈创建失败" << endl;
	//向栈随机传入数据
	CreatStack(&S);
	while (DBD)
	{
		system("pause");
		system("cls");
		cout << "1.输出栈的内容  2.进栈操作  3.出栈操作  4.退出程序" << endl;
		cin >> n;
		switch (n)
		{
		case 1:
		{
			PrintStack(&S);
			cout << "第一个数是栈顶" << endl;
	
			break;
		}
		case 2:
		{
			SElemType e;//用于临时储存要进栈的数据
			e = rand() % 100 + 1;//向e中随机传入一个1-100的数
			Push(&S, e);
			break;
		}
		case 3:
		{
			Pop(&S);
			break;
		}
		case 4:
		{
			DBD = 0;
			cout << "谢谢使用" << endl;
			break;
		}
		default:
		{
			cout << "输入不合法" << endl;
			break;
		}
		}
	}

	return 0;
}

顺序栈完成。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小林想被监督学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值