一、栈
1.栈的介绍
后进先出,只允许在一端进行插入和删除操作的线性表
2.栈的基本操作
注:栈的插入和删除操作都在栈顶
3.栈的算法思路
1>顺序存储实现栈
注:弹栈不改变栈顶元素,只是改变栈顶指针top,下一步入栈会自动覆盖元素
* 栈空的条件:s.top=-1 * 栈满的条件:s.top=MaxSize-1
2>链式存储实现栈
4.代码实战
#include <stdio.h>
#define MaxSize 50
typedef int ElemType;
typedef struct{
ElemType data[MaxSize];
int top;
}SqStack;
void InitStack(SqStack &S)
{
S.top=-1;
}
bool StackEmpty(SqStack S)
{
if(-1==S.top)
{
return true;
}else{
return false;
}
}
bool Push(SqStack &S,ElemType x)
{
if(S.top>=MaxSize-1)
{
return false;
}
S.data[++S.top]=x;
return true;
}
bool GetTop(SqStack S,ElemType &m)
{
if(StackEmpty(S))
{
return false;
}
m=S.data[S.top];
return true;
}
bool Pop(SqStack &S,ElemType &m)
{
if(StackEmpty(S))
{
return false;
}
m=S.data[S.top--];
return true;
}
int main() {
SqStack S;
InitStack(S);
bool flag;
flag=StackEmpty(S);
if(flag)
{
printf("stack is empty\n");
}
Push(S,3);
Push(S,4);
Push(S,5);
ElemType m;
flag=GetTop(S,m);
if(flag)
{
printf("get top %d\n",m);
}
flag=Pop(S,m);
if(flag)
{
printf("pop element %d\n",m);
}
return 0;
}
二、队列
1.队列特性
2.循环队列
3.循环队列入队&出队
4.队列的链式存储
5.队列代码实战
初始化队列(含头结点)->>入队->>出队->>判断队列是否为空(基于循环队列)
#include <stdio.h>
#define MaxSize 5
typedef int ElemType;
typedef struct{
ElemType data[MaxSize];
int front,rear;
}SqQueue;
void InitQueue(SqQueue &Q)
{
Q.rear=Q.front=0; //这里不能是等于,只能是赋值,等于只能返回0/1,而这里又无返回值,等于不能真正使两者数据发生变化,所以后续的为空判断就无效了
}
bool IsEmpty(SqQueue Q)
{
return Q.rear==Q.front; //优化代码条数,该判断语句就可直接拿到true和FALSE的返回值
}
bool EnQueue(SqQueue &Q,ElemType x)
{
if((Q.rear+1)%MaxSize==Q.front)
{
return false;
}
Q.data[Q.rear]=x;
Q.rear=(Q.rear+1)%MaxSize;
return true;
}
bool DeQueue(SqQueue &Q,ElemType &m)
{
if(Q.front==Q.rear)
{
return false;
}
m=Q.data[Q.front];
Q.front=(Q.front+1)%MaxSize;
return true;
}
int main() {
SqQueue Q;
InitQueue(Q);
bool ret;
ret=IsEmpty(Q);
if(ret)
{
printf("SqQueue is Empty\n");
}else{
printf("SqQueue is not Empty\n");
}
EnQueue(Q,3);
EnQueue(Q,4);
EnQueue(Q,5);
ret=EnQueue(Q,6);
ret=EnQueue(Q,7);
if(ret)
{
printf("EnQueue success\n");
}else{
printf("EnQueue failed\n");
}
ElemType m;
ret=DeQueue(Q,m);
if(ret)
{
printf("DeQueue success\n");
}else{
printf("DeQueue failed\n");
}
ret=EnQueue(Q,8);
if(ret)
{
printf("EnQueue success\n");
}else{
printf("EnQueue failed\n");
}
return 0;
}
队列的实战->>通过链表实现
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct LinkNode{
ElemType data;
struct LinkNode *next;
}LinkNode;
typedef struct{
LinkNode *front,*rear;
}LinkQueue;
void InitQueue(LinkQueue &S)
{
S.front=S.rear=(LinkNode*)malloc(sizeof(LinkNode));
S.front->next=NULL;
}
bool IsEmpty(LinkQueue S)
{
return S.front==S.rear;
}
void EnQueue(LinkQueue &S,ElemType x)
{
LinkNode *p=(LinkNode*)malloc(sizeof(LinkNode));
p->data=x;
p->next=NULL;
S.rear->next=p;
S.rear=p;
}
bool DeQueue(LinkQueue &S,ElemType &element)
{
if(S.front==S.rear)
{
return false;
}
LinkNode *q=S.front->next;
element=q->data;
S.front->next=q->next;
if(S.rear==q)
{
S.rear=S.front;
}
free(q);
return true;
}
int main() {
LinkQueue S;
InitQueue(S);
bool ret;
ret=IsEmpty(S);
if(ret)
{
printf("LinkQueue is empty\n");
}else{
printf("LinkQueue is not empty\n");
}
EnQueue(S,3);
EnQueue(S,4);
EnQueue(S,5);
EnQueue(S,6);
EnQueue(S,7);
ElemType element;
ret=DeQueue(S,element);
if(ret)
{
printf("DeQueue success element= %d\n",element);
}else{
printf("DeQueue failed\n");
}
return 0;
}
三、2019年42题解析
* 思路分析:
* 代码
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct LNode {
ElemType data;
struct LNode* next;//指向下一个结点
}LNode,*LinkList;
void EnQueue(LinkList front, LinkList& rear, ElemType val)
{
LinkList pnew;
if (rear->next == front)//判断队列是不是满了
{
//队列满,申请一个结点的空间,放入队列
pnew= (LinkList)malloc(sizeof(LNode));
rear->data = val;//把入队元素放入rear指向结点
rear->next = pnew;//放了一个结点,其相当于做了分割
pnew->next = front;
rear = pnew;
}
else {//如果队列不满,直接放值,让rear后移一个结点
rear->data = val;
rear = rear->next;
}
}
void DeQueue(LinkList& front, LinkList rear)
{
if (front == rear)
{
printf("queue is empty\n");
}
else {
printf("dequeue %d\n", front->data);
front = front->next;
}
}
void CircleQueue(LinkList& front, LinkList& rear)
{
//队列头和队列尾都指向一个结点,这时队列既是空的,也是满的
front = (LinkList)malloc(sizeof(LNode));
rear = front;
rear->next = front;//构造循环队列
//入队
EnQueue(front, rear, 3);
EnQueue(front, rear, 4);
//出队
DeQueue(front, rear);
DeQueue(front, rear);
DeQueue(front, rear);
}
int main()
{
LinkList front, rear;
CircleQueue(front, rear);
return 0;
}