数据结构-队列(上)

205 阅读2分钟

队列(上)

队列的结构以及顺序表中队列(queue_s)的定义、初始化

队列和栈一样,也是一种特殊的线性表,和栈不同的是,栈只能在线性表的一端进行插入和删除操作,而常规的队列(因为还有双端队列这种情况)是在线性表的一端只能进行插入操作,另一端只能进行删除操作。

#define MaxSize 100

//队列结构体
struct queue_s {
    int front, rear;
    int data[MaxSize];
};
//队列初始化
queue_s *new_queue_s() {
    queue_s *q = new queue_s;
    q->front = 0;
    q->rear = 0;
    return q;
}

在这种队列中,我们可以使用front==rear==0作为判空条件,但是判断队列满条件不能是rear==MaxSize,因为随着数据元素的删除,front指针的值也在不断增加,最后删除完成所有的数据元素后,front==rear,但是rear指针的值仍然是MaxSize,也就是说rear指针的值并不会因为删除操作而减少。所以这种顺序队列是存在缺点的。

顺序表中定义循环队列(queue_r)

#define MaxSize 100

//循环队列结构体
struct queue_r {
    int front, rear;
    int data[MaxSize];
};
//循环队列初始化
queue_r *new_queue_r(){
    queue_r *q = new queue_r;
    q->front = 0;
    q->rear = 0;
    return q;
}
//判空
bool isEmpty(queue_r q) {
    if (q.front == q.rear) return true;
    return false;
}
//判满
bool isFull(queue_r q) {
    if ((q.rear + 1) % MaxSize == q.front) return true;
    return false;
}

这种队列弥补了传统顺序队列的缺点,它将队列看作为一个环状的结构(虽然本质上还是由一个顺序数组组成)。这样当front的值为MaxSize-1(即即将到达队列所容许的最大容量)时,再进一步就会将front的值变为0(front=(front+1)%MaxSize,取余操作)。这样,判断队列满的条件就变成了front==rear。不过,这也和队列空的判别条件产生了冲突,即当front==rear时,这个队列可能是空的,也可能是满的。

常见的纠正方法为牺牲一个存储单元,即数据元素入队时从下一个存储单元入队,这样判满条件就变成了(rear+1)%MaxSize==front,和判空条件作出了区分。

当然,还可以在队列的结构体中增加数据变量用来进行记录数据信息,比如增加某个变量用来代表当前队列元素个数,或者直接增加变量用来代表当前队列空还是队列满。