C语言队列

队列(Queue)是一种先进先出(FIFO,First-In-First-Out)的线性数据结构。它类似于现实生活中的排队,新元素被添加到队尾,而从队首移除元素。

1. 队列的基本操作:

  • Enqueue (入队): 将一个元素添加到队列的尾部。
  • Dequeue (出队): 从队列的头部移除一个元素,并返回该元素的值。
  • Front (队首): 返回队首元素的值,但不移除它。
  • Rear (队尾): 返回队尾元素的值,但不移除它。
  • IsEmpty (判空): 检查队列是否为空。
  • IsFull (判满): 检查队列是否已满(对于固定大小的队列)。
  • Size (大小): 返回队列中元素的数量。

2. 队列的实现方式:

C语言中,队列通常可以通过两种方式实现:

  • 数组实现 (顺序队列): 使用数组来存储队列元素,需要维护队首和队尾指针。
  • 链表实现 (链式队列): 使用链表来存储队列元素,每个节点包含数据和指向下一个节点的指针。

3. 数组实现 (顺序队列):

3.1 结构体定义:

#define MAX_SIZE 100 // 定义队列的最大容量

typedef struct {
    int data[MAX_SIZE]; // 存储队列元素的数组
    int front;          // 队首指针,指向队首元素
    int rear;           // 队尾指针,指向队尾元素的下一个位置
} Queue;

3.2 初始化队列:

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

3.3 判空:

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

3.4 判满:

int isFull(Queue *q) {
    return (q->rear + 1) % MAX_SIZE == q->front; // 循环队列的判满条件
}

3.5 入队:

int enqueue(Queue *q, int value) {
    if (isFull(q)) {
        printf("Queue is full!\n");
        return 0; // 入队失败
    }
    q->data[q->rear] = value;
    q->rear = (q->rear + 1) % MAX_SIZE; // 循环队列的队尾指针更新
    return 1; // 入队成功
}

3.6 出队:

int dequeue(Queue *q, int *value) {
    if (isEmpty(q)) {
        printf("Queue is empty!\n");
        return 0; // 出队失败
    }
    *value = q->data[q->front];
    q->front = (q->front + 1) % MAX_SIZE; // 循环队列的队首指针更新
    return 1; // 出队成功
}

3.7 获取队首元素:

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

3.8 获取队尾元素:

int rear(Queue *q, int *value) {
    if (isEmpty(q)) {
        printf("Queue is empty!\n");
        return 0;
    }
    *value = q->data[(q->rear - 1 + MAX_SIZE) % MAX_SIZE]; // 注意循环队列的队尾元素位置
    return 1;
}

3.9 循环队列:

为了避免“假溢出”现象(即队列还有空间,但 rear 指针已经到达数组末尾),通常使用循环队列。循环队列通过取模运算 (%) 来实现队首和队尾指针的循环移动。

4. 链表实现 (链式队列):

4.1 结构体定义:

typedef struct Node {
    int data;
    struct Node *next;
} Node;

typedef struct {
    Node *front;
    Node *rear;
} Queue;

4.2 初始化队列:

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

4.3 判空:

int isEmpty(Queue *q) {
    return q->front == NULL;
}

4.4 入队:

int enqueue(Queue *q, int value) {
    Node *newNode = (Node *)malloc(sizeof(Node));
    if (newNode == NULL) {
        printf("Memory allocation failed!\n");
        return 0; // 入队失败
    }
    newNode->data = value;
    newNode->next = NULL;

    if (isEmpty(q)) {
        q->front = newNode;
        q->rear = newNode;
    } else {
        q->rear->next = newNode;
        q->rear = newNode;
    }
    return 1; // 入队成功
}

4.5 出队:

int dequeue(Queue *q, int *value) {
    if (isEmpty(q)) {
        printf("Queue is empty!\n");
        return 0; // 出队失败
    }
    Node *temp = q->front;
    *value = temp->data;
    q->front = q->front->next;

    if (q->front == NULL) {
        q->rear = NULL; // 如果队列为空,则 rear 也需要置为 NULL
    }

    free(temp);
    return 1; // 出队成功
}

4.6 获取队首元素:

int front(Queue *q, int *value) {
    if (isEmpty(q)) {
        printf("Queue is empty!\n");
        return 0;
    }
    *value = q->front->data;
    return 1;
}

4.7 获取队尾元素:

int rear(Queue *q, int *value) {
    if (isEmpty(q)) {
        printf("Queue is empty!\n");
        return 0;
    }
    *value = q->rear->data;
    return 1;
}

5. 完整示例 (链表实现):

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

// ... (链表实现的结构体定义和函数) ...

int main() {
    Queue q;
    initQueue(&q);

    enqueue(&q, 10);
    enqueue(&q, 20);
    enqueue(&q, 30);

    int value;
    if (front(&q, &value)) {
        printf("Front element: %d\n", value);
    }
    if (rear(&q, &value)) {
        printf("Rear element: %d\n", value);
    }

    while (!isEmpty(&q)) {
        if (dequeue(&q, &value)) {
            printf("Dequeued element: %d\n", value);
        }
    }

    return 0;
}

6. 数组实现 vs 链表实现:

特性数组实现 (顺序队列)链表实现 (链式队列)
内存分配静态分配动态分配
空间利用率可能浪费空间更有效利用空间
插入/删除可能需要移动元素效率更高
大小限制固定大小大小可变
实现复杂度相对简单相对复杂

总结:

  • 数组实现: 简单,但受限于预定义的大小,可能导致空间浪费或溢出。
  • 链表实现: 灵活,可以动态调整大小,空间利用率高,插入和删除操作效率更高,但实现相对复杂,需要处理指针。

选择哪种实现方式取决于具体应用场景的需求。如果队列大小已知且固定,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值