数据结构(循环队列)

数据结构(队列)

队列是一种仅限在数据末尾进行增加数据和数据起始减少数据的数据结构,其特点为先进先出(FIFO)。

其基本操作与栈的操作类似,不同的删除数据在队头进行。

队列的存储分为两种,顺序表示与链式表示。

与顺序栈相似,我们需要一个连续的存储单元,依次存放数据,尚需尚需附设两个整型变量 front 和 rear分别指示队列头元素及队列尾元素的位置(即称头指针,尾指针)。

这里将数据简单化处理为int类型,则有:

#define MAXSIZE 1000

tyepdef struct queue{

  int data[MAXSIZE];//数据空间

  int front;//队头索引

  int rear;//队尾索引

}queue;

类似与数组,为实现增加与减少操作,在初始化时,令front = rear = 0;每当插入新的数据时,rear+1,每当删队头元素时,front+1。因此,在非空队列中,front始终指向队头元素,rear始终指向队尾元素的下一位置。

此时,不断的增加和减少元素,导致front,rear不断增加,会出现两指针不断接近连续空间的末尾,最后可能出现数据的溢出,而此时连续空间的起始部分可能并未占满,所以称这种现象为“假溢出”

为解决这一问题,使用循环队列,即当数据指针到达空间末端后,对其求模,使其回到初始位置,充分利用空间。

//初始化队列
#define MAXSIZE 1000

queue* initQueue(){

  queue* q = (queue*)malloc(sizeof(queue));

  q->front = q->rear = 0;//将索引初始化

  return q;

}
//获得队列长度

int Queue_Length(queue* obj,int val){

  return (obj->rear - obj->front + MAXSIZE)%MAXSIZE;
  /*防止出现队尾索引小于队头索引情况,对其加最大容量后,对其求模*/
//增加队尾元素

void QueuePush(queue* obj){

  if((obj->rear + 1)%MAXSIZE != obj->front){//加1即为下一元素,还需注意是否越界访问,队列是否满的问题
​    obj->data[obj->rear] = val;

​    obj->rear = (obj->rear + 1)/MAXSIZE;

  }

}
//删除队头元素

void Queue_Pop(queue* obj){

  if(((obj->rear +1)%MAXSIZE != obj->front)){

​    obj->front = (obj->front+1)%MAXSIZE;//加1指向下一元素即可。

  }

}
//获取队头元素

 int Queue_getFront(queue* obj){

  if(obj->front != obj->rear){//需判断是否为空的问题return obj->data[obj->front];

  }
  return -1;//为空则返回-1

}

链式存储结构

typedef struct QNode{

  int data;//数据域

  struct QNode* next;//指针域

}QNode;

//类似的,需要头,尾指针。

typedef struct{

  struct QNode* front;//需要头,尾指针对元素进行操作

  struct QNode* rear;

}Q;
//初始化队列

QNode* initQueue(){

 Q.front = Q.rear = (QNode*)malloc(sizeof(QNode));

  Q.front->data = 0;

  Q.front->next = NULL;//置空,避免野指针

}
//入队

void push(QNode* obj, int val){

  QNode* temp = (QNode*)malloc(sizeof(QNode));

  temp->data = val;

  temp->next = NULL;

  Q.rear->next =temp;//注意从队尾加入数据

  Q.rear = temp;//链接上新节点

}
//出队

int pop(QNode* obj,int val){
int flag = 0;
  if(Q.front != Q.rear){

​    QNode* temp = Q.front->next;

​    val = temp->data;//取出并删除队头元素
    flag = 1;//记录下队列不为空
​    Q.front->next = temp->next;if(temp == Q.rear){

​      Q.rear = Q.front;}free(temp);//注意释放内存

  }
  if(flag){//队列不为空,则返回删除的数据,否则返回-1
  return val;
  }
  else{
  return -1;

}
//获取队首的值

int  Get_Queuefront(QNode* obj){

  if(Q.front != Q.rear){return Q.front->next->data;//注意头节点的数据域无效

  }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值