队列的实现-顺序队列和链队列

来源:互联网 发布:tina8.0电路仿真软件 编辑:程序博客网 时间:2024/05/16 05:51

本文主要给出我对队列的实现,包括顺序队列和链队列。

顺序队列(循环队列)

基本概念

顺序队列

顺序队列是用数组存放队列元素,同时设置队头和对尾指针来控制元素的出队和入队。约定:

  • 队头指针front指向队头元素,
  • 队尾指针rear指向队尾元素的下一个

由于单纯的顺序队列存在“假溢出”的现象,即指针是单向移动的,当front在高地址的时候,其实低地址的空间也可以使用。所以,考虑采用循环队列的形式来实现。循环队列是将存储队列的数组看成头尾相接的循环结构,从而地段低端地址也可以得到有效的使用。

在循环队列中,浪费一个数组元素空间的情况下:

  • 队空的条件是 : front == rear;
  • 队满的条件是:(rear + 1) % QUEUE_SIZE = front
  • 队列的长度是:(rear - front + QUEUE_SIZE) % QUEUE_SIZE

需要特别注意的是,循环队列队头和队尾指针的移动,都要在循环意义下 + 1 即:

  • front = (front + 1) % QUEUE_SIZE
  • rear = (rear + 1) % QUEUE_SIZE

代码实现

常量声明

common.h

#ifndef common_H#define common_H/* 函数结果状态码 */#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1//#define OVERFLOW -2//#define UNDERFLOW -3/* 类型定义 */typedef int Status;     // Status是函数的类型,其值是函数结果状态码typedef int ElemType;   // ElemType是数据类型#endif

顺序队列存储结构声明

Queue.h

#ifndef Queue_H#define Queue_H#define QUEUE_SIZE 1024#include "common.h"#include <cstring>// 循环队列结构定义struct Queue{    ElemType data[QUEUE_SIZE];    int front; // 头指针    int rear;  // 尾指针    Queue(){ std::memset( this, 0, sizeof(Queue) ); }};// 循环队列基本操作Status push( Queue& que, ElemType x );Status pop( Queue& que );ElemType front( Queue& que );ElemType back( Queue& que );int size( Queue& que );bool empty( Queue& que );#endif

顺序队列基本操作(Queue.cpp)

  • 入队
    思路:注意上溢
Status push( Queue& que, ElemType x ){    if( (que.rear + 1)%QUEUE_SIZE == que.front ){        std::cerr << "Overflow";        return OVERFLOW;    }    else{        que.data[ que.rear ] = x;        que.rear = ( que.rear + 1 )%QUEUE_SIZE; // 循环意义下+1        return OK;    } }
  • 出队
    思路:注意下溢
Status pop( Queue& que ){    if( que.front == que.rear ){        std::cerr << "Underflow";        return UNDERFLOW;    }    else{        que.front = (que.front + 1)%QUEUE_SIZE; // 循环意义下+1        return OK;    }}
  • 返回队头元素
    思路:注意上溢
ElemType front( Queue& que ){    if( que.front == que.rear ){        std::cerr << "Underflow";        return UNDERFLOW;    }    else{        return que.data[que.front];    }}
  • 返回队尾元素
    思路:注意下溢
ElemType back( Queue& que ){    if( que.front == que.rear ){        std::cerr << "Underflow";        return UNDERFLOW;    }    else{        return que.data[ (que.rear - 1)%QUEUE_SIZE ];    }}
  • 返回队列大小
int size( Queue& que ){    return (que.rear - que.front + QUEUE_SIZE)%QUEUE_SIZE;}
  • 判断队空
bool empty( Queue& que ){    return que.front == que.rear;}

链队列

基本概念

链队列

顺序队列是用链表存放队列元素,同时设置队头和对尾指针来控制元素的出队和入队。约定:

  • 队头指针front指向队头元素的前一个,即指向头结点
  • 队尾指针rear指向队尾元素

代码实现

常量声明

common.h

#ifndef common _H#define common_H/* 函数结果状态码 */#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1//#define OVERFLOW -2//#define UNDERFLOW -3/* 类型定义 */typedef int Status;     // Status是函数的类型,其值是函数结果状态码typedef int ElemType;   // ElemType是数据类型#endif

链队列存储结构声明

LinkedQueue.h

#ifndef LinkedQueue_H#define LinkedQueue_H#include "common.h"#include <cstdlib>#include <cstring>// 链队列节点结构声明struct ListNode{    ElemType data;    ListNode* next;    ListNode() { std::memset(this, 0, sizeof(ListNode)); }    ListNode( ElemType x ) : data(x), next(NULL) {}};// 链队列结构声明struct LinkedQueue{    ListNode* front; // front指向队首前一个元素即头结点    ListNode* rear;  // rear指向队尾元素    LinkedQueue(){        front = new ListNode; // 增加头结点        rear = front;    }    virtual ~LinkedQueue(){        delete front;    }};// 链队列基本操作Status push( LinkedQueue& que, ElemType x );Status pop( LinkedQueue& que );ElemType front( LinkedQueue& que );ElemType back( LinkedQueue& que );int size( LinkedQueue& que );bool empty( LinkedQueue& que );#endif

链队列基本操作(LinkedQueue.cpp)

  • 入队
Status push( LinkedQueue& que, ElemType x ){    ListNode* s = new ListNode(x);    if(!s){        std::cerr << "Not enough space!";        return ERROR;    }    que.rear->next = s;    que.rear = s;    return OK;}
  • 出队
    思路:小心队列为空的情形
Status pop( LinkedQueue& que ){    ListNode* s = que.front->next;    if(!s){        std::cerr << "Underflow";        return UNDERFLOW;    }    else{        que.front->next = s->next;        delete s;        return OK;    }}
  • 获得队头元素
    思路:小心队列为空的情形
ElemType front( LinkedQueue& que ){    ListNode* s = que.front->next;    if(!s){        std::cerr << "Underflow";        return UNDERFLOW;    }    else{        return s->data;    }}
  • 获得队尾元素
    思路:小心队列为空的情形
ElemType back( LinkedQueue& que ){    ListNode* s = que.rear;    if(!s){        std::cerr << "Underflow";        return UNDERFLOW;    }    else{        return s->data;    }}
  • 获得队列大小
int size( LinkedQueue& que ){    ListNode* p = que.front->next;    int cnt = 0;    while(p){        ++cnt;        p = p->next;    }    return cnt;}
  • 判断队列是否为空
bool empty( LinkedQueue& que ){    return que.front == que.rear;}
0 0
原创粉丝点击