队列

       队列的特点就不需要再多说了,用于执行元素的插入和删除的函数并没有一个被普遍认可的名字,所以我们将使用insert和delete这个两个名字,并且也没有规定插入到底是在对头还是队尾,总之就是插入和删除各在一头,但是为了现实中的队列相吻合往往比较容易记忆,所以这里同一使用在队尾插入元素在队头删除元素。

      首先还是定义队列的接口。在传统的队列接口中delete函数从队列的头部删除一个元素并返回这个元素,也就是说这个delete函数实际上肩负这两个任务,也就是具有副作用,我们应该尽量避免编写有副作用的函数这样便于维护也便于理解,因此这里使用另外一种接口方式:delete函数删除队列头部的一个元素,但并不返回它,first函数返回第一个元素的值并不将它从队列中删除。除此还有insert函数、create_queue函数和destroy_queue函数。数组的接口定义文件如下:

 

 

      接下来是队列的实现,队列的实现要比堆栈要难,它需要两个指针一个指向队列的头部,一个指向队列的尾部。并且在队列中插入一个元素和删除一个元素以后类似于整个队列向前移位了一样,因此使用数组方式很不适合创建队列,因为数组的起始端在创建时已经固定了,但是队列的两端是不固定的。为了使数组适合于队列的形式发明了循环队列,循环队列把存储空间看成一个环,这样插入和删除元素都是在这个环内实现,避免了内存空间的不断变化,循环队列的实现也比较简单,当尾部下标移出到队列的尾部时,将将下标置0,使其指向队列最初的头部(此时队列的真正头部并不一定在此处,因为有可能有元素出队。)当有元素再次插入时就可以利用原先出队操作而空闲的内存空间。实现方式如下:

      rear  =  (rear + 1)%queue_size;

     对于头指针也需要这样实现;

      front =  (front + 1)%queue_size;

       这里又引入了一个新问题,试想一下当队列为空是rear和front指针是相等的,当队列满是rear指针和front指针也是相等的,那么当front==raer时,队列到底是空呢还是为满呢?

有两种方式可以解决这个问题:一种是引入一个新变量记录队列中元素的个数;另一种是重新定义队列满的含义,就是说不在使用front==rear作为队列满的标识,一种比较认可的方式是通过不允许数组完全填满来解决这个问题。

      还有一个小问题是,当队列中只有一个元素时需要保证对头指针和队尾指针都指向这个元素,而队尾指针在插入一个元素时都需要先增加rear的值,也就是说当队列为空时rear的值应该比front的值小1,因此判断队列为满就不能使用rear的值比front的值小1了而是应该小2。

     综上所述,判断一个队列满的条件应该是:

     (rear+2)%queue_size == front;

     判断一个队列空的条件应该是:

     (rear+1)%queue_size == front;

分析完后,下面就是各种存储方式的实现了。

首先是数组方式的实现:

 

 

接下来是动态数组的实现方式,动态数组和静态数组的实现方式很相似,只是多了一个创建队列和销毁队列的过程。

 

 

 

最后是链式机构的实现方式,比较简单:

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值