C语言数据结构之队列(QUEUE)的实现

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$ 

下一步研究一下哈希表!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值