循环队列

来源:互联网 发布:一元夺宝走势软件 编辑:程序博客网 时间:2024/06/07 18:32

不是只有排序,二叉树才叫数据结构,面试栽在基本的数组和队列,链表,栈的有的是!!!本文对循环队列的重要操作作出总结。注:为了避免队列空和满两个状态混淆, 
采用空闲一个位置的方式,即N个元素空间的循环队列最多只能存放N-1个有效元素。这也是大多数教材的做法。
1) 循环队列初始化:front=rear=0;
2)入队操作:rear=(rear+1)%size;
3)出队操作:front=(front+1)%size;
4)判断是否为空队列:front==rear;
5)判断队列是否已满:front=(rear+1)%size;
6)遍历队列各元素。

 

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <stdbool.h>   //注意使用布尔类型时,需要引入此头文件
 
/*******************************************************************************************************************
定义循环队列的结构体。注:循环队列是在数组的基础上实现的,所以需要一个指向首元素的指针,另外头和尾用int来表示相对偏移量即可。
********************************************************************************************************************/
typedef struct Queue
{
    int * qBase;
    int front;
    int rear;
}QUEUE;
 
void initQueue(QUEUE *pq);
void enQueue(QUEUE *pq , int value);
bool isemptyQueue(QUEUE *pq);
bool is_fullQueue(QUEUE *pq);
void deQueue(QUEUE *pq , int *value);
void traverseQueue( QUEUE *pq);
 
/***************************************** 主函数测试入口 ********************************************/
int main(){
    int val;
    QUEUE queue = {NULL,0,0} ;
    initQueue(&queue);
    enQueue(&queue,4);
    enQueue(&queue,5);
    enQueue(&queue,6);
    enQueue(&queue,7);
    enQueue(&queue,72);
    enQueue(&queue,42);
 
    traverseQueue(&queue);
    deQueue(&queue , &val);
    deQueue(&queue , &val);
 
    traverseQueue(&queue);
    enQueue(&queue,55);
    enQueue(&queue,65);
    traverseQueue(&queue);
 
    return 0;
}
/**************************************初始化一个空的循环队列 ******************************************/
void initQueue(QUEUE *pq){
    pq->qBase = (int *)malloc(sizeof(int)*6);
    if(pq->qBase == NULL){
        printf("内存分配失败!\n");
        exit(-1);
    }
    pq->front = pq->rear = 0;
}
/***************插入一个新元素  注:插入前需要先判断该队列是否已满,避免覆盖有效数据******************/
 
void enQueue(QUEUE *pq , int value){
 
    if(is_fullQueue(pq)){
        printf("循环队列已满,拒绝插入%d!\n",value);
     }
   else{
        pq->qBase[pq->rear] = value;
        pq->rear = (pq->rear + 1)%6 ;
        printf("\n %d 入队 \n" , value);
     }
}
 
/**************  删除一个元素,并通过指针返回该数  注:删除前要判断该队列是否为空。*******************/
 
 void deQueue(QUEUE *pq , int *value){
     if(isemptyQueue(pq)){
      printf("循环队列已空!");
    }
  else{
        *value = pq->qBase[pq->front];
        printf("\n %d 出队 \n",*value);
        pq->front = (pq->front + 1)%6 ;
     }
  }
 /************************************     判断循环队列是否为空 ************************************/
bool isemptyQueue(QUEUE *pq){
    if(pq->front == pq->rear){
        return true;
    }
    else
        return false;
}
 
/************************************    判断循环队列是否已满 ************************************/
bool is_fullQueue(QUEUE *pq){
    if((pq->rear +1)%6 == pq->front){
        return true;
    }else
        return false;
}
 
/*************************************     遍历循环队列中的各元素 *************************************/
void traverseQueue( QUEUE *pq){
    if(isemptyQueue(pq)){
        printf("循环队列为空!\n");
        exit(0);
    }
    printf("当前循环队列 :\n");
    printf("front是%d,rear是%d :\n",pq->front,pq->rear);
  
    int tail = pq->front ;
    while(tail != pq->rear){
        printf(" %d ",pq->qBase[tail]);
        tail = (tail + 1)%6;
    }
}



C++模板实现:

//
// C++ 模版技术实现简单循环队列示例.
//
 
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <stdexcept>
 
//
// 循环队列类模版.
//
// 由于循环队列队尾永远为空,队列物理空间应比指定队列逻辑空间大 1,
// 而返回的队列大小 size 应该为逻辑大小.
//
// 入队/出队时当发生上/下溢将抛出异常.
//
template <typename T>
class CircularQueue
{
private:
    T *_pQueue;
    size_t _front, _rear, _size;
    static const size_t _MAX_QUEUE_SIZE = 20;
 
public:
    CircularQueue(const size_t size = _MAX_QUEUE_SIZE)
        : _front(0)
        , _rear(0)
        , _size(size + 1)
    { _pQueue = new T[_size]; }
     
     
    ~CircularQueue(void)
    {delete[] _pQueue; }
     
     
    size_t getSize(void)const
    {return _size - 1; }
     
     
    T getFront(void)const
    {
        if (isEmpty()) {
            throw std::underflow_error("队列为空 !");
        }
        return _pQueue[_front];
    }
     
     
    bool isEmpty(void)const
    {return _front == _rear; }
     
     
    bool isFull(void)const
    {return (_rear + 1) % _size == _front; }
     
     
    void enqueue(const T &val)
    {
        if (isFull()) {
            throw std::overflow_error("队满上溢 !");
        }
        _pQueue[_rear] = val;
        _rear = (_rear + 1) % _size;
    }
     
     
    T dequeue(void)
    {
        if (isEmpty()) {
            throw std::underflow_error("队空下溢 !");
        }
        T value = _pQueue[_front];
        _front = (_front + 1) % _size;
         
        return value;
    }
};
 
 
//
// 队列测试
//
int main(void)
{
    CircularQueue<int> queue;
    const size_t QUEUE_SIZE = queue.getSize();
     
    for (size_t i = 0; i < QUEUE_SIZE; ++i)
    {
        queue.enqueue(i);
    }
     
    // queue.enqueue(QUEUE_SIZE);
     
    std::cout << std::endl
              <<"队列" << (queue.isFull() ? "" :"不") << "为满."
              << std::endl
              <<"队列" << (queue.isEmpty() ? "" :"不") << "为空."
              << std::endl;
     
    for (size_t i = 0; i < QUEUE_SIZE; ++i)
    {
        std::cout << std::setw(3) << queue.dequeue();
    }
     
    // std::cout << std::setw(3) << queue.dequeue();
     
    std::cout << std::endl
              <<"队列" << (queue.isFull() ? "" :"不") << "为满."
              << std::endl
              <<"队列" << (queue.isEmpty() ? "" :"不") << "为空."
              << std::endl;
               
     
     
    return EXIT_SUCCESS;
}


原创粉丝点击