这个作业属于哪个班级 | 数据结构-网络20 |
---|---|
这个作业的地址 | DS博客作业02--栈和队列 |
这个作业的目标 | 学习栈语言--网络2011/2012和队列的结构设计及运算操作 |
姓名 | 梁桢 |
0.PTA得分截图
1.本周学习总结(0-5分)
1.1 栈
1.1.1画一个栈的图形,介绍如下内容。
- 定义:栈是一种只能在一端进行插入或删除操作的线性表。表中允许进行插入,删除的一端称为栈顶。
- 进栈:插入操作
- 出栈:删除操作
- 出栈顺序:后进先出。例如:上图中的出栈顺序为an,an-1,....,a2,a1
- 存储结构:顺序栈,链栈
1.1.2 顺序栈
- 顺序栈:采用顺序存储结构的栈称为顺序栈
- 结构体定义
typedef struct
{
ElemType data[MaxSize];
int top; //栈顶指针
}Stack,*SqStack;
- 初始化:
void CreatStack(SqStack s) {
s = new Stack;
s->top = -1;
}
- 进栈:
tip:先要判断栈是否满
bool Push(SqStack s, ElemType e) {
if (s->top == MaxSize-1) {
printf("栈满");
return false;
}
s->data[++s->top] = e;
return true;
}
- 出栈:先要判断栈是否为空
bool Pop(SqStack s, ElemType e) {
if (s->top == -1) {
printf("栈空");
return false;
}
e=s->data[s->top--];
return true;
}
- 对栈进行操作时都要考虑栈满或空,应该预先进行判断
1.1.3 链栈
- 链栈:采用链式存储结构的栈称为链栈,这里采用带头节点的单链表来实现链栈
- 结构体定义
typedef struct linkstack
{
ElemType data;
struct linkstack *next;
}StStack,*LinkStack;
- 初始化栈
void InitStack(LiStack& s)
{
s = new LiNode;
s->next = NULL;
}
- 进栈
bool Push(LinkStack &S, int e) //在栈顶插入元素e
{
LinkStack p;
p = new Snode; //生成新结点
p->data = e; //将e放在新结点数据域
p->next = S; //将新结点的指针域指向S
S = p; //修改栈顶指针为p
return true;
}
- 出栈
bool Pop(LinkStack &S, int &e)
{
LinkStack p;
if (S == NULL)
return false;
e = S->data; //将栈顶元素赋给e
p = S; //用p保存栈顶元素地址,以备释放
S = S->next; //修改栈顶指针,指向下一个结点
delete p; //释放原栈顶元素的空间
return true;
}
- 取栈顶元素
int GetTop(LinkStack S) //返回S的栈顶元素
{
if (S != NULL)
return S->data; //返回栈顶元素的值
else
return -1;
}
1.2 栈的应用
1.2.1符号配对
1.2.2表达式转换
1.3 队列
队列:
1.3.1顺序队列:
- 结构体定义
typedef struct Squeue
{
DataType queue[QueueSize];
int front, rear;
}SeqQueue;
- 初始化队列
void InitQueue(SqQueue& q)
{
q = new Queue;
q->front = q->rear = -1;
}
2.进列
bool EnQueue(SeqQueue *S, DataType e)
{
if (S->front==(S->rear+1)%QueueSize)//循环
{
return false;
}
S->rear ++;
S->queue[S->rear] = e;
return true;
}
3.出列
bool DeQueue(SeqQueue *S, DataType &e)
{
if (S->front==S->rear)
{
return false;
}
else
{
S->front++;
e = S->queue[S->front];
return true;
}
}
1.3.2环形队列
- 结构体定义
typedef struct
{
ElemType data[MaxSize];
int front, rear;
}Queue;
typedef Queue* SqQueue;
- 初始化队列
void InitQueue(SqQueue& q)
{
q = new Queue;
q->front = q->rear = 0;
}
- 销毁队列
void DestroyQueue(SqQueue& q)
{
delete q;
}
- 进列
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;
e = q->data[q->front];
q->front = (q->front + 1) % MaxSize;
return true;
}
1.3.3链队列:采用链式存储结构的队列称为链队
- 定义结构体
typedef struct qnode
{
ElemType data;//数据元素
struct qnode* next;
}QNode;
- 初始化
void InitQueue(LinkQueue* Q)
{
Q->front = Q->rear = NULL;
}
2.进列
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;
}
1.3.4队列应用:
#include<iostream>
#define MAXQSIZE 100//队列可能达到的最大长度
#define OK 1
#define ERROR 0
#define OVERFLOW -2
using namespace std;
typedef struct {
char name[20]; //姓名
char sex; //性别,'F'表示女性,'M'表示男性
} Person;
//- - - - - 队列的顺序存储结构- - - - -
typedef struct {
Person data[MAXQSIZE];
int front; //头指针
int rear; //尾指针
} Queue;
typedef Queue *SqQueue;
SqQueue Mdancers, Fdancers; //分别存放男士和女士入队者队列
int InitQueue(SqQueue &Q);
void DestroyQueue(SqQueue &q);
int QueueLen(SqQueue Q);//队列长度
int EnQueue(SqQueue &Q, Person e);//加入队列
int QueueEmpty(SqQueue &Q);//队列是否为空
int DeQueue(SqQueue &Q, Person &e);//出队列
void DancePartner(Person dancer[], int num); //配对舞伴
int main(){
int i;
int n;
Person dancer[MAXQSIZE];
cin>>n;
for(i=0;i<n;i++) cin>> dancer[i].name >> dancer[i].sex;
InitQueue(Mdancers); //男士队列初始化
InitQueue(Fdancers); //女士队列初始化
cout << "The dancing partners are:" << endl;
DancePartner(dancer, n);
if (!QueueEmpty(Fdancers)) {
cout << "F:"<<QueueLen(Fdancers) ;
} else if (!QueueEmpty(Mdancers)) {
cout << "M:"<<QueueLen(Mdancers) ;
}
DestroyQueue(Fdancers);
DestroyQueue(Mdancers);
return 0;
}
int InitQueue(SqQueue &Q) {//构造一个空队列Q
Q = new Queue; //为队列分配一个最大容量为MAXSIZE的数组空间
if (!Q->data)
exit( OVERFLOW); //存储分配失败
Q->front = Q->rear = 0; //头指针和尾指针置为零,队列为空
return OK;
}
void DestroyQueue(SqQueue &q)
{
delete q;
}
2.PTA实验作业(4分)
2.1 符号配对
2.1.1 解题思路及伪代码
思路:先建立一个链栈,将字符串遍历,如果遇到左括号则入栈,遇到右括号就判断是否与栈顶的符号对应,是则栈顶元素出栈,继续遍历,遍历完成后,若栈空则输出yes,否则输出no
2.1.2 总结解题所用的知识点
- 栈的应用
- 扫描遍历字符串
- 判断字符为左括号,右括号,以及符号匹配的条件
2.2 银行业务队列简单模拟
2.2.1 解题思路及伪代码
思路:建立两个队列,一个单数号,另一个双数号,然后执行出队,在两队都不为空的前提下,每次执行两次第一队出队,一次第二队出队,若其中一队为空后,直接将另外一队全部出队
2.2.2 总结解题所用的知识点
- 队列的应用
- 队列的判断