C语言数据结构之队列(QUEUE)的实现
同Stack一样,也可以用数组来实现队列这一数据结构,队列的特点是先入先出(FIFO, First In First Out)原则,当队列指针到达数组尾部时,可以让队列指针指向数组头部,实现数组的循环使用,也就是循环队列。
简单实现
- QSIZE 队列的长度
- Qdata 保存队列数据的数组
- front 队列头指针
- rear 队列尾指针
- queue_is_empty 判断队列是否为空
- queue_is_full 判断队列是否为满
- enqueue 数据入队
- dequeue 数据出队
- queue_info 显示队列相关信息
- test_queue测试函数
代码如下:
/* filename : queue.c */
#include <stdio.h>
#include <stdlib.h>
/* define queue size */
#define QSIZE 8
/* define Qdata array, queue front and rear */
static int Qdata[QSIZE] = {0};
static int front = 0;
static int rear = 0;
/* if queue is empty return 1 else return 0 */
int
queue_is_empty (void)
{
return (front == rear);
}
/**/
int
queue_is_full (void)
{
return ((rear + 1) % QSIZE == front);
}
/* push val into queue */
void
enqueue (int val)
{
if (queue_is_full())
{
printf ("Warning : Queue is full!\n");
return;
}
Qdata[rear] = val;
rear = (rear + 1) % QSIZE;
}
/* pop a val from queue */
int
dequeue (void)
{
int tmp = -1;
if (queue_is_empty())
{
printf ("Warning : Queue is empty!\n");
return tmp;
}
tmp = Qdata[front];
front = (front + 1) % QSIZE;
return tmp;
}
/* output queue info */
void
queue_info (void)
{
int i = front;
printf ("Front : %d, rear : %d\n", front, rear);
printf ("[ ");
while (i != rear)
{
printf ("%d ", Qdata[i]);
i = (i + 1) % QSIZE;
}
printf ("]\n------------------------------\n");
}
/********************************/
/**/
void
test_queue (void)
{
for (int i = 0; i < 10; i++)
enqueue (1000 + i);
queue_info ();
printf ("dequeue : [ ");
for (int i = 0; i < 5; i++)
printf ("%d ", dequeue ());
printf ("]\n");
queue_info ();
for (int i = 0; i < 3; i++)
enqueue (1008 + i);
queue_info ();
printf ("dequeue : [ ");
for (int i = 0; i < 5; i++)
printf ("%d ", dequeue ());
printf ("]\n");
dequeue ();
queue_info ();
}
/**/
int
main (int argc, char *argv[])
{
test_queue ();
return 0;
}
/* --[oooooooo]-- */
编译运行,测试结果如下:
songvm@ubuntu:~/works/xdn/loo$ gcc queue.c -o queue
songvm@ubuntu:~/works/xdn/loo$ ./queue
Warning : Queue is full!
Warning : Queue is full!
Warning : Queue is full!
Front : 0, rear : 7
[ 1000 1001 1002 1003 1004 1005 1006 ]
------------------------------
dequeue : [ 1000 1001 1002 1003 1004 ]
Front : 5, rear : 7
[ 1005 1006 ]
------------------------------
Front : 5, rear : 2
[ 1005 1006 1008 1009 1010 ]
------------------------------
dequeue : [ 1005 1006 1008 1009 1010 ]
Warning : Queue is empty!
Front : 2, rear : 2
[ ]
------------------------------
songvm@ubuntu:~/works/xdn/loo$
封装到一个结构体定义数据类型Queue
- 保存数据的指针elts
- 头指针front,尾指针rear
- 队列长度length
- 将数据推入队列 queue_push
- 从队列弹出数据 queue_pop
- 测试向队列推入10个字符串,然后从队列弹出,输出队列相关信息
代码如下:
/* filename : queue.c */
#include <stdio.h>
#include <stdlib.h>
/* compile : gcc queue.c -o queue */
/* run : ./queue */
/* define datatype Queue */
typedef struct _Queue Queue;
struct _Queue {
void **elts;
int front, rear;
int length;
};
/* create a new Queue */
Queue*
queue_new (int len)
{
Queue *q = (Queue*) malloc (sizeof(Queue));
q->elts = (void**) malloc (len * sizeof(void*));
q->front = 0;
q->rear = 0;
q->length = len;
return q;
}
/* free the Queue */
void
queue_free (Queue *q)
{
free (q->elts);
free (q);
}
/* if queue is empty return 1 else return 0 */
int
queue_is_empty (Queue *q)
{
if (q->front == q->rear) return 1;
return 0;
}
/* if queue is full return 1 else return 0 */
int
queue_is_full (Queue *q)
{
if ((q->rear + 1) % q->length == q->front) return 1;
return 0;
}
/* push data info a queue */
void
queue_push (Queue *q, void *data)
{
if (queue_is_full(q))
{
printf ("Warning : Queue is full!\n");
return;
}
q->elts[q->rear] = data;
q->rear = (q->rear + 1) % q->length;
}
/* pop data from a queue */
void*
queue_pop (Queue *q)
{
void *tmp = NULL;
if (queue_is_empty(q))
{
printf ("Warning : Queue is empty!\n");
return tmp;
}
tmp = q->elts[q->front];
q->front = (q->front + 1) % q->length;
return tmp;
}
/* output queue info */
void
queue_info (Queue *q)
{
int i = q->front;
printf ("Queue length is %d\n", q->length);
printf ("Front : %d, rear : %d\n", q->front, q->rear);
printf ("[ ");
while (i != q->rear)
{
printf ("%s ", (char*)(q->elts[i]));
i = (i + 1) % q->length;
}
printf ("]\n------------------------------\n");
}
/**********************************/
/**/
void
test_queue (void)
{
char *buf[10] = {"AAA", "BBB", "CCC", "DDD", "EEE",
"FFF", "GGG", "HHH", "III", "JJJ"};
Queue *qu = queue_new (10);
for (int i = 0; i < 10; i++)
queue_push (qu, (void*)(buf[i]));
queue_info (qu);
for (int i = 0; i < 10; i++)
{
char *t = (char*)(queue_pop (qu));
if (t != NULL)
printf ("%s\n", t);
}
queue_info (qu);
queue_free (qu);
}
/**/
int
main (int argc, char *argv[])
{
test_queue ();
return 0;
}
/* [ooooooooo] */
编译运行,效果如下,达到预期:
songvm@ubuntu:~/works/xdn/loo$ gcc queue.c -o queue
songvm@ubuntu:~/works/xdn/loo$ ./queue
Warning : Queue is full!
Queue length is 10
Front : 0, rear : 9
[ AAA BBB CCC DDD EEE FFF GGG HHH III ]
------------------------------
AAA
BBB
CCC
DDD
EEE
FFF
GGG
HHH
III
Warning : Queue is empty!
Queue length is 10
Front : 9, rear : 9
[ ]
------------------------------
songvm@ubuntu:~/works/xdn/loo$
下一步研究一下哈希表!!!