栈与队列的基本操作(c学习)

栈的理解:

物理意义上的栈是在内存中是给函数开辟空间的一块区域。举个例子,当我使用自定义函数的时候,内存中的栈区会开辟一块空间给这个函数,然后当退出这块区域时,会销毁这块区域。

而承接这块开辟区域的物理方式之一就是数组,所以今天我将带大家通过数组的角度来理解栈

栈的基本操作

栈是一种后进先出(LIFO)的数据结构,主要操作包括:

  • 初始化栈:创建一个空栈,通常需要分配内存空间并设置栈顶指针。
  • #include <stdio.h>
    #include <stdlib.h>
    
    //先确定我要存放的有效元素的最大值
    #define MAX_SIZE 100
    
    //栈的结构体定义
    typedef struct {
    
        int data[MAX_SIZE];//存放元素的空间,也就是栈
    
        int top;//指向首个插入元素的位置,也就是栈顶
    
    } Stack;
    
    //栈的初始化,表示栈为空
    void initStack(Stack *s) {
        s->top = -1;
    }
    

  • 入栈(Push):将元素添加到栈顶,栈顶指针向上移动。
  • // 判断栈是否已满
    int isFull(Stack *s) {
        return s->top == MAX_SIZE - 1;  // 栈顶达到最大索引则为满
    }
    
    // 入栈操作:向栈顶添加元素
    int push(Stack *s, int value) {
        if (isFull(s)) {
            printf("栈已满,无法入栈\n");
            return 0;  // 入栈失败
        }
        s->top++;               // 栈顶指针上移
        s->data[s->top] = value;  // 将元素存入栈顶位置
        return 1;  // 入栈成功
    }

  • 出栈(Pop):移除栈顶元素并返回其值,栈顶指针向下移动。
  • // 出栈操作:从栈顶移除元素,并返回该元素
    int pop(Stack *s, int *value) {
        if (isEmpty(s)) {
            printf("栈为空,无法出栈\n");
            return 0;  // 出栈失败
        }
        *value = s->data[s->top];  // 获取栈顶元素
        s->top--;                  // 栈顶指针下移
        return 1;  // 出栈成功
    }

  • 获取栈顶元素(Peek/Top):返回栈顶元素的值,但不移除它。
  • // 获取栈顶元素,但不移除
    int getTop(Stack *s, int *value) {
        if (isEmpty(s)) {
            printf("栈为空,无栈顶元素\n");
            return 0;  // 获取失败
        }
        *value = s->data[s->top];  // 获取栈顶元素
        return 1;  // 获取成功
    }

  • 判断栈是否为空(IsEmpty):检查栈中是否有元素。
  • // 判断栈是否为空
    int isEmpty(Stack *s) {
        return s->top == -1;  // 栈顶为-1则为空
    }

  • 获取栈的大小(Size):返回栈中元素的数量。

栈学习中的问题:

1、首先带大家理清的是top的初始化,这和入栈这步操作是脱离不了干系的,当我们想插入元素时,我们同时也要让top向后移,方便下一步操作,这时我们就需要根据top后移和插入元素这两步的先后关系来定义top的初始值,因为我们要始终要让top指向栈顶元素的位置,所以在上述代码中,我是先进行top++,因此当插入元素时,我们就应该使top的值为0(因为数组首元素下标为0),所以我们会初始化top为-1。

目录

栈的理解:

栈的基本操作

队列的基本操作

栈的C语言实现示例

队列的C语言实现示例

注意事项


队列的基本操作

