DS博客作业02
2021-04-05 22:09 米奈希尔。 阅读(86) 评论(1) 编辑 收藏 举报| 这个作业属于哪个班级 | C语言--网络2011/2012 |
| ---- | ---- | ---- |
| 这个作业的地址 | DS博客作业02--栈和队列 |
| 这个作业的目标 | 学习栈和队列的结构设计及运算操作。 |
|姓名 | 罗发槺 |
0.PTA得分截图
1.本周学习总结(0-5分)
1.1 栈
- 栈(stack)是一种只能在一端进行插入或删除操作的线性表。表中允操作的一端称为栈顶(top),
表的另一端称为栈底(bottom),如图3.1所示。栈顶的当前位置是动态的,栈顶的当前位置由一个被称
为栈顶指针的位置指示器来指示。当栈中没有数据元素时称为空栈。栈的插人操作通常称为进栈或入
栈( push),栈的删除操作通常称为出栈或退栈(pop)。 - 栈的主要特点是“后进先出”(Last In First Out,LIFO),即后进栈的元素先出栈。每次进栈的
数据元素都放在原来栈顶元素之前成为新的栈顶元素,每次出栈的数据元素都是当前栈顶元素。栈也
称为后进先出表。
1.11顺序栈的结构、操作函数
-
- 顺序栈的结构体定义
typedef int Position;
typedef struct SNode *PtrToSNode;
struct SNode {
ElementType *Data; /* 存储元素的数组 */
Position Top; /* 栈顶指针 */
int MaxSize; /* 堆栈最大容量 */
};
typedef PtrToSNode Stack;
- 2.初始化栈
Stack CreateStack( int MaxSize )
{
Stack S = (Stack)malloc(sizeof(struct SNode));
S->Data = (ElementType *)malloc(MaxSize * sizeof(ElementType));
S->Top = 0;
S->MaxSize = MaxSize;
return S;
}
- 3.进栈
bool Push(Stack S, ElementType X)
{
if (S->MaxSize == S->Top)
{
puts("Stack Full");
return 0;
}
S->Data[S->Top++]=X;
return 1;
}
- 4.出栈
ElementType Pop(Stack S)
{
if (!S->Top)
{
puts("Stack Empty");
return ERROR;
}
return S->Data[--S->Top];
}
- 5.输出栈的元素
void PrintStack(Stack S)
{
while (S->Top)
printf("%d ", S->Data[--S->Top]);
puts("");
}
- 6.判空和销毁栈
bool StackEmpty(Stack S)
{
return S->top==-1;
}
void DesStack(SqStack &S)
{
free(s);
}
1.12链栈的结构、操作函数
-
- 链栈的结构体定义
typedef struct linknode
{
ElemType data;
struct linknode *next;
}LinkStNode;
- 2.初始化栈
void InitStack(LinkStNode *&s)
{
s = (LinkStNode*)malloc(sizeof(LinkStNode));
s->next=NULL;
}
- 3.销毁栈
void DestroyStack(LinkStNodew& s)
{
LinkStNode* pre - s, * p = s->next;
while(p!- NULL)//pre指向头结点指向首结点
{
free(pre);//循环到书为空
pre = p://释放pre销版
p = pre->next;// pre.p同步后移
}
free(pre);//此时pre指向尾结点,释放其空间
}
- 4.进栈
void Push(LinkStNode n& s, ElemType e)
{
LinkStNode* p;
p = (LinkStNode*)malloc(sizeof(LinkStNode));
p->data = e;
p->next = s->next;
s->next = p;
}
- 5.出栈
bool Pop(LinkStNode*& s, ElemType& e)
{
LinkStNode* p;
if (s->next == NULL)
return false;
p = s->next;
e = p - > data;
s->next = p->next;
free(p);
return ture;
}
- 6.取栈顶元素
bool GetTop(LinkStNode* s, ElemType& s)
{
if (s->next == NULL)
return false;
e = s->next->data;
return true;
}
1.2 栈的应用
表达式转换
转换原则
- 遇到操作数, 直接输出
- 操作符的优先级为 () 最大, * / 次之, +- 最小. 遇到操作符后, 假如操作符堆栈为空, 则直接压入操作符, 否则判断当前操作符与栈顶操作符的优先关系, 假如栈顶操作符的优先级大于 等于当前操作符的优先级, 那么弹出栈顶操作符, 持续弹出, 直到栈顶操作符优先级小于当前操作符优先级或栈为空. 最后将当前操作符入栈
- 如果遇到右括号, 那么将栈顶操作符弹出, 持续弹出直到遇到左括号, 左括号弹出但不输出
- 表达式读入完毕, 若栈不为空, 则持续弹出栈顶操作符, 直到栈为空
迷宫求解
1.3 队列
- 队列(queue)简称队,它也是一种操作受限的线性表,其限制为仅允许在表的一端进行插人操作,而在表的
另一端进行删除操作。把进行插人的一端称为队尾(rear),把进行删除的一端称为队头或队首(front),如图
所示。向队列中插入新元素称为进队或入队(enqueue),新元素进队后就成为新的队尾元素;从队列中删除元
素称为出队或离队(dequeue),元素出队后,其直接后继元素就成为队首元素。 - 由于队列的插人和删除操作分别是在各自的一端进行的,每个元素必然按照进入的次序出队,所以又把队列
称为先进先出表(FirstIn First Out. FIFO)。
1.31 顺序队列
- 1.队列的结构体定义
typedef struct {
Person data[MAXQSIZE];
int front; //头指针
int rear; //尾指针
} Queue;
- 2.初始化队列
int InitQueue(SqQueue &Q) {//构造一个空队列Q
Q = new Queue; //为队列分配一个最大容量为MAXSIZE的数组空间
if (!Q->data)
exit( OVERFLOW); //存储分配失败
Q->front = Q->rear = 0; //头指针和尾指针置为零,队列为空
return OK;
}
- 3.进队
bool enQueue(SqQueue *&q,ElemType e)
{
if(q->rear==MaxSize-1)
return false;
q->rear++;
q->data[q->rear]=e;
return true;
}
- 4.出队
bool deQueue(SqQueue *&q,ElemType &e)
{
if(q->front==q->rear)
return false;
q->front++;
e=q->data[q->front];
return true;
}
- 5.判空和销毁队列
bool QueueEmpty(SqQueue *q)
{
return q->front==q->rear;
}
bool DestoryQueue(SqQueue *&q)
{
free(q);
}
1.32 链队列
- 1.结构体定义
typedef struct qnode
{
Elemtype data;
struct qnode* next;
}DataNode;
typedef struct
{
DataNode front;//队头指针;
DataNode rear;//队尾指针;
}LinkQuNode;
- 2.初始化队列
void InitQueue(LinkQueue& q)
{
q = (LinkQuNode*)malloc(sizeof(LinkQuNode));
q.front->next = NULL;
q.rear->next = NULL;
}
- 3.进队
void eeQueue(LinkQuNode*& q, Elmetype& e)
{
DataNode* t;
t = (DataNode*)malloc(sizeof(DataNode));
t->data = e;
t->next = NULL;
if (q->rear == NULL)
q->front = q->rear = t;
else
{
q->rear->next = t;
q->rear = t;
}
}
- 4.出队
bool deQueue(LinkQuNode*& q, Elmetype& e)
{
DataNode* t;
if (q->rear == NULL)
return false;
t = q->front;
if (q->front == q->rear)
q->front = q->rear = NULL;
else
q->front = q->front->next;
e = t->data;
free(t);
return true;
}
1.33环形队列
- 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;
}
- 2.出队
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;
}
1.4队列的应用
1.舞伴
2.报数
2.PTA实验作业
2.1 符号配对
2.1.1
- 解题思路:利用各种条件来限制进栈和出栈的条件
*伪代码
int len = strlen(s);
for i=0 to len
if不是括号
continue
endif
if是左括号
进栈
endif
else if是右括号
{
if栈空
break;
if是右括号且栈顶是左括号
出栈
}
endif
endfor
if栈空且i=len
输出yes
else if栈空
输出no
else
输出栈顶和no
2.1.2 总结解题所用的知识点
- 1.stl库的stack容器,可以调用已有的函数进行操作,极大的方便了代码的编程
- 2.c++的cin和cout
- 3.C语言的for和if ,else等
2.2 银行业务队列简单模拟
2.2.1 解题思路及伪代码
- 解题思路
先对奇偶数进行队列的输入,然后按照先出2个A在出1个B进行输出,等到一个空了之后再把没空的全部输出。 - 伪代码
queue<int> a, b;
for i=1 to n
if奇的
进入b队列
else
进入a队列
endfor
while a or b 不空
for 1 to 2
输出a.front
a.pop
endfor
输出b.front
b.pop
endwhile
输出不空的队列的全部元素
2.2.2 总结解题所用的知识点
- 1.stl库的queue容器,可以调用已有的函数进行操作,极大的方便了代码的编程
- 2.c++的cin和cout
- 3.C语言的for,while和if ,else等
3.阅读代码
3.1 题目及解题代码
class Solution {
public:
int countStudents(vector<int>& students, vector<int>& sandwiches) {
int stusum=0;
for(int i=0;i<students.size();i++)
stusum+=students[i];
queue<int> q;
for(int i=0;i<students.size();i++)
q.push(students[i]);
int i=0;
while(i<sandwiches.size()){
if(q.front()==sandwiches[i]){
stusum-=sandwiches[i];
q.pop();
i++;
}
else{
q.push(q.front());
q.pop();
}
if(q.size()==0)
break;
if((sandwiches[i]!=q.front() && stusum==0 )||(sandwiches[i]!=q.front() &&stusum==q.size()))
break;
}
return sandwiches.size()-i;
}
};
作者:ZackQwQ
链接:https://leetcode-cn.com/problems/number-of-students-unable-to-eat-lunch/solution/c-dui-lie-queue-by-zackcai-wngn/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
3.2 该题的设计思路及伪代码
设计思路:先对喜好值进行求和,然后让学生数组进入队列,再利用循环来对队伍的第一个人的喜好进行挑选,符合条件的就把之前计数好的减去喜好值,最后用喜好值来进行条件限制循环的结束。
定义一个整型数studum来计数
for 0 to 学生数
stusum加学生是1的数
endfor
定义一个queue容器q
for 0 to 学生数
学生数组进队列
endfor
int i
while小于三明治数
if队列第一个数等于sandwiches[i]
{
stusum-sandwiches[i]
endif
q.pop
i++;
}
else
{
队列第一个数进栈
出栈
}
if队列没有元素就退出循环
if((sandwiches[i]!=q.front() && stusum==0 )||(sandwiches[i]!=q.front() &&stusum==q.size()))
break;
endif
endwhile
return 三明治容器元素-1;
3.3 分析该题目解题优势及难点。
难点:对于条件的限制和对学生喜欢的三明治的比较如何设计。
优势:利用stl库的函数进行代码编程,不用自己来书写多余代码,大大提高了效率而且是的代码简洁美观。
【推荐】国内首个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训练数据并当服务器共享给他人