数据结构之队列

一、队列的定义和基本操作

1、队列的定义

队列(queue)又名队,它是一种运算受限的线性表。
限定仅允许在一端进行插入,这一端被称为队头(front);在另一端进行删除操作的线性表,这一端被称为队尾(rear)
向队列中插入新元素又称作入队(EnQueue),它是把新元素放到队尾元素的上面,使之成为新的队尾元素;
从队列中删除元素称作出队(DeQueue),它是把队头元素删除掉,使其相邻的元素成为新的队头元素。
栈的操作特性为先进先出FIFO(First In First Out)

2、队列的基本操作

InitQueue(&Q):初始化一个空队列;
QueueEmpty(Q):判断一个队列是否为空,若队列Q为空则返回true,否则返回false;
EnQueue(&Q, x):入队,若队列Q未满,则将x加入使之成为新队尾;
DeQueue(&Q,&x):出队,若队列Q非空,则删除队头元素,并用x返回;
GetHead(Q,&x):读队头元素,若队列Q非空,则用x返回队头元素;

二、队列的存储方式及其实现

队列的存储方式主要有两种:

2.1顺序队列

即队列的顺序存储结构。利用一组地址连续的存储单元依次存放队列中的元素,并附设两个指针:队头指针front指向队头元素,队尾指针rear指向队尾元素的下一个位置。示意图如下:
在这里插入图片描述
元素入队时,rear向后移动;元素出队时,front向后移动;最终两个指针会达到数组末端处,此时会造成队列的“假溢出”。为了解决这一问题,使用循环队列代替顺序队列。

循环队列就是将顺序队列从逻辑上视为一个环,当队首指针Q.front=MaxSize-1后,再前进一个位置就自动到0。示意图如下:
在这里插入图片描述
队列的顺序存储结构可如下定义:

#define MaxSize 50    //定义队列中元素的最大个数
typedef struct{
	Elemtype data[MaxSize];   //存放队列中元素
	int front,rear;           //队头指针、队尾指针
}SqQueue;

顺序栈的基本操作实现如下:

// 初始化队列
void InitQueue(SqQueue *q) {
    q->front = q->rear = 0;
}

// 判断队列是否为空
int QueueEmpty(SqQueue q) {
    return q.front == q.rear;
}

// 入队
int EnQueue(SqQueue *q, int x) {
    // 判断队列是否已满
    if ((q->rear + 1) % MAXSIZE == q->front) {
        return 0;
    }
    q->data[q->rear] = x;
    q->rear = (q->rear + 1) % MAXSIZE;    
    return 1;
}
// 出队
int DeQueue(SqQueue *q, int *x) {
    // 判断队列是否为空    
    if (q->front == q->rear) {        
    	return 0;    
    }    
    *x = q->data[q->front];    
    q->front = (q->front + 1) % MAXSIZE;    
    return 1;
}

2.2 链队列

即队列的链式存储结构。是一个同时带有队头指针和队尾指针的单链表,头指针指向队头结点,尾指针指向队尾结点。用单链表表示的链队列适合于数据元素变动比较大的情况,而且不存在队列满且产生溢出的问题。示意图如下:
在这里插入图片描述

队列的链式存储结构可如下定义:

// 链队列结构体定义
typedef struct QueueNode {
    int data;
    struct QueueNode* next;
} QueueNode;
typedef struct {
    QueueNode* front; // 队头指针    
    QueueNode* rear; // 队尾指针
} LinkQueue;

链队列的基本操作实现如下:

// 初始化链队列
void InitQueue(LinkQueue* Q) {
    Q->front = Q->rear = (QueueNode*)malloc(sizeof(QueueNode));    
    Q->front->next = NULL;
}
// 入队操作
void EnQueue(LinkQueue* Q, int x) {
    QueueNode* s = (QueueNode*)malloc(sizeof(QueueNode));    
    s->data = x;    
    s->next = NULL;    
    Q->rear->next = s;    
    Q->rear = s;
}
// 出队操作
int DeQueue(LinkQueue* Q) {
    if (Q->front == Q->rear) {
            printf("队列为空!\n");        
            exit(-1);    
    }    
    QueueNode* p = Q->front->next;    
    int x = p->data;    
    Q->front->next = p->next;    
    if (Q->rear == p) 
        Q->rear = Q->front;    
    free(p);    
    return x;
}
// 判断队列是否为空
int IsEmpty(LinkQueue* Q) {
    if (Q->front == Q->rear)
        return 1;    
    else 
        return 0;
}

总结

本文仅仅简单介绍了队列的定义与基本实现,仅供参考。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

BohumLee

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

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

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

打赏作者

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

抵扣说明:

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

余额充值