队列
1.队列的定义
同栈一样,队列也是一种特殊的线性表。其主要特征为先进先出(FIFO)。常见的操作包括:
- 初始化
- 销毁
- 清空
- 判空
- 入队
- 出队
- 遍历
- …
2. 队的实现
由于堆也是线性表的子集,所以队列的实现也可以分为两种:顺序队列(本文中用的是循环队列)和链队。
在具体实现前,先贴上文章代码中公有的头文件,主要是定义了一些状态宏。
//
// Created by 张兴锐 on 2018/7/25.
//
#ifndef DATASTRUCTURE_PUBLIC_H
#define DATASTRUCTURE_PUBLIC_H
// 函数结果状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASLIBLE -1
#define OVERFLOW
typedef int Status;
typedef int ElemType;
#endif //DATASTRUCTURE_PUBLIC_H
现在,先介绍一链。
3. 链队列
链队的结构如下图:
链队有两个指针,一个头指针,其next指向头结点,另一个尾指针队尾结点。
3.1 定义
//----------------链队列定义------------
/**
* 节点
*/
typedef struct Node{
ElemType data;
struct Node *next;
}*LkNode;
/**
* 队列:
* head 头指针
* tail 尾指针
*/
typedef struct LQ{
LkNode head;
LkNode tail;
}LinkQueue;
3.2 初始化
/**
* 初始化队列
* @param queue
* @return OK
* ERROR
*/
Status initQueue(SqQueue &queue){
queue.elem = (ElemType *)malloc(MAX_SIZE*sizeof(ElemType));
if(!queue.elem) exit(ERROR);
queue.head = 0;
queue.tail = 0;
return OK;
}
3.3 入队
/**
* 入队
* @param queue
* @return OK
* ERROR
*/
Status enQueue(LinkQueue &queue,ElemType e){
LkNode p = (LkNode)malloc(sizeof(Node));
if(!p) exit(ERROR);
p->data = e;
p->next = NULL;//p->next = queue.tail->next;
queue.tail->next = p;
queue.tail = p;
return OK;
}
3.4 出队
/**
* 出队
* @param q
* @param e
* @return
*/
Status deQueue(LinkQueue &queue,ElemType &e){
if(queue.head == queue.tail) exit(ERROR);
LkNode p = queue.head->next;
e = p->data;
queue.head->next = p->next;
if(p == queue.tail) queue.tail = queue.head; //删除最后一个元素后,tail指针丢失地址
free(p);
return OK;
}
需要特别注意的是,在出队操作中,
if(p == queue.tail) queue.tail = queue.head; //删除最后一个元素后,tail指针丢失地址
需要将尾指针重定向。
3.5 其余操作
/**
* 判空
* @param q
* @return
*/
Status isEmpty(LinkQueue &q){
if(q.head == q.tail) return TRUE;
return FALSE;
}
/**
* 销毁队列
* @param queue
* @return
*/
Status destroyQueue(LinkQueue &queue){
while(queue.head){
LkNode p = queue.head->next;
free(queue.head);
queue.head = p->next;
}
return OK;
}
4. 循环队列
由于普通循环队列中,可能存在如下情况
这时,不可继续插入新的队尾元素,又不宜开辟新的空间,毕竟原空间并没有占满。所以使用循环队列的结构。其核心在于
4.1 定义
//----------------循环队列定义------------
#define MAX_SIZE 6
typedef struct{
ElemType *elem;
int head;
int tail;
}SqQueue;
4.2 初始化
/**
* 初始化队列
* @param queue
* @return OK
* ERROR
*/
Status initQueue(SqQueue &queue){
queue.elem = (ElemType *)malloc(MAX_SIZE*sizeof(ElemType));
if(!queue.elem) exit(ERROR);
queue.head = 0;
queue.tail = 0;
return OK;
}
4.3 入队
/**
* 入队列
* @param queue
* @param e
* @return
*/
Status enQueue(SqQueue &queue, ElemType e){
if(queue.tail + 1 % MAX_SIZE == queue.head) exit(ERROR);
queue.elem[queue.tail] = e;
queue.tail = (queue.tail + 1) % MAX_SIZE;
return OK;
}
4.4 出队
/**
* 出队
* @param queue
* @param e
* @return
*/
Status deQueue(SqQueue &queue,ElemType &e){
if(queue.head == queue.tail) exit(ERROR);
e = queue.elem[queue.head];
queue.head = (queue.head+1) % MAX_SIZE;
return OK;
}