线性表之队列

主要内容

  1. 队列

一.队列

队列是一种先进先出(FIFO,First In First Out)的线性数据结构,它具有两个基本操作:入队(enqueue)和出(dequeue)。入队操作在队列的末尾添加一个元素,出队操作从队列的头部移除一个元素。

1.队列的顺序存储

代码如下(示例):

队列的顺序存储结构通常使用数组来实现,可以通过数组的下标来表示队列的头部和尾部,以及元素的添加和移除。下面是队列的顺序存储结构的示例代码:

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 *queue) {
    queue->front = 0;
    queue->rear = 0;
}

// 判断队列是否为空
int isEmpty(Queue *queue) {
    return queue->front == queue->rear;
}

// 入队
void enqueue(Queue *queue, int value) {
    if ((queue->rear + 1) % MAX_SIZE == queue->front) {
        printf("Queue is full\n");
        return;
    }
    queue->data[queue->rear] = value;
    queue->rear = (queue->rear + 1) % MAX_SIZE;
}

// 出队
int dequeue(Queue *queue) {
    if (isEmpty(queue)) {
        printf("Queue is empty\n");
        return -1;
    }
    int value = queue->data[queue->front];
    queue->front = (queue->front + 1) % MAX_SIZE;
    return value;
}

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

    enqueue(&queue, 1);
    enqueue(&queue, 2);
    enqueue(&queue, 3);

    printf("Dequeued: %d\n", dequeue(&queue));
    printf("Dequeued: %d\n", dequeue(&queue));
    printf("Dequeued: %d\n", dequeue(&queue));

    return 0;
}
在这个示例中,我们使用了一个数组来存储队列的元素,
同时使用front和rear指针来表示队列的头部和尾部。
enqueue函数用于将元素添加到队列中,dequeue函数用于从队列中移除元素。
通过这种方式,我们可以使用数组来实现队列的顺序存储结构。

Python实现:

class ArrayQueue:
    def __init__(self, capacity):
        self.capacity = capacity
        self.queue = [None] * capacity
        self.front = 0
        self.rear = 0

    def enqueue(self, item):
        if (self.rear + 1) % self.capacity == self.front:
            raise Exception("Queue is full")
        self.queue[self.rear] = item
        self.rear = (self.rear + 1) % self.capacity

    def dequeue(self):
        if self.front == self.rear:
            raise Exception("Queue is empty")
        item = self.queue[self.front]
        self.front = (self.front + 1) % self.capacity
        return item

2.队列的链式存储

队列的链式存储结构通常使用链表来实现,每个节点表示队列中的一个元素,通过指针来连接各个节点。下面是队列的链式存储结构的示例代码:

C语言实现:

typedef struct QueueNode {
    int data;               // 队列中的元素
    struct QueueNode *next; // 指向下一个节点的指针
} QueueNode;

typedef struct {
    QueueNode *front;       // 指向队头节点的指针
    QueueNode *rear;        // 指向队尾节点的指针
} Queue;

其中,QueueNode 表示队列中的一个节点,包含一个 data 成员表示节点中存储的元素,以及一个 next成员表示指向下一个节点的指针。

Queue 表示队列本身,包含两个指针成员 frontrear,分别指向队头和队尾节点。

创建一个空队列可以用如下的代码:

Queue *createQueue() {
    Queue *q = (Queue *)malloc(sizeof(Queue));
    q->front = q->rear = NULL;
    return q;
}

入队操作可以用如下的代码实现:

void enqueue(Queue *q, int data) {
    QueueNode *newNode = (QueueNode *)malloc(sizeof(QueueNode));
    newNode->data = data;
    newNode->next = NULL;

    if (q->rear == NULL) {
        q->front = q->rear = newNode;
    } else {
        q->rear->next = newNode;
        q->rear = newNode;
    }
}

出队操作可以用如下的代码实现:

int dequeue(Queue *q) {
    if (q->front == NULL) {
        printf("Queue is empty.\n");
        return -1;
    }

    int data = q->front->data;
    QueueNode *temp = q->front;
    q->front = q->front->next;
    free(temp);

    if (q->front == NULL) {
        q->rear = NULL;
    }

    return data;
}
需要注意的是,当队列为空时进行出队操作会导致错误,
因此在出队操作前需要先检查队列是否为空。

Python实现:

class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

class LinkedQueue:
    def __init__(self):
        self.front = None
        self.rear = None

    def enqueue(self, item):
        new_node = Node(item)
        if self.rear is None:
            self.front = new_node
            self.rear = new_node
        else:
            self.rear.next = new_node
            self.rear = new_node

    def dequeue(self):
        if self.front is None:
            raise Exception("Queue is empty")
        item = self.front.data
        self.front = self.front.next
        if self.front is None:
            self.rear = None
        return item

3.双端队列

双端队列(deque)是一种具有队列和栈特性的数据结构,可以在队列的两端进行插入和删除操作。双端队列受限于元素的插入和删除操作只能在两端进行,不能在中间进行。

双端队列的相关示例包括:浏览器的前进和后退功能、打印机的打印任务队列等。

C语言示例:

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

#define MAX_SIZE 100

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

void initDeque(Deque *deque) {
    deque->front = 0;
    deque->rear = -1;
}

bool isFull(Deque *deque) {
    return (deque->rear == MAX_SIZE - 1) || (deque->front == 0 && deque->rear == MAX_SIZE - 1);
}

bool isEmpty(Deque *deque) {
    return (deque->front > deque->rear);
}

void insertFront(Deque *deque, int value) {
    if (isFull(deque)) {
        printf("Deque is full\n");
        return;
    }
    deque->data[--deque->front] = value;
}

void insertRear(Deque *deque, int value) {
    if (isFull(deque)) {
        printf("Deque is full\n");
        return;
    }
    deque->data[++deque->rear] = value;
}

int deleteFront(Deque *deque) {
    if (isEmpty(deque)) {
        printf("Deque is empty\n");
        return -1;
    }
    return deque->data[deque->front++];
}

int deleteRear(Deque *deque) {
    if (isEmpty(deque)) {
        printf("Deque is empty\n");
        return -1;
    }
    return deque->data[deque->rear--];
}

int main() {
    Deque deque;
    initDeque(&deque);

    insertFront(&deque, 1);
    insertRear(&deque, 2);
    insertFront(&deque, 3);
    insertRear(&deque, 4);

    printf("Deleted from front: %d\n", deleteFront(&deque));
    printf("Deleted from rear: %d\n", deleteRear(&deque));

    return 0;
}

Python示例:

from collections import deque

deque = deque()

deque.appendleft(1)
deque.append(2)
deque.appendleft(3)
deque.append(4)

print("Deleted from front:", deque.popleft())
print("Deleted from rear:", deque.pop())

总结

以上是今天要讲的内容,学到了队列相关知识。

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

K要努力

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值