三、栈、队列和数组

三、栈、队列和数组

在这里插入图片描述

一、栈

栈是一种运算受限的线性表,插入和删除运算只允许在表的某一端进行,栈的特点是先进后出

栈的基本运算包括:初始化判空栈进栈出栈取栈顶

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();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值