一、栈
栈(stack):
- 先进后出(First In Last Out) FILO
- 只允许在一端 [栈顶(Top)] 进行插入或删除操作的线性表
1. 顺序表实现栈
入栈
S.data[++S.top]=1;
//上述代码可以拆解成
S.top=S.top+1;
S.data[S.top]=1;
出栈
x=S.data[S.top--];
//可以拆解成
x=S.data[S.top];
S.top=S.top-1;
2. 链表实现栈
考研中相对没有顺序实现重要,不过多了解
定义栈
LiStack Lhead=(LiStack)malloc(sizeof(struct Linknode));
Lhead->next=NULL;
LiStack top=NULL;
入栈
top=(LiStack)malloc(sizeof(struct Linknode));
top->next=NULL;
top->data=1;
top->next=Lhead->next;
Lhead->next=top;
出栈
//c:3
c=top->data;
Lhead->next=top->next;
free(top);
top=Lhead->next;
代码实战步骤:初始化栈、判断栈是否为空、压栈、获取栈顶元素、弹栈。
代码:
#include<stdio.h>
#include<stdlib.h>
#define MaxSize 50
typedef int ElemType;
typedef struct {
ElemType data[MaxSize];//数组
int top;//始终指向栈顶的一个变量
}SqStack;
//初始化栈
void init_stack(SqStack &S)
{
S.top=-1;//初始化栈,就是让S.top=-1.让栈为空
}
//判断栈是否为空
bool stack_empty(SqStack S)
{
if(S.top==-1)
{
return true;
}else{
return false;
}
}
//入栈
bool Push(SqStack &S,ElemType x)
{
//判断是否栈满
if(S.top==MaxSize-1)
{
return false;
}
S.data[++S.top]=x;//等价于S.top=S.top+1; S.data[S.top]=x;
return true;
}
//获取栈顶元素
bool get_top(SqStack S,ElemType &m)
{
//判断是否为空
if(stack_empty(S))
{
return false;//没拿到
}
m=S.data[S.top];//拿到栈顶元素
return true;
}
//弹栈
bool Pop(SqStack &S,ElemType &m)
{
//判断是否为空
if(stack_empty(S))
{
return false;//没拿到
}
m=S.data[S.top--];//出栈 等价于m=S.data[S.top]; S.top=S.top-1;
return true;
}
int main() {
SqStack S;
init_stack(S);
bool flag;
flag=stack_empty(S);
if(flag)
{
printf("stack is empty\n");
}
Push(S,3);//入栈元素3
Push(S,4);//入栈元素4
Push(S,5);//入栈元素5
ElemType m;
flag=get_top(S,m);
if(flag)
{
printf("get top %d\n",m);
}
flag=Pop(S,m);//弹出栈顶元素
if(flag)
{
printf("pop element %d\n",m);
}
return 0;
}
测试结果:
stack is empty
get top 5
pop element 5
二、队列
队列(queue):
- 先进先出(First In First Out) FIFO
- 只允许在表的一端进行插入,在表的另一端进行删除
1. 循环队列实战
判断循环队列满的条件
(Q.rear+1)%MaxSize==Q.front
代码:
#include <stdio.h>
#include<stdlib.h>
#define MaxSize 5
typedef int ElemType;
typedef struct{
ElemType data[MaxSize];//数组,存储MaxSize-1个元素
int front,rear;//队列头 队列尾
}SqQueue;
//初始化队列
void init_queue(SqQueue &Q)
{
Q.front=Q.rear=0;//初始化循环队列,就是让头和尾指向零
}
//判断循环队列是否为空
bool is_empty(SqQueue Q)
{
return Q.front==Q.rear;
}
//入队
bool en_queue(SqQueue &Q,ElemType x)
{
if((Q.rear+1)%MaxSize==Q.front)
{
return false;//队列满,不能入队
}
Q.data[Q.rear]=x;//放入元素
Q.rear=(Q.rear+1)%MaxSize;//rear+1,如果大于数组最大下标,回到开头
return true;
}
//出队
bool de_queue(SqQueue &Q,ElemType &x)
{
if(Q.rear==Q.front)//队列为空,无法出队
{
return false;
}
x=Q.data[Q.front];//出队
Q.front=(Q.front+1)%MaxSize;
return true;
}
//循环队列的代码实战
int main() {
SqQueue Q;
init_queue(Q);
bool ret;
ret=is_empty(Q);
if(ret)
{
printf("SqQueue is empty\n");
}else{
printf("SqQueue is not empty\n");
}
en_queue(Q,3);
en_queue(Q,4);
en_queue(Q,5);
ret = en_queue(Q,6);
ret = en_queue(Q,7);
if(ret)
{
printf("en_queue success\n");
}else{
printf("en_queue failed\n");
}
ElemType element;//存储出队元素
de_queue(Q,element);
if(ret)
{
printf("en_queue success %d\n",element);
}else{
printf("en_queue failed\n");
}
ret = en_queue(Q,8);
if(ret)
{
printf("en_queue success\n");
}else{
printf("en_queue failed\n");
}
return 0;
}
测试结果:
SqQueue is empty
en_queue failed
en_queue failed
en_queue success
2. 队列实战(通过链表实现)
代码:
#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 init_queue(LinkQueue &Q)
{
Q.front=Q.rear= (LinkNode*)malloc(sizeof(LinkNode));
Q.front->next=NULL;
}
//入队
void en_queue(LinkQueue &Q,ElemType x)
{
LinkNode *pnew=(LinkNode*) malloc(sizeof(LinkNode));
pnew->data=x;
pnew->next=NULL;//让next为空,否则遍历时结束不了
Q.rear->next=pnew;//尾指针的next指向pnew,从尾部入队
Q.rear=pnew;//rear指向新的尾部
}
//出队
bool de_queue(LinkQueue &Q,ElemType &x)
{
if(Q.rear==Q.front)//队列为空
{
return false;
}
LinkNode *q=Q.front->next;//拿到第一个结点,存入q
x=q->data;//获取要删除的元素值
Q.front->next=q->next;//让一个结点断链
if(Q.rear==q)//链表只剩余一个结点时,被删后,要改变rear
{
Q.rear=Q.front;
}
free(q);
return true;
}
int main() {
LinkQueue Q;
init_queue(Q);//初始化队列
en_queue(Q,3);
en_queue(Q,4);
en_queue(Q,5);
en_queue(Q,6);
en_queue(Q,7);
ElemType element;
bool ret;
ret=de_queue(Q,element);
if(ret)
{
printf("de_queue success %d\n",element);
} else{
printf("de_queue failed\n");
}
return 0;
}
测试结果:
de_queue success 3