7.29 数据结构学习笔记-队列

本文介绍了如何使用数组和链表来实现队列数据结构。在数组实现中,讨论了循环队列的概念,强调了在队满和队空条件下的判断以及元素的添加和移除顺序。而在链表实现中,展示了如何通过单向链表创建和管理队列,包括节点的插入和删除操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数据结构–队列

一. 队列–用数组实现时出现的问题

_Bool offerQueue(ArrayQueue queue,int element)
{
    if(queue->front+1==queue->rear) return 0;
    queue->rear++;
    queue->array[queue->rear]=element;
    return 1;
}

错误1. if(queue->front+1==queue->rear) return 0;

在这里插入图片描述
如图,实际上这种实现方式就是数组,你末尾下标加1怎么能等于头呢
应该这样判断:
if((queue->rear + 1) % queue->capacity == queue->front)
下一行queue->rear后移同理:
queue->rear = (queue->rear + 1) % queue->capacity;

问题2. 先存/取值,再变下标!

初始状态(队空条件):Q->front == Q->rear == 0。
进队操作:队不满时,先送值到队尾元素,再将队尾指针加1。
出队操作:队不空时,先取队头元素值,再将队头指针加1。

队列到底是先取值再变下标还是都可以???

3. 较完整代码

//循环队列

#include <bits/stdc++.h>
using namespace std;

typedef int E;

struct Queue {
    E * array;
    int capacity;   //数组容量
    int rear, front;   //队尾、队首指针
};
typedef struct Queue * ArrayQueue;

bool initQueue(ArrayQueue queue){
    queue->array = (int*)malloc(sizeof(E) * 10);
    if(queue->array == NULL) return 0;
    queue->capacity = 10;
    queue->front = queue->rear = 0;   //默认情况下队首和队尾都指向0的位置
    return 1;
}
_Bool offerQueue(ArrayQueue queue,int element)
{
    if((queue->rear+1)%queue->capacity==queue->front) return 0;
    queue->array[queue->rear]=element;
    queue->rear = (queue->rear + 1) % queue->capacity;
    return 1;
}

void printQueue(ArrayQueue queue){
    printf("<<< ");
    int i = queue->front;   //遍历队列需要从队首开始
    do {
        printf("%d ", queue->array[i]);  //先打印当前位置上的元素
        i = (i + 1) % queue->capacity;   //然后 向后循环移动
    } while (i != queue->rear);   //当到达队尾时,结束
    printf("<<<\n");
}
int pollQueue(ArrayQueue queue)
{
    if(queue->rear==queue->front) 
    {
        cout<<"队列为空!";
        return 0;
    }
    int tmp=queue->array[queue->front];
    queue->front=(queue->front + 1) % queue->capacity;
    return tmp; 
}
int main(){
    struct Queue queue;
    initQueue(&queue);
    for (int i = 0; i < 5; ++i) {
        offerQueue(&queue, i * 100);
    }
    printQueue(&queue);
    pollQueue(&queue);
    printQueue(&queue);
}

二. 队列–用链表实现

//单向链表实现队列

#include <bits/stdc++.h>
using namespace std;

typedef int E;

struct LNode {
    E element;
    struct LNode * next;
};
typedef struct LNode * Node;

struct Queue{
    Node front, rear;
};
typedef struct Queue * LinkedQueue;   //因为要存储首位两个指针,所以这里封装一个新的结构体吧


_Bool initQueue(LinkedQueue queue){
    Node node = (Node)malloc(sizeof(struct LNode));
    if(node == NULL) return 0;
      node->next = NULL;
    queue->front = queue->rear = node;   //一开始两个指针都是指向头结点的,表示队列为空
    return 1;
}
_Bool offerQueue(LinkedQueue queue, E element){
    Node node = (Node)malloc(sizeof(struct LNode));
    if(node == NULL) return 0;
      node->next = NULL;
    node->element = element;
    queue->rear->next = node;   //先让尾结点的下一个指向新的结点
    queue->rear = node;   //然后让队尾指针指向新的尾结点
    return 1;
}

void printQueue(LinkedQueue queue){
    printf("<<< ");
    Node node = queue->front->next;
    while (1) {    //注意不能直接判空,因为前面我们没考虑,也就没将新结点next设定为NULL
        printf("%d ", node->element);
        if(node == queue->rear) break;    //当已经打印最后一个元素后,再结束
        else node = node->next;
    }
    printf("<<<\n");
}
E pollQueue(LinkedQueue queue){
    E e = queue->front->next->element;
    Node node = queue->front->next;
    queue->front->next = queue->front->next->next;  //直接让头结点指向下下个结点
    if(queue->rear == node) queue->rear = queue->front;   //如果队尾就是待出队的结点,那么队尾回到队首位置上
    free(node);   //释放内存
    return e;
}

int main(){
    struct Queue queue;
    initQueue(&queue);
    for (int i = 0; i < 5; ++i) {
        offerQueue(&queue, i*100);
    }
    printQueue(&queue);
    while (queue.front!=queue.rear){
        printf("%d ", pollQueue(&queue));
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值