数据结构之队列的实现
2016-02-16 15:21
531 查看
数据结构之队列的实现
队列是一种先进先出(First-IN First-OUT, FIFO)的结构,实现队列一般有两种方法,第一是使用链表的形式实现,另外一种是使用数组实现。下面分别以这两种方式实现数据结构中的队列。
一、 使用链表实现
队列一般就有下列几个函数:
void init_queue(queue_node *queue); //初始化队列
bool in_queue(queue_node *queue,queue_type value);//进队
bool queue_is_empty(queue_node *queue);//判断队列是否空
bool queue_is_full(queue_node *queue);//判断队列是否已满
queue_type out_queue(queue_node *queue);//出队
代码实现如下:
二、使用数组实现队列
使用数组实现队列,当有出队时,如果不把后面的数据向前移动,这样就会造成队列的容量越来越小,如果把后面的数据向前移动,就会造成很大开销;
解决这样个问题就是使用循环数组的形式,就是把队列的尾部环绕到数组的头部;这样当已出队删除的位置可以从新存储入队。
使用循环数组实现队列,又会引出另外一个问题,就是无法区别队列满与空,
当队列为满时如下所示:
当队列为满时,把队列中的元素都出列,那么队列就空了,为空时如下所示:
所以循环数组实现队列有无法识别队列满与队列空的现象,解决这一问题可以引入一个变量记录队列的元素,也可以牺牲队列中一个元素位置,来区分满与空,下面代码就是使用牺牲一个元素位置来区分的。
队列是一种先进先出(First-IN First-OUT, FIFO)的结构,实现队列一般有两种方法,第一是使用链表的形式实现,另外一种是使用数组实现。下面分别以这两种方式实现数据结构中的队列。
一、 使用链表实现
队列一般就有下列几个函数:
void init_queue(queue_node *queue); //初始化队列
bool in_queue(queue_node *queue,queue_type value);//进队
bool queue_is_empty(queue_node *queue);//判断队列是否空
bool queue_is_full(queue_node *queue);//判断队列是否已满
queue_type out_queue(queue_node *queue);//出队
代码实现如下:
#include<stdio.h> #include<stdlib.h> #include<stdbool.h> #define ITEMS_MAX 125 //队列最大的容量 typedef int queue_type; //队列数值的类型 /*队列节点*/ typedef struct _node { queue_type value; struct _node *next; }node; typedef struct _queue_node { node *front; node *rear; int items; //记录队列中项目的个数 }queue_node; int main(void) { unsigned char i; queue_type value; /*定义一个队列并初始化*/ queue_node q; init_queue(&q); /*in_queue*/ for(i=1; i<125; i++) { if(queue_is_full(&q)) { printf("queue is full\n"); exit(-1); } else { in_queue(&q,i); } } /*out_queue*/ for(i=1; i<125; i++) { if(queue_is_empty(&q)) { printf("queue is empty\n"); exit(-1); } else { value = out_queue(&q); printf("%d\n",value); } } } /*@brief Initialize a queue *@param queue:pointer to a queue_node structrue *@retval None */ void init_queue(queue_node *queue) { queue->front = NULL; queue->rear = NULL; queue->items = 0; } /*@brief queue up *@param queue_node:Pointer to a queue_node structrue * queue_type: *@retval None */ bool in_queue(queue_node *queue,queue_type pvalue) { node *pnew; pnew = (node*)malloc(sizeof(node)); if(pnew == NULL) { printf("create a new queue node false\n"); return false; } pnew->value = pvalue; pnew->next = NULL; if(queue_is_empty(queue)) //初次 { queue->front = pnew; queue->rear = pnew; } else { queue->rear->next = pnew; //链接到队尾尾端 queue->rear = pnew; //记录队尾尾端位置 } queue->items++; return true; } /*@brief whether the queue is empty *@param queue_node:Pointer to a queue_node structrue *@retval None */ bool queue_is_empty(queue_node *queue) { if(queue->items == 0) { return true; } else { return false; } } /*@brief whether the queue is full *@param queue_node:Pointer to a queue_node structrue *@retval None */ bool queue_is_full(queue_node *queue) { if(queue->items >= ITEMS_MAX) { return true; } else { return false; } } /*@brief queue out *@param queue_node:Pointer to a queue_node structrue *@retval None */ queue_type out_queue(queue_node *queue) { queue_type temp; node *p; if(queue_is_empty(queue)) { printf("The queue is empty\n"); exit(-1); } temp = queue->front->value; p = queue->front; queue->front = queue->front->next; free(p); queue->items--; if(queue->items == 0) { queue->rear = NULL; } return temp; }
二、使用数组实现队列
使用数组实现队列,当有出队时,如果不把后面的数据向前移动,这样就会造成队列的容量越来越小,如果把后面的数据向前移动,就会造成很大开销;
解决这样个问题就是使用循环数组的形式,就是把队列的尾部环绕到数组的头部;这样当已出队删除的位置可以从新存储入队。
使用循环数组实现队列,又会引出另外一个问题,就是无法区别队列满与空,
当队列为满时如下所示:
当队列为满时,把队列中的元素都出列,那么队列就空了,为空时如下所示:
所以循环数组实现队列有无法识别队列满与队列空的现象,解决这一问题可以引入一个变量记录队列的元素,也可以牺牲队列中一个元素位置,来区分满与空,下面代码就是使用牺牲一个元素位置来区分的。
#include<stdio.h> #include<stdlib.h> #include<stdbool.h> //队列容量大小,实质是100-1,一个位置空出用于区分队列满与空 #define QUEUE_DEEP 100 typedef unsigned char queue_type; //队列数值类型 typedef struct _queue_msg { queue_type buffer[QUEUE_DEEP]; unsigned char front; unsigned char rear; }queue_msg; /*定义并初始化一个队列*/ queue_msg queue= { .front = 1, .rear = 0, }; bool queue_is_empty(queue_msg *queue); bool queue_is_full(queue_msg *queue); bool in_queue(queue_msg *queue,queue_type value); queue_type out_queue(queue_msg *queue); int main(void) { unsigned char i; queue_type value; /*in_queue*/ for(i=1; i<=99; i++) { in_queue(&queue,i); } /*out_queue*/ for(i=1; i<=99; i++) { value = out_queue(&queue); printf("%d\n",value); } value = out_queue(&queue); } bool in_queue(queue_msg *queue,queue_type value) { if(queue_is_full(queue)) { printf("The queue is fulled\n"); exit(-1); } else { //等价与 queue->rear = (queue->rear+1)%QUEUE_DEEP; queue->rear++; if(queue->rear >= QUEUE_DEEP) { queue->rear = 0; } queue->buffer[queue->rear] = value; } return true; } queue_type out_queue(queue_msg *queue) { queue_type temp; if(queue_is_empty(queue)) { printf("The queue is empty\n"); exit(-1); } else { //等价与 queue->front = (queue->front+1)%QUEUE_DEEP temp = queue->buffer[queue->front]; queue->front++; if(queue->front >= QUEUE_DEEP) { queue->front = 0; } } return temp; } //判断队列是否空 bool queue_is_empty(queue_msg *queue) { return ((queue->rear+1)%QUEUE_DEEP == queue->front); } //判断队列是否满 bool queue_is_full(queue_msg *queue) { return ((queue->rear+2)%QUEUE_DEEP == queue->front); }
相关文章推荐
- 跟我学数据结构之栈和队列
- AVL树-scala实现
- 数据结构(陈越)-网易云课堂 第一周编程题
- 【数据结构】链表中倒数第k个结点
- 高级数据结构 - 线段树(2)
- 高级数据结构 - 线段树(1)
- 逆序对 - 树状数组求解 - 高级数据结构
- 数据结构学习笔记——树的概念
- 数据结构实验报告单链表的基本操作
- 基础数据结构之数组与链表(五)
- 数据结构和算法
- 数据结构及算法
- 二叉树的构建,线索化,以及线索二叉树的遍历c++语言表示(《数据结构》算法6.5,6.6,6.7)
- 数据结构之动态数组实现
- 数据结构和算法
- 学习笔记------数据结构(C语言版) 串的模式匹配
- 【数据结构学习笔记】——霍夫曼编码
- 关于编码-解码
- 折半查找法
- 【数据结构】旋转数组中的最小数字