队列是一种先进先出(FIFO)的数据结构,类型有链式队列和顺序队列,接下来我讲的是顺序队列:

  • 初始化队列:创建一个空队列,通常需要分配内存空间并设置队首和队尾指针。
  • // 顺序队列结构体
    typedef struct {
        int data[MAX_SIZE];  // 存储队列元素的数组
        int front;           // 队头指针(指向队头元素)
        int rear;            // 队尾指针(指向队尾元素的下一个位置)
    } SeqQueue;
    
    // 初始化队列(创建空队列)
    void initQueue(SeqQueue *q) {
        q->front = 0;  // 队头初始化为0
        q->rear = 0;   // 队尾初始化为0(表示队列为空)
    }

  • 入队(Enqueue):将元素添加到队尾,队尾指针向后移动。
  • // 入队操作
    int enqueue(SeqQueue *q, int value) {
        if (isFull(q)) {
            printf("队列已满,无法入队\n");
            return 0;
        }
        q->data[q->rear] = value;               // 存入元素
        q->rear = (q->rear + 1) % MAX_SIZE;     // 队尾指针后移(循环队列)
        return 1;
    }

  • 出队(Dequeue):移除队首元素并返回其值,队首指针向后移动。
  • / 出队操作
    int dequeue(SeqQueue *q, int *value) {
        if (isEmpty(q)) {
            printf("队列为空,无法出队\n");
            return 0;
        }
        *value = q->data[q->front];             // 取出队头元素
        q->front = (q->front + 1) % MAX_SIZE;   // 队头指针后移(循环队列)
        return 1;
    }

  • 获取队首元素(Front):返回队首元素的值,但不移除它。
  • / 顺序队列获取队首元素(不删除)
    int getSeqQueueFront(SeqQueue *q, int *value) {
        if (q->front == q->rear) {  // 队列为空
            return 0;  // 获取失败
        }
        *value = q->data[q->front];  // 仅返回队首元素值,不修改队列
        return 1;  // 获取成功
    }

  • 判断队列是否为空(IsEmpty):检查队列中是否有元素。
  • // 判断队列是否为空
    int isEmpty(SeqQueue *q) {
        return q->front == q->rear;
    }

  • 获取队列的大小(Size):返回队列中元素的数量。
  • // 获取顺序队列大小
    int getSeqQueueSize(SeqQueue *q) {
        // 循环队列公式:(队尾 - 队头 + 最大容量) % 最大容量
        return (q->rear - q->front + MAX_SIZE) % MAX_SIZE;
    }

栈的C语言实现示例

#include <stdio.h>
#include <stdlib.h>

#define MAX_SIZE 100

typedef struct {
    int data[MAX_SIZE];
    int top;
} Stack;

void initStack(Stack *s) {
    s->top = -1;
}

int isEmpty(Stack *s) {
    return s->top == -1;
}

int isFull(Stack *s) {
    return s->top == MAX_SIZE - 1;
}

void push(Stack *s, int value) {
    if (isFull(s)) {
        printf("Stack overflow\n");
        return;
    }
    s->data[++s->top] = value;
}

int pop(Stack *s) {
    if (isEmpty(s)) {
        printf("Stack underflow\n");
        exit(1);
    }
    return s->data[s->top--];
}

int peek(Stack *s) {
    if (isEmpty(s)) {
        printf("Stack is empty\n");
        exit(1);
    }
    return s->data[s->top];
}

队列的C语言实现示例

#include <stdio.h>
#include <stdlib.h>

#define MAX_SIZE 100

typedef struct {
    int data[MAX_SIZE];
    int front;
    int rear;
} Queue;

void initQueue(Queue *q) {
    q->front = 0;
    q->rear = -1;
}

int isEmpty(Queue *q) {
    return q->rear < q->front;
}

int isFull(Queue *q) {
    return q->rear == MAX_SIZE - 1;
}

void enqueue(Queue *q, int value) {
    if (isFull(q)) {
        printf("Queue overflow\n");
        return;
    }
    q->data[++q->rear] = value;
}

int dequeue(Queue *q) {
    if (isEmpty(q)) {
        printf("Queue underflow\n");
        exit(1);
    }
    return q->data[q->front++];
}

int front(Queue *q) {
    if (isEmpty(q)) {
        printf("Queue is empty\n");
        exit(1);
    }
    return q->data[q->front];
}

注意事项

  • 栈和队列的实现:可以使用数组或链表实现,数组实现简单但大小固定,链表实现灵活但需要更多内存管理。
  • 边界条件:操作时需检查栈或队列是否为空或已满,避免溢出或下溢。
  • 动态扩展:链表实现可以动态扩展,数组实现通常需要预先分配固定大小。
  • 栈的特点:一端操作、后进先出、高效灵活、线性结构
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值