数据结构-队列ADT

队列是一端插入一端删除的数据结构,不同于栈在一端同时删除和插入

 

初始化后的队列ADT

但是我们可以看到此时会有一种问题就是假溢出

也就是我们入队5个元素后 将123位置的元素出列但是会发现 再次入队的话队列已经无法入队 因此我们需要引入一个循环队列的ADT

这样我们就可以只用将队列从0直接入队

但是怎样将rear游标移动到0这个位置呢?

其实只需要套用下面的公式就可以将front rear在这个环中每次逆时针向后移动一位

front=(front+1)%maxsize

rear=(rear+1)%maxsize

也就是等于他和maxsize的差距 差几个位置到一圈 加一是因为产生了一个差值

队列的顺代码实现(数组):

typedef struct
{
	int front;//头元素前一个元素的下标位置
	int rear; //队尾元素的下标
	int maxSize;//队列的最大长度
	ElemType *element;//指向一维数组
}Queue;

//创建一个能容纳maxsize个元素的空队列
void Creat(Queue *Q,int mSize)
{
	Q->maxSize = mSize;
	Q->element = (ElemType)malloc(sizeof(ElemType)*maxSize);
	Q->front = Q->rear = 0;
}

//销毁一个存在的队列并释放内存
void Destroy(Queue *Q)
{
	Q->maxSize == -1;
	free(Q->element);
	Q->front = Q->rear = -1;
}

//判断队列是否为空
BOOL IsEmpty(Queue *Q)
{
	return Q->front = Q->rear;
}

//判断队列是否已满
BOOL IsFull(Queue *Q)
{
	return (Q->rear+1)%Q->maxSize==Q->front;//在循环队列中如果rear向后移动一个和front重合
}

//获取队列头元素
BOOL Front(Queue *Q, ElemType* x)
{
	if(IsEmpty(Q))
		return FALSE;
	x=Q->element[( Q->front+1 )% Q->maxSize];
	return TRUE;
}

//在队列的队尾插入元素x
BOOL EnQueue(Queue *Q,ElemType * x)
{
	if(IsFull(Q))
		return FALSE;
	Q->rear=(Q->rear+1)%Q->maxSize;
	Q->element[Q->rear]=x;
	return TRUE;
}

//删除队列的头元素
BOOL DeQueue(Queue * Q)
{
	if(IsEmpty(Q))
		return FALSE;
	Q->front=(Q->front+1)%Q->maxSize;//巧妙的利用取余将循环队列的下标后移一个从而无视头元素
	return TRUE;
}

//清楚队列的所有元素,不释放内存
void Clear(Queue *Q)
{
	Q->front = Q->rear = 0;
}

如果使用顺序表的话(数组) 需要留出一个位置作为标志判断队列是否满 

 

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

#define STATE_OK 1
#define STATE_FALSE 0

#define MAX_SIZE 6

typedef int State;

/*循环队列结构*/
typedef struct {
    int data[MAX_SIZE];    //这里的数据暂且作为int 可以改为class 或者 结构体
	int front;    //头
	int rear;    //尾
    int length;
}SeqQueue;

void InitSeqQueue(SeqQueue * seq_queue)
{
	if(seq_queue == NULL){
		seq_queue = (SeqQueue *)malloc(sizeof(SeqQueue));
	}
	seq_queue->front = 0;
	seq_queue->rear = 0;
	seq_queue->length = 0;
}

State IsSeqQueueEmpty(SeqQueue * seq_queue)
{
    if(seq_queue->rear == seq_queue->front)
		return STATE_OK;
    return STATE_FALSE;
}

State IsSeqQueueFull(SeqQueue * seq_queue)
{
    if(seq_queue->rear + 1 % MAX_SIZE == seq_queue->front) //相差一位
	{
		return STATE_OK;
	}
	return STATE_FALSE;
}

State offer(SeqQueue * seq_queue,int element)
{
    if(IsSeqQueueFull(seq_queue))
	{
		return STATE_FALSE;
	}
	seq_queue->data[seq_queue->rear] = element;
	seq_queue->rear = (seq_queue->rear + 1) % MAX_SIZE; // 后移一位 但是要形成环状
	seq_queue->length++;
	return STATE_OK;
}

//尾进头出 *element记录出队数据
State poll(SeqQueue * seq_queue,int * element)
{
	if(IsSeqQueueEmpty(seq_queue))
		return STATE_FALSE;
	*element = seq_queue->data[seq_queue->front];
	seq_queue->front = (seq_queue->front + 1) % MAX_SIZE;
	seq_queue->length--;
	return STATE_OK;

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值