队列的相关知识

本文详细介绍了队列的基本概念,包括队的结构、顺序队列(数组和循环队列)的实现方法,以及链式队列的声明、初始化和基本操作,如入队、出队、队首元素获取等。
摘要由CSDN通过智能技术生成

队列的相关知识

一.队的结构

队(queue)作为一种特殊的线性表,与现实中的排队相类似,作为受限的线性表,它只被允许在一端进行插入,另一端进行删除。

被允许插入的叫做队尾(front),允许删除的另一端就叫做队头(rear)。

从队列的尾部插入新的元素被称作入队,相反从队头删除相应元素就称为出队。


二.队列的存储结构

与栈相同,队的存储结构也分为两种结构:

顺序存储(数组)以及链式存储结构(链表),以上两者均可完成队列的实现

1.顺序队列

(1)定义:

用一段地址连续的存储单元(数组),来依次存放队头到队尾的元素,叫做顺序队列

我们在使用顺序结构来实现队列时,除了数组之外,我们需要用结构体封装两个指针:队头指针(front)队尾指针(rear),使其分别指向队头与队尾

队尾与队头指针的用法如下所示:

image-20231126211352700

(2)假溢出

通过以上例子,当元素F将继续插入队列之中就会发生假溢出的情况发生,因为rear=5 > 4,结尾已经达到了队列的最大长度了,但实际上队列中的空间并未被数据完全占据,因此此现象被称为假溢出

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


2.循环队列

(1)定义:

为了避免假溢出的发生,使得队列的空间能够得到充分的利用,于是我们将顺序队列的队首与队尾相连,将数组看作一个首位相连的循环结构

队头和队尾相互连接的顺序队列我们称之为循环队列。

那么问题随之而来,当循环队列为为空或者未满时,我们应该如何进行判断呢?

以下提供两个相关方案:

方案一:在循环中增加一个计算器count,当count = MAXSIZE时我们就可以判断,循环队列此时为满。

那么队满的条件就可以如此表示:(rear+1)%MAX==front

方案二:我们可以在队列的结构体中,增添一个指向该队列中的队尾下个数据的指针,当指针指向队头元素所在位置时,则判断队满。

那么队满的条件就为:rear==front

(2)基本操作

队的结构

typedef struct
{
    int data[MAX];
    int front;    //头指针
    int rear;    //尾指针
}Queue;

队的初始化

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

判空操作

bool Queuefull(Queue* q){
    return (q->rear+1)%MAX==q->front;
}

入队操作

void enterQueue(Queue *q,int data){
    if(Queuefull){
        printf("队列已满");
        return ;
    }
    q->data[q->rear]==data;
    q->rear=(q->rear+1)%MAX;
    return 1;
}

出队操作

int pop(Queue *q){
    if(Queuefull(q)){
        return -1;
    }
    int temp=q->data[q->front];
    q->front = (q->front + 1) % MAX;
    return temp;
}

求队首元素


3.链式队列

顾名思义,采取链式存储的队列就被称之为链式队列,根据队列的结构,我们需要两个指针frontrear

分别指向队头和队尾。

  1. 链表的声明

    #include <stdio.h>
    #include <stdlib.h>
    //声明一个结构体来表示节点
    typedef struct Node
    {
         int data;   
         struct Node * next; 
    }Node;
    //声明一个结构体来定义上面这个结构体的两个指针
    typedef struct
    {
        Node *front,*rear;//分别指向队首和队尾的指针
    }Queue;
    
    
  2. 链表的初始化

    void initializeQueue(Queue* q) {
        q->front = q->rear = NULL;
    }
    
  3. 队列的遍历

    void printQueue(Queue* q) {
        if (isEmpty(q)) {
            printf("队列为空\n");
        } else {
            Node* current = q->front;
            while (current != NULL) {
                printf("%d ", current->data);
                current = current->next;
            }
            printf("\n");
        }
    }
    
    
  4. 入队操作

    void enqueue(Queue* q, int data) {
        Node* newNode = (Node*)malloc(sizeof(Node));
        newNode->data = data;
        newNode->next = NULL;
        if (q->rear == NULL) { // 队列为空
            q->front = q->rear = newNode;
        } else {
            q->rear->next = newNode;
            q->rear = newNode;
        }
    }
    
  5. 查看队首元素

    int peek(Queue* q) {
        if (q->front == NULL) { // 队列为空
            printf("队列为空\n");
            return -1; // 返回一个特殊值表示队列为空
        } else {
            return q->front->data;
        }
    }
    
  6. 队列的判空

    int Empty(Queue* Q){
        //队空的条件是头指针和尾指针指向相同的地方
        if(Q.front==Q.rear)
        {
            return 1;
        }
        return 0;
    
    
  7. 出队操作

    int dequeue(Queue* Q) {
        if (Empty(Q)) { 
            printf("队列为空\n");
            return -1; 
        } else {
            int data = q->front->data;
            Node* temp = q->front;
            q->front = q->front->next;
            if (q->front == NULL) { 
                q->rear = NULL;// 如果队列中只有一个节点,则出队后将rear置为NULL
            }
            free(temp);
            return value;
        }
    }
    

    主函数内容如下

    int main() {
        Queue q;
        initializeQueue(&q);
    
        enqueue(&q, 10);
        enqueue(&q, 20);
        enqueue(&q, 30);
    
        printf("队列元素: ");
        printQueue(&q);
    
        printf("队首元素: %d\n", peek(&q));
    
        printf("出队元素: %d\n", dequeue(&q));
    	enqueue(&q, 10);
        printf("打印队列: ");
        printQueue(&q);
    
        return 0;
    }
    
    printf("队列元素: ");
    printQueue(&q);
    
    printf("队首元素: %d\n", peek(&q));
    
    printf("出队元素: %d\n", dequeue(&q));
    

    enqueue(&q, 10);
    printf("打印队列: ");
    printQueue(&q);

    return 0;
    

    }

    
    
    
    
    
    
  • 10
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值