代码如下,现在来解析下几个比较重要的地方。。。
#include <stdio.h>
#include <stdlib.h>
struct list_node{
int data;
struct list_node *next;
};
struct queue{
struct list_node *front;
struct list_node *rear;
};
int is_queue_empty(struct queue *q )
{
return (q->front==NULL || q->rear==NULL);
}
int enqueue(struct queue *q,int value)
{
struct list_node *p = (struct list_node *)malloc(sizeof(struct list_node));
if(p ==NULL)
{
printf("malloc failed \n");
return -1;
}
p->data = value;
p->next = NULL;
if(q->rear ==NULL)
q->front = q->rear =p;
else
{
q->rear->next = p;
q->rear = p;
}
return 0;
}
struct list_node *dequeue(struct queue *q)
{
struct list_node *p;
if(q->front ==NULL){
printf("empty queue \n");
return (struct list_node*)-1;
}
p = q->front;
if(q->front->next ==NULL)
q->front = q->rear =NULL;
else
q->front = q->front->next;
return p;
}
void clear_queue(struct queue *q)
{
struct list_node *p;
if(q->front == NULL){
printf("empty queue \n");
free(q);
}
p = q->front;
while(p != NULL){
q->front = q->front->next;
free(p);
p= q->front;
}
free(q);
}
int print_queue(struct queue *q)
{
struct list_node *p;
if(q ==NULL){
printf("no queue \n");
return -1;
}
p = q->front;
while(p!=NULL){
printf("%d\n",p->data);
p =p->next;
}
return 0;
}
int main(void)
{
struct queue *q = (struct queue *) malloc(sizeof(struct queue));
q->front = q->rear = NULL;
struct list_node *node;
enqueue(q,1);
enqueue(q,2);
print_queue(q);
node = dequeue(q);
free(node);
clear_queue(q);
}
队列的插入 enqueue 函数分析。我们知道 ,队列只能在队尾插入元素。
if(q->rear ==NULL)
q->front = q->rear =p; 表明队列中没有元素,这个是第一个元素。
如下图所示的这种情况。。
继续看代码,else 是正常情况的插入
else
{
q->rear->next = p;
q->rear = p;
}
看下面这张图: 首先 把 p(要插入的节点)的地址存储在 q->rear 节点上 (队尾),形成一个链表,连接起来。
此时,p成为了最后一个节点,要 把队尾节点移动到p处 (q->rear = p;)
在来看删除函数,只能在 队列的头删除
dequeue
if(q->front->next ==NULL)
q->front = q->rear =NULL;
这两句说明,这个队列里面现在只有一个节点,你要删除。 你删了,就没有节点了,把 front 和 rear 都设置为空。
如图:
接下来再看正常的删除操作。。
else
q->front = q->front->next;
如下图 删除操作。
再来看打印函数 int print_queue(struct queue *q)
p = q->front; 一定要定义个临时变量把 q->front 接过来,千万不要直接使用 q->front遍历,不然队列的头就乱套了。