数据结构学习2——栈和队列(通过C++代码例子)

希望可以帮助到大家,同时希望帮助大家能够关注+收藏,会持续更新后面的内容

一、基础概念

1.栈的定义
(1)栈:
栈实际上是一种线性表,它只允许在固定的一段进行插入或者删除元素,在进行数据插入或者删除的一段称之为栈顶,剩下的一端称之为栈顶。其遵循的原则是后进先出。
(2)栈的核心操作:三大核心操作,入栈,出栈,取栈顶元素
(3)对于栈的形象理解:枪上子弹,先进后出

2.队列的定义
(1)队列:
首先队列也是一种特殊的线性表,它允许在一端进行插入数据,在另一端进行删除数据的。队列里边有队首,队尾,队首元素。其遵循的原则是先进先出。
(2)队列的核心操作:三大核心操作分别是入队列,出队列,取队首元素
(3)对于队列的形象理解:排队

详细链接  队列和栈的说明

图文说明链接 写的很好

二、实验题目

选题1:字符串中心对称问题:任意输入一个字符串,试判断其是否对称。

选题2: 停车场管理:设有一个可以停放n 辆汽车的狭长停车场,它只有一个大门可以供车辆进出。车辆按到达停车场时间的早晚依次从停车场最里面向大门口处停放(最先到达的第一辆车放在停车场的最里面)。如果停车场已放满n辆车,则后来的车辆只能在停车场大门外的便道上等待,一旦停车场内有车开走,则排在便道上的第一辆车就进入停车场。停车场内如有某辆车要开走,在它之后进入停车场的车辆都必须先退出停车场为它让路,待其开出停车场后,这些车辆再依原来的次序进场。每辆车在离开停车场时,都应该根据它在停车场内停留的时间长短交费。如果停留在便道上的车未进停车场就要离去,允许其离去,不收停车费,并且仍然保持在便道上等待的车辆的次序。编制一程序模拟该停车场的管理。

三、源代码

选题1:字符串中心对称问题

#include <iostream>
using namespace std;

#define STACK_INIT_SIZE 100
#define STACKINCREASE 10
#define SElemType char
#define QElemType char
#define Status int
#define OK 1
#define OVERFLOW -1
#define ERROR 0

typedef struct QNode {
	QElemType data;
	struct QNode* next;
}QNode, * QueuePtr;

typedef struct {
	QueuePtr front;     //对头指针
	QueuePtr rear;      //队尾指针
}LinkQueue;

//构造空队列Q
Status InitQueue(LinkQueue& Q) {
	Q.front = Q.front = (QueuePtr)malloc(sizeof(QNode));

	if (!Q.front) return OVERFLOW;
	Q.front->next = NULL;
	return OK;
}

//元素e插入队列
Status EnQueue(LinkQueue& Q, QElemType e) {
	QueuePtr p, q;
	p = new QNode;
	q = new QNode;
	if (!p) return OVERFLOW;
	p->data = e;
	p->next = NULL;

	if (Q.front->next == NULL) {
		Q.front->next = p;
		Q.rear = p;
	}
	else {
		q = Q.front;
		while (q->next->next != NULL) {
			q = q->next;
		}
		q->next->next = p;
		Q.rear = p;
	}
	return OK;
}

//删除Q的队头元素
Status DeQueue(LinkQueue& Q, QElemType& e) {
	QueuePtr p;
	if (Q.front == Q.rear) return ERROR;
	p = Q.front->next;
	e = p->data;
	Q.front->next = p->next;
	if (Q.rear == p) Q.rear = Q.front;
	delete(p);
	return OK;
}

typedef struct {
	SElemType* base;
	SElemType* top;
	int stacksize;
}SqStack;

//构造空栈S
Status InitStack(SqStack& S) {
	S.base = (SElemType*)malloc(STACK_INIT_SIZE * sizeof(SElemType));
	if (!S.base) return OVERFLOW;

	S.top = S.base;
	S.stacksize = STACK_INIT_SIZE;

	return OK;
}

//入栈操作
Status Push(SqStack& S, SElemType e) {
	if (S.top - S.base >= S.stacksize) {    //栈满,追加空间
		S.base = (SElemType*)realloc(S.base, (S.stacksize + STACKINCREASE) * sizeof(SElemType));
		
		S.top = S.base + S.stacksize;
		S.stacksize += STACKINCREASE;
	}

	*S.top = e;
	S.top++;
	return OK;
}

