队列
什么是队列
队列是一种特殊的线性表,单向队列只能在一端插入数据(后),另一端删除数据(前);它和栈一样,队列是一种操作受限制的线性表;进行插入操作的称为队尾,进行删除操作的称为队头;队列中的数据被称为元素;没有元素的队列称为空队列。(First In First Out,FIFO)
顺序队列
顺序队列的结构声明
typedef int ElemType;
typedef struct Queue
{
ElemType *data;
int head;
int rear;
int size;
}Queue;
队列的操作方法
队列的初始化_InitQueue
void InitQueue(Queue *que, int init_size)
{
if(que == NULL) exit(0);
init_size = init_size >= 0 ? init_size : 10; // UNDO
que->data = (ElemType*)malloc(sizeof(ElemType) * init_size); // UNDO
que->head = que->rear = 0; //head 和 rear 都为 0
que->size = init_size;
}
插入元素_Push
bool Push(Queue *que, ElemType value)
{
if(que == NULL) exit(0);
if(Full(que)) //判满
{
if(!AppendSpace(que))//申请空间
{
return false;
}
}
// UNDO
que->data[que->rear] = value;
que->rear = (que->rear+1) % que->size;
return true;
}
判满_Full
如果rear==front 时 是无法判断队列到底是空还是满的,所以我们牺牲一个存储单元,例如上图,六个空间我们只使用五个。当 (que->rear+1)%que->size == que->head 时 这样判断队列是否为满
static Bool Full(Queue *que)
{
if((que->rear+1) % que->size == que->head)
return TRUE;
return FALSE;
}
申请空间_AppendSpace
static Bool AppendSpace(Queue *que)
{
ElemType *new_space = (ElemType *)malloc(sizeof(ElemType) * que->size * 2);//申请双倍空间
if(new_space == NULL) return FALSE;
// UNDO 挪数据
int index = 0;
while(que->head != que->rear)
{
new_space[index++] = que->data[que->head++];//把原本que->date的元素放入new_space
//que->head 相当于数组下标
que->head = que->head % que->size;
}
que->head = 0;
que->rear = que->size - 1;
free(que->data);
que->data = new_space;
que->size *= 2;
return TRUE;
}
弹出队顶元素_Pop
bool Pop(Queue *que)
{
if(que == NULL) exit(0);
if(Empty(que)) return FALSE;
que->head += 1;
que->head %= que->size;
return TRUE;
}
判空_Empty
Bool Empty(Queue *que)
{
if(que == NULL) exit(0);
if(que->head == que->rear) return TRUE;
return FALSE;
}
队顶元素_Top
Bool Top(Queue *que, ElemType *reval)
{
// UNDO
if(que == NULL || Empty(que)) return FALSE;
*reval = que->data[que->head];
return TRUE;
}
销毁队列_DestroyQueue
void DestroyQueue(Queue *que)
{
if(que == NULL) exit(0);
free(que->data);
que->data = NULL;
que->head = que->rear = que->size = 0;
}
链式队列
链式队列的结构
typedef int ElemType;
typedef struct Node
{
ElemType data;
struct Node *next;
}Node;
typedef struct Queue
{
Node *head; // 头指针
Node *rear; // 尾指针
}Queue;
方法的实现
队列的初始化_InitLinkQue
void InitLinkQue(Queue *que)
{
if(que == NULL) exit(0);
que->head = que->rear = NULL;
}
插入队列_Push
int Push(Queue *que, ElemType value)
{
if(que == NULL) exit(0);
Node *new_node = (Node *)malloc(sizeof(Node));
if(new_node == NULL) return 0;
new_node->data = value;
new_node->next = NULL;
if(Empty(que))
{
que->head = que->rear = new_node;
}
else
{
que->rear->next = new_node; //队列链表的原本最后一个结点指向new_node
que->rear = new_node;//这时候链表最后一个结点变为new_node
}
return 1;
}
判空_Empty
int Empty(Queue *que)
{
if(que == NULL) exit(0);
return que->head == NULL;
}
弹出_Pop
int Pop(Queue *que)
{
if(que == NULL) exit(0);
if(Empty(que)) return 0;
Node *p = que->head;
que->head = p->next;
//将head后移一个结点
free(p);
if(que->head == NULL) que->rear = NULL;
return 1;
}
获得队顶元素
int Top(Queue *que, ElemType *reval)
{
if(que == NULL) exit(0);
if(Empty(que)) return 0;
*reval = que->head->data;
return 1;
}
销毁队列
void DestroyLinkQue(Que *que)
{
if(que == NULL) exit(0);
while(!Empty(que))
{
Pop(que);
}
}