【十二】队列及其顺序存储结构

1、队列的定义

  • 队列是一种特殊的线性表
  • 队列仅在线性表的两端进行操作
  • 队头( Front):取出数据元素的一端
  • 队尾( Rear):插入数据元素的一端
  • 队列不允许在中间部位进行操作!

2、队列的性质
性质:先进先出(FIFO)

这里写图片描述

3、队列的顺序存储实现

示意图:
这里写图片描述

4、代码复用

利用顺序链表,实现顺序存储的队列!

/*
  在队尾添加一个元素
  如果成功,返回1,失败返回0
*/
int SeqQueue_Append(SeqQueue *queue, SeqQueueNode *item)  //O(1)
{
  //将线性表的尾部定义为队列的尾部
  return List_Insert(queue,item,List_Length(queue));
}

/*
  在队头移出一个元素
  如果成功,返回被移出的元素指针,否则,返回NULL
*/
SeqQueueNode *SeqQueue_Retrieve(SeqQueue *queue) //O(n)
{
  return List_Delete(queue,0);
}

经过时间复杂度的分析,常用操作SeqQueue_Append();的时间复杂度为O(1),但是SeqQueue_Retrieve();操作的时间复杂度却是O(n),所以有了以下改进的算法!

5、顺序队列的优化方案

SeqQueue_Retrieve();操作,因为删除的是顺序链表的第1个元素,所以每次都需要把后面的元素依次向前移动一位,这就增加了时间复杂度!

  • 定义front使其始终代表队头的下标
    • 出队时将队头元素返回,且front++
  • 定义rear使其始终代表队尾下一个元素的下标
    • 入队时将新元素插入,且rear++
  • 没有必要只将下标为0的位置定义为队头!!!

这里写图片描述

6、改进的算法

数据结构的定义:

/*
    为了保持对外的接口一致
*/
typedef void SeqQueue;
typedef void SeqQueueNode;
/*
    内部实现的具体定义
*/
#ifdef WIN32
  typedef unsigned int TSeqQueueNode;
#else
  typedef unsigned long TSeqQueueNode;
#endif

//增加了front和rear成员,用于标记队头和队尾
typedef struct _struct_SeqQueue
{
  int capacity;
  int length;
  int front;
  int rear;
  TSeqQueueNode *node;
}TSeqQueue;

这里写图片描述

部分代码:

/*
  在队尾添加一个元素
  如果成功,返回1,失败返回0
*/
int SeqQueue_Append(SeqQueue *queue, SeqQueueNode *item) //O(1)
{
  int iret = 1;
  TSeqQueue *tqueue = (TSeqQueue*)queue;
  iret = iret && (tqueue != NULL) && (item != NULL);
  if(iret)
  {
    //判断是否有位置可以插入
    iret = tqueue->length < tqueue->capacity;
    if(iret)
    {
    //在当前队尾的位置插入数据,注意保存的是地址值
    tqueue->node[tqueue->rear] = (TSeqQueueNode)item;
    //让队尾向后移动一个位置,如果超出数组,则重新指向0号位置
    //此时数组是循环利用的
    tqueue->rear = (tqueue->rear + 1) % tqueue->capacity;
    tqueue->length++;
    }

  }
  return iret;
}


/*
  在队头移出一个元素
  如果成功,返回被移出的元素指针,否则,返回NULL
*/
SeqQueueNode *SeqQueue_Retrieve(SeqQueue *queue) //O(1)
{
  TSeqQueueNode *ret = NULL;
  TSeqQueue *tqueue = (TSeqQueue*)queue;
  if(tqueue != NULL)
  {
    //判断是否还有元素可取
    if(tqueue->length > 0)
    {
      ret = (SeqQueueNode*)tqueue->node[tqueue->front];
      //让队头向后移动一个位置,如果超出了数组,则指向0号位置
      tqueue->front = (tqueue->front + 1) % tqueue->capacity;
      tqueue->length--;
    }

  }
  return ret;
}

7、完整源码下载

文件名:seqqueue-1.0.tar.gz
说明:利用顺序链表实现的顺序队列
链接: http://pan.baidu.com/s/1kTnDpaf 密码: b7di

文件名:seqqueue-2.0.tar.gz
说明:未使用顺序链表,采用改进的算法重新实现的顺序队列
链接: http://pan.baidu.com/s/1i3Ij6g1 密码: eixe

编译步骤:
0.1 解压缩:tar -zxvf seqqueue-1.0.tar.gz/seqqueue-2.0.tar.gz
0.2 进入目录:./configure
0.3 生成Seqlist:make
0.4 运行程序:./SeqQueue

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值