//出栈操作
Status Pop(SqStack& S, SElemType& e) {
	if (S.top == S.base) return ERROR;
	e = *--S.top;
	return OK;
}

//判断是否是回文
Status IsPalindrome(char p[]) {
	LinkQueue Q;
	SqStack S;
	if (!InitStack(S)) return ERROR;
	if (!InitQueue(Q)) return ERROR;
	SElemType e1;
	QElemType e2;

	int i = 0;
	while (p[i]) {            //将输入的字符串p输入到栈和队列中
		Push(S, p[i]);        //同时i记录字符个数
		EnQueue(Q, p[i++]);
	}
	for (i; i > 0; i--) {       //将字符分别从栈和队列中取出
		Pop(S, e1);
		DeQueue(Q, e2);
		if (e1 != e2)         //两个字符不相等,返回错误
			return ERROR;
	}
	return OK;
}

int main() {
	char p[100], e;
	cout << "判断字符串是否属于回文字符串" << endl;
	cout << "请输入一串字符:";
	cin >> p;
	if (IsPalindrome(p)) cout << p << "是回文字符串!\n";
	else cout << p << "不是回文字符串!" << endl;
	return 0;
}

选题2: 停车场管理

#include <iostream>
#include <stdlib.h> 
#define Max_N 3
#define Max_M 5
#define True 1
#define False 0

using namespace std;
/*定义车辆的数据类型*/
typedef struct
{
	int num;     /*车辆车牌号*/
	int arrtime; /*车辆到达时间*/
}elemtype;
/*定义顺序栈(停车场)数据类型*/
typedef struct 
{
	elemtype stack[Max_N];/*定义存放元素的数组*/
	int top;              /*定义栈顶指针*/
}sqstktp;

/*定义链队列元素(停在停车场外便道上的车辆)数据类型*/
typedef struct node
{
	int num;           /*车牌号*/
	struct node* next;/*后边相邻车辆所在位置*/
}queueptr;

/*链队列的队头指针和队尾指针的数据类型*/
typedef struct
{
	queueptr* front, * rear;/*链队列的队头指针和队尾指针*/
}linkedquetp;

/*初始化顺序栈(停车场)*/
void inistack(sqstktp* s)
{
	s->top = -1;/*栈顶指针*/
}

/*元素入栈(汽车驶入停车场)*/
int push(sqstktp* s, elemtype x)
{
	if (s->top == Max_N - 1)/*栈满(停车场无车位)*/
		return (False);
	else
	{
		s->stack[++s->top] = x;
		/*元素入栈(车辆驶入停车场)*/
		return(True);
	}
}
/*元素出栈(汽车驶出停车场)*/
elemtype pop(sqstktp* s)
{
	elemtype x;    /*出栈元素(要驶出停车场的车辆)*/
	if (s->top < 0)/*如果是空栈(停车场无车)*/
	{
		x.num = 0;     /*车牌号置为0*/
		x.arrtime = 0;/*车辆到达时间置为0*/
		return(x);
	}
	else
	{
		s->top--;/*栈顶元素*/
		return(s->stack[s->top + 1]);/*返回原栈顶元素*/
	}
}
/*创建一个空链队列*/
void inilinkedque(linkedquetp* s)
{
	s->front = (queueptr*)malloc(sizeof(queueptr));
	s->rear = s->front;            
	s->front->next = 0;
	s->front->num = 0;
	/*记录便道上等待进入停车场的车辆数*/
}

/*链队列元素入队(新到车辆在便道上等候)*/
void enlinkedque(linkedquetp* s, int num1)
{
	queueptr* p;
	p = (queueptr*)malloc(sizeof(queueptr));

	p->num = num1;     /*记录车牌*/
	p->next = 0;     
	s->rear->next = p;
	s->rear = p;
	s->front->num++;
}

int dllinkedque(linkedquetp* s)
{
	queueptr* p;
	int n;
	if (s->front == s->rear)/*便道上无车辆等候进入停车场*/
		return 0;
	else
	{
		p = s->front->next;/*保存队头元素所在的位置到p*/
		s->front->next = p->next;
		if (p->next == 0)
			s->rear = s->front;
		n = p->num;
		free(p);
		s->front->num--;
		return(n);/*返回离队车辆的车牌*/
	}
}

