C语言博客作业02--栈和队列
| 这个作业属于哪个班级 | 数据结构--网络2011,2012(集美大学) |
| ---- | ---- | ---- | ---- |
| 这个作业的地址 | C博客作业02--栈和队列
| 这个作业的目标 | 学习如何设计函数、C语言基本数据类型 |
| 姓名 | 张官德 |
0.PTA得分截图
1.本周学习总结(0-5分)
1.1栈
-
栈是一种线性数据结构,栈的特征是数据的插入和删除只能通过一端来实现,这一端称为“栈顶”,相应的另一端称为“栈底”;另外其还有先进后出,后进先出的特征。
-
顺序栈
结构体
typedef struct
{ ElemType data[MaxSize]; //栈中数据元素
int top; //top为栈顶指针
} Stack;
typedef Stack *SqStack;
顺序栈的基本操作
初始化操作
void InitStack(SqStack s)
{
s = new SqStack;//分配一个顺序栈的空间,首地址存放s处
s->top = -1; //栈顶指针置为-1
}
判断栈是否为空
bool StackEmpty(SqStack s)
{
if(s->top == -1) //栈为空返回true
{
return true;
}
return false;
}
出栈与入栈操作
//出栈
bool Pop(SqStack &s,ElemType e)
{
if(StackEmpty(s)) //判断是否为空栈
{
return false;
}
e = s->data[s->top--]; //退栈
return true;
}
* 出栈并没有将原来站内的数据删除,只是指针下移
//入栈
bool Push(SqStack &s,ElemType e)
{
if(s->top == MAXSIZE - 1) //判断是否栈满
{
return false;
}
s->data[s->top++] = e; //入栈
return true;
}
取栈顶
bool GetTop(SqStack s, ElemType e) {
if (s->top == -1) {
cout << "栈空";
return false;
}
e = s->data[s->top];
return true;
}
毁栈
void DestroyStack(SqStack s)
{
delete s;
}
- 链栈
结构体
typedef struct StackNode
{
ElemType data;
struct StackNode *next;
}Node,*Stack;
顺序栈的基本操作
初始化操作
void CreatStack(LiStack &s)
{
s=new LiNode;
s->next=NULL;
}
判断栈是否为空
bool StackEmpty(LiStack S)
{
return (S->next == NULL);
}
入栈与出栈
//头插入栈
void Push(Stack& s, ElemType e)
{
Stack p;
p = new Node;
p->data = e;
p->next = s->next;
s->next = p;
}
//出栈
bool Pop(LiStack& S, ElemType e)
{
LiStack p;
if (S->next == NULL)return false;//判断栈是否为空
p = S->next;
e = p->data;
S->next = p->next;
delete p;
return true;
}
毁栈
void DestroyStack(Stack &s)
{
Stack p;
while (s!=NULL)
{ p=s;
s=s->next;
delete p;
}
}
1.2 栈的应用
栈是一个重要的数据结构,其特性简而言之就是“后进先出”,这种特性在计算机中有着广泛的运用。其实程序员无时无刻不在使用者栈,函数的调用是我们间接使用栈的最好的例子,但是栈在实际中的运用远不止这些,比较经典的应用还包括括号匹配、逆波兰表达式的求值等
例如符号配对
从第一个字符开始扫描
当遇见普通字符时忽略,当遇见左符号时压入栈中
当遇见右符号时从栈中弹出栈顶符号
进行匹配
匹配成功:继续读入下一个字符
匹配失败:立即停止,并报错
结束:
成功:所有字符扫描完毕,且栈为空
失败:匹配失败或所有字符扫描完毕但栈非空
1.3 队列
-
1)队列(Queue)队列是一种先进先出的线性表。它只允许在表的一端进行插入,而在另一端进行删除。向队列中插入元素称为入队,从队列中删除元素称为出队。
2)队首(front)允许进行删除的一端称为队首。3)队尾(rear)允许进行插入的一端称为队尾。
顺序队列
结构体
typedef struct
{ ElemType data[MaxSize];
int front,rear; //队首和队尾指针
}Queue;
typedef Queue *SqQueue;
初始化
void InitQueue(SqQueue &q)
{ q=new Queue;
q->front=q->rear=-1;
}
入队
bool enQueue(SqQueue &q,ElemType e)
{
if (q->rear+1==MaxSize )
return false;
q->rear=q->rear+1;//队尾指针增加
q->data[q->rear]=e;//数据纳入
return true;
}
出队
bool deQueue(SqQueue &q,ElemType &e)
{
if (q->front==q->rear)
return false;
q->front=q->front+1;
e=q->data[q->front];
return true;
//队首指针
}
毁队列
void DestroyQueue(SqQueue &q)
{
delete q;
}
环队列###
环队列与顺序队列的结构体一样,只是初始化不同
初始化
void InitQueue(SqQueue &q)
{ q=new Queue;
q->front=q->rear=0;
}
入队
bool enQueue(SqQueue &q,ElemType e)
{ if ((q->rear+1)%MaxSize==q->front)
return false;
q->rear=(q->rear+1)%MaxSize;//与顺序队列不同之处
q->data[q->rear]=e;
return true;
}
出队
bool deQueue(SqQueue &q,ElemType &e)
{ if (q->front==q->rear)
return false;
q->front=(q->front+1)%MaxSize;
e=q->data[q->front];
return true;
}
链队列
结构体
typedef struct node {
ElemType data;
struct node* next;
}QueueNode;
//定义头节点
typedef struct {
QueueNode* front;
QueueNode* rear;
}LinkQueue;
初始化
void InitQueue(LinkQueue* Q)
{
Q->front = Q->rear = NULL;
}
是否为空
int QueueEmpty(LinkQueue* Q)
{
return(Q->front == NULL && Q->rear == NULL);
}
入队
void EnLinkQueue(LinkQueue* Q, ElemType v)
{
QueueNode* p;
p = new QueueNode;//创立节点
p->data = v;
p->next = NULL;
if (QueueEmpty(Q)) {
Q->front = Q->rear = p;
}
else{
Q->rear->next = p; //尾插入列
Q->rear = p; //指向队列尾
}
出队
bool DeLinkQueue(LinkQueue* Q, ElemType &e)
{
QueueNode* s;
if (QueueEmpty(Q))
return false; //判断队列是否为空
s = Q->front;
e = s->data;
if (Q->front == Q->rear)
Q->front = Q->rear = NULL;
else
Q->front = s->next;
delete s;
return true;
}
毁队列
Status DestroyQueue(LinkQueue& Q)
{
while (Q.front)
{
Q.rear = Q.front->next;
free(Q.front);
Q.front = Q.rear;
}
return OK;
}
队列应用
int QueueLen(SqQueue Q) {
return Q->rear - Q->front;
}
int EnQueue(SqQueue& Q, Person e) {
Q->data[Q->rear] = e;
Q->rear++;
return 1;
}
int QueueEmpty(SqQueue& Q) {
if (Q->front == Q->rear) {
return 1;
}
else {
return 0;
}
}
int DeQueue(SqQueue& Q, Person& e) {
e = Q->data[Q->front++];
return 1;
}
void DancePartner(Person dancer[], int num) {
int i = 0;
Person e;
for (i = 0; i < num; i++) {
e = dancer[i];
if (e.sex == 'F') {
EnQueue(Fdancers, e);
}
else {
EnQueue(Mdancers, e);
}
}
while (!QueueEmpty(Fdancers) && !QueueEmpty(Mdancers)) {
DeQueue(Fdancers,e);
cout << e.name;
DeQueue(Mdancers, e);
cout << " " << e.name << endl;
}
}
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <stack>
#include <queue>
using namespace std;
int main()
{
queue<int>q;
int n;
int m;
int i;
int count = 0;
int e;
int flag = 0;
cin >> n;//人数
cin >> m;//出列的数
if (m > n)
{
cout << "error!";
return 0;
}
//入队
for (i = 1;i <= n;i++)
{
q.push(i);
}
//报数
while (!q.empty())
{
count++;
if (count == m)//出队
{
if (flag == 0)
{
cout << q.front();
flag = 1;
}
else
{
cout << " " << q.front();
}
q.pop();
count = 0;
}
else if (count != m && !q.empty())//继续入队
{
e = q.front();
q.push(e);
q.pop();
}
}
return 0;
}
2.PTA实验作业
符号配对
#include<stdlib.h>
#include<stdio.h>
#include<string>
#include<iostream>
using namespace std;
struct SNode {
char data[1000];
int top;
};
typedef struct SNode* stack;
int main() {
stack s;
int i;
s = new SNode;
int flag = 0;
s->top = -1;
string str;
while (1) {
getline(cin, str);
if (str[0] == '.') {
break;
}
for (i = 0; str[i]; i++) {
if (str[i] == '[' || str[i] == '{' || str[i] == '(') {
s->top++;
s->data[s->top] = str[i];
}
else if (str[i] == '/' && str[i + 1] == '*') {
s->top++;
s->data[s->top] = str[i];
s->top++;
s->data[s->top] = str[i + 1];
}
if (str[i] == ']' || str[i] == '}' || str[i] == ')'||(str[i]=='*'&&str[i+1]=='/')) {
if (str[i] == ']' && s->data[s->top] == '['&&s->top!=-1) {
s->top--;
}
else if (str[i] == '}' && s->data[s->top] == '{' && s->top != -1) {
s->top--;
}
else if (str[i] == ')' && s->data[s->top] == '(' && s->top != -1) {
s->top--;
}
else if (str[i] == '*' && str[i + 1] == '/' && s->data[s->top] == '*' && s->data[s->top - 1] == '/' && s->top != -1) {
s->top--;
s->top--;
}
else if (s->top == -1 && str[i] == ']') {
flag = 1;
break;
}
else if (s->top == -1 && str[i] == '}') {
flag = 2;
break;
}
else if (s->top == -1 && str[i] == ')') {
flag = 3;
break;
}
else if (s->top == -1 && str[i] == '/' && str[i - 1] == '*') {
flag = 4;
break;
}
}
}
}
if (flag) {
cout << "NO" << endl;
cout << "?-]";
}
else if (flag == 2) {
cout << "NO" << endl;
cout << "?-}";
}
else if (flag == 3) {
cout << "NO" << endl;
cout << "?-)";
}
else if (flag == 4) {
cout << "NO" << endl;
cout << "?-*/";
}
if (s->top == -1 && flag == 0) {
cout << "YES";
}
else if (s->top != -1 && s->data[s->top] == '[') {
cout << "NO" << endl;
cout << "[-?";
}
else if (s->top != -1 && s->data[s->top] == '{') {
cout << "NO" << endl;
cout << "{-?";
}
else if (s->top != -1 && s->data[s->top] == '(') {
cout << "NO" << endl;
cout << "(-?";
}
else if(s->top != -1 && s->data[s->top] == '*'&& s->data[s->top-1] == '/') {
cout << "NO" << endl;
cout << "/*-?";
}
}
解题思路
遇到左符号就入栈,遇到右符号就出一个栈,如果到最后栈空可以判断匹配成功或者左边符号没有入栈过,若是第二种且有右符号则缺左符号,
若到最后栈不空则缺右符号。
知识点
栈的基本运用
include < string > 的运用
银行业务队列简单模拟
#include <stdio.h>
#include <stdlib.h>
#include<iostream>
using namespace std;
typedef int Position;
typedef struct SNode *PtrToSNode;
typedef struct {
int *data;
int front;
int rear;
} Team;
typedef Team *SqTeam;
SqTeam Creat()
{
SqTeam T = new Team;
T->front = 0;
T->rear = 0;
T->data= (int*)malloc(1000 * sizeof(int));
return T;
}
void push(SqTeam T,int a)
{
T->data[T->rear++] = a;
return;
}
int empty(SqTeam T)
{
if (T->rear == T->front)return 0;
return 1;
}
void pop(SqTeam T,int *flag)
{
if (empty(T) && *flag == 1)
{
printf("%d", T->data[T->front++]); *flag = 0;
}
else if (empty(T) && *flag == 0)
printf(" %d", T->data[T->front++]);
}
int main()
{
SqTeam A, B;
A = Creat();
B = Creat();
int n,i,a,*flag,f=1;
flag = &f;
cin >> n;
for (i = 0; i < n; i++)
{
cin >> a;
if (a % 2 != 0)push(A, a);
else push(B, a);
}
while (empty(A) && empty(B))
{
pop(A,flag);
pop(A,flag);
pop(B,flag);
}
if (!empty(A))
{
while (empty(B))
{
pop(B, flag);
}
}
if (!empty(B))
{
while (empty(A))
{
pop(A, flag);
}
}
return 0;
}
1)将a,b客户入队到俩个不同队列
2)输出a两个,b一个
3)输出剩余队列的元素
知识点
队列的运用
出入关系明确
3.代码阅读
解题思路
解题代码
#include<iostream>
#include<queue>
using namespace std;
class Mystack
{
public:
Mystack()
{
}
void push(int x)
{
std::queue<int> temp_queue;
temp_queue.push(x);
while(!_data.empty())
{
temp_queue.push(_data.front());
_data.pop();
}
while(!temp_queue.empty())
{
_data.push(temp_queue.front());
temp_queue.pop();
}
}
int pop()
{
int x=_data.front(); //取栈顶元素,即为队列头部元素
_data.pop();
return x;
}
int top()
{
return _data.front();//返回栈顶元素,即为直接范围队列头部元素
}
bool empty()
{
return _data.empty();
}
private:
std::queue<int> _data; //_data数据队列存储元素的顺序就是栈存储元素的顺序。
};
int main()
{
Mystack S;
S.push(1);
S.push(2);
S.push(3);
S.push(4);
printf("%d\n",S.top());
S.pop();
printf("%d\n",S.top());
S.push(5);
printf("%d\n",S.top());
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人