// 2014年4月17日
// 顺序队列的表示和实现
// 数据格式
//
// front
// near
// size
// front near
// ↓ ↓
// data -> [data] [data] [data] [data] ... [data]
//
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <time.h>
typedef int element_t;
typedef struct tag_queue_t
{
int front; // 头部指示器
int near; // 尾部指示器
int size; // 缓冲区大小
element_t *data; // 数据缓冲区
} *queue_t;
// 初始化队列,分配内存,填充结构体成员
void queue_init(queue_t& queue)
{
queue = (queue_t)malloc(sizeof(tag_queue_t));
queue->data = (element_t *)malloc(sizeof(element_t));
queue->size = 1;
queue->front = 0;
queue->near = 0;
}
// 销毁队列,释放内存
void queue_destroy(queue_t& queue)
{
free(queue->data);
free(queue);
queue = 0;
}
// 清空队列,头部指示器和尾部指示器相等即可
void queue_clear(queue_t& queue)
{
queue->near = queue->front;
}
// 尾部指示器和头部的相等则为空
bool queue_is_empty(queue_t& queue)
{
return queue->front == queue->near;
}
// 尾部指示器再移动一次和头部的相等则已满
bool queue_is_full(queue_t& queue)
{
return (queue->near+1) % queue->size == queue->front;
}
// 计算长度的时候有三种情况
// 第一种情况 length = front - near;
// 状态 near ... front
// 第二种情况 length = near - front
// 状态 front ... near
// 第三种情况 length = 0
// front
// near
// 可以合并为 abs(front-near)
// 也可以使用下面这个表达式来计算
int queue_length(queue_t& queue)
{
return (queue->near - queue->front + queue->size) % queue->size;
}
// 入队图示:
// 入队前
// front near
// ↓ ↓
// data -> [data] [data] [data] [data] ... [data]
//
// 入队后
// front near
// ↓ ↓
// data -> [data] [data] [data] [data] ... [data]
void queue_put(queue_t& queue, element_t e)
{
if (queue_is_full(queue))
{
int size = queue->size << 1;
queue->data = (element_t *)realloc(queue->data, sizeof(element_t) * size);
queue->size = size;
}
queue->data[queue->near] = e; // 放入数据
++queue->near; // 更新尾部指示器
queue->near %= queue->size; // 如果到缓冲区尾部,就回到缓冲区头
}
// 出队图示:
// 出队前
// front near
// ↓ ↓
// data -> [data] [data] [data] [data] ... [data]
//
// 入队后
// front near
// ↓ ↓
// data -> [data] [data] [data] [data] ... [data]
bool queue_get(queue_t& queue, element_t& e)
{
if (queue_is_empty(queue))
{
return false;
}
e = queue->data[queue->front]; // 取出数据
++queue->front; // 更新头部指示器
queue->front %= queue->size; // 如果到缓冲区尾部,就回到缓冲区头
}
void print(queue_t& queue)
{
int front = queue->front;
int near = queue->near;
while (front != near)
{
printf("%02d ", queue->data[front]);
++front;
front %= queue->size;
}
printf("\n");
}
int range(int a, int b)
{
return rand()%b + a;
}
int main()
{
int n = 1000;
int size = 10;
srand((unsigned)time(0));
while (n--)
{
printf("n=%d\n", n);
queue_t queue;
queue_init(queue);
int a = range(1, size);
while (a--)
{
int i = range(1, 10);
queue_put(queue, i);
print(queue);
}
int b = range(1, size);
while (b--)
{
element_t e;
if(!queue_get(queue, e))
{
if (queue_is_empty(queue))
{
break;
}
}
print(queue);
}
queue_destroy(queue);
}
return 0;
}
顺序队列的表示和实现
最新推荐文章于 2022-06-07 17:46:47 发布