三、栈、队列和数组
一、栈
栈是一种运算受限的线性表,插入和删除运算只允许在表的某一端进行,栈的特点是先进后出
。
栈的基本运算包括:初始化
、判空栈
、进栈
、出栈
、取栈顶
。
1.1 顺序栈
#include <stdio.h>
// 定义栈的大小
const int maxsize = 6;
typedef int DataType; // 给int类型加一个别名
typedef struct seqstack {
DataType data[maxsize];
int top;
} Seqstack;
// 1. 初始化
int InitStack(Seqstack *stack) {
stack->top = -1;
return 1;
}
// 2. 判断栈为空,为空返回1,否则返回0
int EmptyStack(Seqstack *stack) {
return stack->top == -1;
}
// 3. 进栈 top相当于数据下标
int PushStack(Seqstack *stack, DataType x) {
if (stack->top == maxsize - 1) {
// 栈已满
return 0;
} else {
stack->top++;
stack->data[stack->top] = x;
return 1;
}
}
// 4. 出栈
int Pop(Seqstack *stack) {
if (EmptyStack(stack)) {
// 栈为空
return 0;
}
stack->top--;
return 1;
}
// 5. 获取栈顶元素
DataType GetTop(Seqstack *stack) {
if (EmptyStack(stack)) return NULL;
return stack->data[stack->top];
}
void printfArray(DataType datas[], int size) {
for (int i = 0; i <= size; i++) {
printf("for stack data: i=%d, data=%d \n", i, datas[i]);
}
}
int main() {
// 初始化
Seqstack stack;
int i = InitStack(&stack);
printf("initialized. top=%d ,i=%d\n", stack.top, i);
// 栈判空
Seqstack stk; // 必须初始化然后才能调用判空
int empty = EmptyStack(&stack);
printf("EmptyStack %d \n", empty);
// 进栈
int push = PushStack(&stack, 5);
PushStack(&stack, 8);
printf("push result: %d \n", push);
printfArray(stack.data, stack.top);
// 出栈
int pop = Pop(&stack);
printf("Pop result: %d \n", pop);
printfArray(stack.data, stack.top);
// 获取栈顶元素
DataType dt = GetTop(&stack);
printf("GetTop: %d \n", dt);
return 0;
}
1.2 链栈
#include<stdio.h>
#include <stdlib.h>
typedef int DataType;
typedef struct node {
DataType data; // 当前元素
struct node *next; //当前元素的下一个
} LkStk;
// 1. 初始化
int InitStack(LkStk **LS) {
// malloc 分配内存地址, sizeof计算每个对象占用的内存大小
*LS = (LkStk *) malloc(sizeof(LkStk));
(*LS)->next = NULL;
return 1;
}
// 2. 判断栈空
int EmptyStack(LkStk *LS) {
return LS->next == NULL;
}
// 3. 进栈
int PushStack(LkStk *LS, DataType x) {
LkStk *newData = (LkStk *) malloc(sizeof(LkStk));
newData->data = x;
newData->next = LS->next;
LS->next = newData;
return 1;
}
// 4. 出栈
int PopStack(LkStk *LS) {
if (EmptyStack(LS)) return 0;
LkStk *dls = LS->next;
LS->next = dls->next;
free(dls);
return 1;
}
// 5. 获取栈顶元素
DataType GetTop(LkStk *LS) {
if (EmptyStack(LS)) {
// 栈为空
return NULL;
}
return LS->next->data;
}
int main() {
// 1. 初始化
LkStk *LS;
int init = InitStack(&LS);
printf("InitStack result: %d \n", init);
// 2. 栈判空
int empty = EmptyStack(LS);
printf("EmptyStack result: %d \n", empty);
// 3. 进栈
int push = PushStack(LS, 10);
PushStack(LS, 18);
PushStack(LS, 28);
printf("PushStack:%d \n", push);
// 4. 出栈
int pop = PopStack(LS);
printf("PopStack: %d \n", pop);
// 5. 获取栈顶元素
int data = GetTop(LS);
printf("GetTop: %d \n", data);
}
二、队列
2.1 队列的顺序实现
#include<stdio.h>
// 定义队列的长度
const int maxsize = 5;
typedef int DataType;
typedef struct seqqueue {
DataType data[maxsize];
int front, rear;
} SeqQue;
// 1. 初始化
void InitQueue(SeqQue *CQ) {
CQ->front = 0;
CQ->rear = 0;
}
//2. 队列判空
int EmptyQueue(SeqQue *CQ) {
return CQ->rear == CQ->front;
}
//3. 入队列
int PushQueue(SeqQue *CQ, DataType x) {
if ((CQ->rear + 1) % maxsize == CQ->front) {
//队列已满
return 0;
}
CQ->data[CQ->rear ] = x;
CQ->rear = (CQ->rear + 1) % maxsize;
return 1;
}
//4. 出队列
int PopQueue(SeqQue *CQ) {
if (EmptyQueue(CQ)) {
// 队列为空
return 0;
}
CQ->front = (CQ->front + 1) % maxsize;
return 1;
}
//5.获取队列首元素
DataType GetTop(SeqQue *CQ) {
if (EmptyQueue(CQ)) {
// 队列为空
return 0;
}
return CQ->data[CQ->front];
}
int main() {
// 1.初始化
SeqQue CQ;
InitQueue(&CQ);
// 2.队列判空
int empty = EmptyQueue(&CQ);
printf("empty: %d \n", empty);
// 3. 入队列 循环队列会比原始长度少1
PushQueue(&CQ, 5);
PushQueue(&CQ, 8);
PushQueue(&CQ, 9);
PushQueue(&CQ, 12);
int push = PushQueue(&CQ, 15);
printf("push: %d \n", push);
//4. 出队列
int pop = PopQueue(&CQ);
printf("pop: %d \n", pop);
int data = GetTop(&CQ);
printf("getTop: %d \n", data);
return 1;
}
2.2 队列的链接实现
//
// Created by 84344 on 2024/11/5.
//
#include<stdio.h>
#include <stdlib.h>
typedef int DataType;
const int maxsize = 5;
typedef struct Node {
struct Node *next;
DataType data;
} Node;
typedef struct LkQueue {
Node *front, *rear;
} LkQueue;
// 1.初始化
void InitQueue(LkQueue *L) {
Node *temp = (Node *) malloc(sizeof(Node));
L->front = temp;
L->rear = temp;
L->front->next = NULL;
}
// 2. 队列判空
int EmptyQueue(LkQueue *L) {
return L->rear == L->front;
}
// 3.入队列
int PushQueue(LkQueue *L, DataType x) {
Node *newNode = (Node *) malloc(sizeof(Node));
newNode->data = x;
newNode->next = NULL;
L->rear->next = newNode;
L->rear = newNode;
return 1;
}
// 4.出队列
int OutQueue(LkQueue *L) {
if (EmptyQueue(L)) {
// 队列为空
return 0;
}
Node *temp = L->front->next;
L->front->next = temp->next;
if (L->front->next == NULL) {
L->rear = L->front;
}
free(temp);
return 1;
}
// 5. 获取队首元素
DataType GetHead(LkQueue *L) {
if (EmptyQueue(L)) {
// 队列为空
return NULL;
}
return L->front->next->data;
}
int main() {
// 1.初始化
LkQueue L;
InitQueue(&L);
// 2. 队列判空
int empty = EmptyQueue(&L);
printf("empty: %d \n", empty);
//3. 入队列
PushQueue(&L, 19);
PushQueue(&L, 29);
int push = PushQueue(&L, 23);
printf("push: %d \n", push);
//4. 出队列
int out = OutQueue(&L);
printf("out: %d \n", out);
int headData = GetHead(&L);
printf("headData: %d \n", headData);
}
2.3 队列的应用
模拟银行客户排队场景
//
// Created by 84344 on 2024/11/6.
//
#include<stdio.h>
#include <stdlib.h>
typedef int DataType;
typedef struct Node {
struct Node *next;
DataType data;
} Node;
typedef struct LkQue {
Node *front, *rear;
};
// 1. 初始化
void InitQue(LkQue *LQ) {
Node *init = (Node *) malloc(sizeof(Node));
init->next = NULL;
LQ->rear = init;
LQ->front = init;
}
// 队列判空
int EmptyQue(LkQue *LQ) {
return LQ->rear == LQ->front;
}
// 进队列
int EnQue(LkQue *LQ, DataType n) {
Node *nNode = (Node *) malloc(sizeof(Node));
nNode->data = n;
nNode->next = NULL;
LQ->rear->next = nNode;
LQ->rear = nNode;
return 1;
}
int OutQue(LkQue *LQ) {
if (EmptyQue(LQ)) return 0;
Node *temp = LQ->front->next;
LQ->front->next = temp->next;
if (LQ->front->next == NULL) {
LQ->rear = LQ->front;
}
free(temp);
return 1;
}
// 获取队首
DataType GetTop(LkQue *LQ) {
if (EmptyQue(LQ)) return NULL;
return LQ->front->next->data;
}
void GetService() {
LkQue LQ;
int n;
char ch;
InitQue(&LQ);
while (1) {
printf("\n 请输入命令:");
scanf("%c", &ch);
switch (ch) {
case 'A':
printf("客户取号 \n");
scanf("%d", &n);
EnQue(&LQ, n);
break;
case 'N':
if (!EmptyQue(&LQ)) {
n = GetTop(&LQ);
OutQue(&LQ);
printf("号为 %d的客户接受服务", n);
} else {
printf("无人等待服务 \n");
}
break;
case 'Q':
printf("排队等候的人依次接受服务");
break;
}
if (ch == 'Q') {
while (!EmptyQue(&LQ)) {
n = GetTop(&LQ);
OutQue(&LQ);
printf("号为 %d的客户接受服务while", n);
}
break;
}
}
}
int main() {
GetService();
}