数据结构——队列

1.队列的基本概念

定义:队列也是一种操作受限的线性表,只允许在表的一端进行插入,另一端进行删除。

概念:向队列中插入元素称为入队,删除元素成为出队。

操作特性为:先进先出

2.队列的基本操作

1.存储类型

typedef struct queue{
	int front;
	int rear;
	Datetype *base;
}Queue;

2.加溢出

在图a中,此时为队列的初始状态,有Q.frontQ.rear0成立,该条件可以作为判断对空的条件。但却不能用Q.rear==MaxSize,在图d中,队列中仅有一个元素,仍满足该条件。这时入队出现假溢出。但这种溢出不是真正的溢出,在数组中仍存在可以存放数据元素的空位置,所以是一种假溢出。
在这里插入图片描述

解决假溢出的方法:

1.按最大可能的进队列操作次数,设置顺序队列的最大元素个数,这种方法很浪费空间,而且有时会因为估计不准而出错;

2.修改出队列算法,设每次出队列后,都把队列中剩余数据元素向队头方向移用一个位置,时间复杂度为O(n),浪费了时间。

3.修改入队列算法,当为真溢出时,返回false;当为假溢出时,则把队列中的数据元素向队头方向移动front+1个位置,使队头元素位于队列的最前端后再完成新数据元素的入队操作;当为其它情况时,进队列操作算法同前。此算法的时间复杂度也为O(n)。

3.循环队列

为了解决假溢出的问题,引入了循环队列。将顺序队列臆想为一个环状的空间,即把存储队列元素的表从逻辑上视为一个环,称为循环队列。当队首指针Q.front==MaxSize-1后,就在进一个位置,自动到0。

那么如何确定不同的队空、队满的判定条件?

方法一:附设一个存储队列中元素个数的变量num,当 num=0时队空,当num=QueueSize时为队满;

方法二:修改队满条件,浪费一个元素空间,队满时数组 中只有一个空闲单元;

方法三:设置标志flag,当 front-rear且flag=0时为队空,当 frontrear且flag=1时为队满。

4.循环队列的基本操作(完整代码(github))

1.初始化

//初始化队列
Status InitQueue(Queue * queue)
{
	queue->base=(Datetype *)malloc(sizeof(Datetype)*MaxSize);
	if(!queue->base) exit(-1);
	queue->front=queue->rear=0;
	return 1;
}

2.判断对空

//判断队列是否为满
Status isFull(Queue *q)
{
	if((q->rear+1)%MaxSize==q->front) return 1;
	else  return 0;
}

3.判断队满

//判断队列是为空
Status isEmpty(Queue *q)
{
	if(q->front==q->rear) return 1;
	else return 0;
}

4.入队

//入队
Status Enqueue(Queue *q,Datetype e)
{
	if(isFull(q)) return 0;//如果队列为满,返回false
	q->base[q->rear]=e;
	q->rear=(q->rear+1)%MaxSize;
	return 1;
}

5.出队

//出队
Status Dequeue(Queue *q)
{
	if(isEmpty(q)) return 0;
	q->front=(q->front+1)%MaxSize;
	return 1;
}

3.链式队列(完整代码(github))

1.存储类型

// 队列的节点 
struct Node
{
        int data;
        struct Node* next;
};
// 队首队尾指针 
struct Queue
{
        struct Node* front;
        struct Node* rear;
        int size;
};

出对时,首先判断队是否为空若不为空,则将其从链表中摘除,并让Q.front指向下一个结点,入队时,建立一个新的结点,将新节点插入到链表的尾部去,并让Q.rear指向这个新插入的结点。

基本操作:

1.初始化

// 队列的节点 
struct Node
{
        int data;
        struct Node* next;
};
// 队首队尾指针 
struct Queue
{
        struct Node* front;
        struct Node* rear;
        int size;
};

2.判断对空

bool QueueEmpty(struct Queue* queue)
{
       if(Q.front==Q.rear) return ture;
       else return false;
}

3.入队

 //入队
void QueuePush(struct Queue* queue, const int data)
{
        struct Node* node;
        node = (struct Node*)malloc(sizeof(struct Node));
        assert(node != NULL);
        
        node->data = data;
        node->next = NULL;
        
        if(QueueEmpty(queue))
        {
            queue->front = node;
            queue->rear = node;
        }
        else
        {            
            queue->rear->next = node;
            queue->rear = node;
        }
        ++queue->size;
}

4.出队

 //入队
void QueuePush(struct Queue* queue, const int data)
{
        struct Node* node;
        node = (struct Node*)malloc(sizeof(struct Node));
        assert(node != NULL);
        
        node->data = data;
        node->next = NULL;
        
        if(QueueEmpty(queue))
        {
            queue->front = node;
            queue->rear = node;
        }
        else
        {            
            queue->rear->next = node;
            queue->rear = node;
        }
        ++queue->size;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值