/*车辆到达*/
void arrive(sqstktp* s1, linkedquetp* p, elemtype x)
{
	int f;/*定义临时变量f,标识:1=入栈成功,0=入栈失败*/
	f = push(s1, x);
	if (f == False)
	{
		enlinkedque(p, x.num);/**/
		cout<<"第"<< x.num<<"号车停在便道第"<<p->front->num<<"号车位上"<<endl;
		/*显示车牌信息和位置信息*/
	}
	else
		cout<<"第:"<<x.num<<"号车停在存车场第"<< s1->top + 1 <<"号车位上"<<endl;
	/*显示车牌信息和停车场内位置*/
}

/*车辆离开*/
void delive(sqstktp* s1, sqstktp* s2, linkedquetp* p, elemtype x)
{
	int n, f = False;
	
	elemtype y;
	queueptr* q;
	while ((s1->top > -1) && (f != True))/*如果停车场不为空且f=0*/
	{
		y = pop(s1);
		if (y.num != x.num)/*如果不是要离开的车辆*/
			n = push(s2, y);
		else
			f = True;
	}
	if (y.num == x.num)/*是要离开的车辆*/
	{
		cout<<"第"<<y.num<<"号车应收费"<<(x.arrtime - y.arrtime) * Max_M<<"元"<< endl;
		/*显示车牌和缴费信息*/

		while (s2->top > -1)
		{
			y = pop(s2);
			f = push(s1, y);
		}
		n = dllinkedque(p);
		if (n != 0)
		{
			y.num = n;
			y.arrtime = x.arrtime;/*计费时间为刚才离去车辆的离开时间*/
			f = push(s1, y);
			cout<<"第"<<y.num<<"号车停在存车场的第"<<s1->top + 1<<"号车位上"<<endl;
			/*显示刚刚进入车辆在停车场位置*/
		}
	}
	else
	{
		while (s2->top > -1)/*停车场未找到要离去的车辆*/
		{
			y = pop(s2);    /*便道里的车放入停车场*/
			f = push(s1, y);
		}
		q = p->front;
		f = False;
		while (f == False && q->next !=0)/*在便道寻找要离去的车辆*/
			if (q->next->num != x.num)
				q = q->next;
			else {
				q->next = q->next->next;
				p->front->num--;
				if (q->next == 0)
					p->rear = p->front; 
			cout<<"第"<<x.num<<"号车离开便道"<<endl;
				f = True;
			}
		if (f == False)
			cout<<"输入数据错误,停车场和便道均无第"<< x.num<<"号车"<<endl;
	}
}

int main()
{
	char ch1, ch2;     /*定义两个字符型变量*/
	sqstktp* s1, * s2;
	linkedquetp* p;   
	elemtype x;       /*定义车牌变量*/
	int flag;
	s1 = (sqstktp*)malloc(sizeof(sqstktp));
	s2 = (sqstktp*)malloc(sizeof(sqstktp));
	p = (linkedquetp*)malloc(sizeof(linkedquetp));
	inistack(s1);/*初始化s1栈*/
	inistack(s2);/*初始化s2栈*/
	inilinkedque(p);
	flag = True;  
	while(1)
	{
		cout << "************************停车场模拟***************************" << endl;
		cout << "*************************************************************" << endl;
		cout << "****:‘A’表示车进入、‘D’表示车离开、‘E’表示程序结束****" << endl;
		cout << "****输入数据:'A'/'D'/'E',车牌号,到达/离开时间**************" << endl;
		cout << "*************************************************************" << endl;
		cin >> ch1 >> x.num >> x.arrtime;
		ch2 = getchar();
		switch (ch1)
		{
		case 'A':arrive(s1, p, x);
			break;
		case 'D':delive(s1, s2, p, x);
			break;
		case 'E':flag = False;
			cout<<"程序结束"<<endl;
			exit(0);
			break;
		default:
		    cout<<"输入数据错误,重新输入"<<endl;
		}
		if (flag == False)
			break;
	}
	return 0;
}

四、运行截图

选题1:

 

 

选题2:

 

如果发现有BUG希望指出。

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

开开心累兮

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

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

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

打赏作者

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

抵扣说明:

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

余额充值