DS博客作业02--栈和队列

| 这个作业属于哪个班级 | 数据结构-网络20 |
| ---- | ---- | ---- |
| 这个作业的地址 | DS博客作业02--栈和队列 |
| 这个作业的目标 | 学习栈语言--网络2011/2012和队列的结构设计及运算操作 |
| 姓名 | 梁桢 |

0.PTA得分截图

1.本周学习总结(0-5分)

1.1 栈

1.1.1画一个栈的图形,介绍如下内容。

  • 定义:栈是一种只能在一端进行插入或删除操作的线性表。表中允许进行插入,删除的一端称为栈顶。
  • 进栈:插入操作
  • 出栈:删除操作
  • 出栈顺序:后进先出。例如:上图中的出栈顺序为an,an-1,....,a2,a1
  • 存储结构:顺序栈,链栈

1.1.2 顺序栈

  • 顺序栈:采用顺序存储结构的栈称为顺序栈
  1. 结构体定义
typedef struct                 
{
   ElemType data[MaxSize];
   int top;   //栈顶指针
}Stack,*SqStack;
  1. 初始化:
void CreatStack(SqStack s) {
	s = new Stack;
	s->top = -1;
}
  1. 进栈:
    tip:先要判断栈是否满
bool Push(SqStack s, ElemType e) {
	if (s->top == MaxSize-1) {
		printf("栈满");
		return false;
	}
	s->data[++s->top] = e;
	return true;
}

  1. 出栈:先要判断栈是否为空
bool Pop(SqStack s, ElemType e) {
	if (s->top == -1) {
		printf("栈空");
		return false;
	}
	e=s->data[s->top--];
	return true;
}
  • 对栈进行操作时都要考虑栈满或空,应该预先进行判断

1.1.3 链栈

  • 链栈:采用链式存储结构的栈称为链栈,这里采用带头节点的单链表来实现链栈
  1. 结构体定义
typedef struct linkstack
{
    ElemType data;
    struct linkstack *next;
}StStack,*LinkStack;

  1. 初始化栈
void InitStack(LiStack& s)
{
	s = new LiNode;
	s->next = NULL;
}
  1. 进栈
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;
}
  1. 出栈
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;
}
  1. 取栈顶元素
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顺序队列:

  1. 结构体定义
typedef struct Squeue
{
	DataType queue[QueueSize];
	int front, rear;
}SeqQueue;
  1. 初始化队列
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环形队列

  1. 结构体定义
typedef struct
{
	ElemType data[MaxSize];
	int front, rear;
}Queue;
typedef Queue* SqQueue;
  1. 初始化队列
void InitQueue(SqQueue& q)
{
	q = new Queue;
	q->front = q->rear = 0;
}
  1. 销毁队列
void DestroyQueue(SqQueue& q)
{
	delete q;
}
  1. 进列
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;
}
  1. 出列
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链队列:采用链式存储结构的队列称为链队

  1. 定义结构体
typedef struct qnode
{
	ElemType data;//数据元素
	struct qnode* next;
}QNode;
  1. 初始化
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;             //指向队列尾
    }
}
  1. 出列
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 总结解题所用的知识点

  1. 栈的应用
  2. 扫描遍历字符串
  3. 判断字符为左括号,右括号,以及符号匹配的条件

2.2 银行业务队列简单模拟

银行业务队列简单模拟

2.2.1 解题思路及伪代码

思路:建立两个队列,一个单数号,另一个双数号,然后执行出队,在两队都不为空的前提下,每次执行两次第一队出队,一次第二队出队,若其中一队为空后,直接将另外一队全部出队

2.2.2 总结解题所用的知识点

  1. 队列的应用
  2. 队列的判断
posted @ 2021-04-05 21:56  一笑惜命  阅读(86)  评论(0编辑  收藏  举报