嵌入式学习之路(二十一)——数据结构(3)
一。数据结构的实现----队列
1) 基本特征:先进先出——FIFO。
2) 基本操作:压入(push)、弹出(pop)。
3) 实现要点:初始化空间、前指针front弹出后指针rear压入、循环使用、判空判满。
我们来用链表来实现一下队列
/*************************************************
**
** 文件名称:ql_test.c
** 文件功能:测试链表的队列是否正确
** 文件作者:紫瞳标
** 文件时间:2014-1-8
**
*************************************************/
#include <stdio.h>
#include "ql.h"
int main()
{
QUEUE queue;/*定义一个队列*/
queue_init(&queue);/*初始化队列*/
int i = 0;
/*写入队列*/
for(i = 0;i < 10;i++)
{
queue_push(&queue,i);
}
printf("size = %u\n",queue_size(&queue));
while(! queue_empty(&queue))/*非空则继续*/
{
printf("%d\n",queue_pop(&queue));
}
queue_deinit(&queue);/*清空队列*/
return 0;
}
/*************************************************
**
** 文件名称:ql.c
** 文件功能:用链表实现队列
** 文件作者:紫瞳标
** 文件时间:2014-1-8
**
*************************************************/
#include <stdlib.h>
#include "ql.h"
/*************************************************
**
** 函数名称:create_node()
** 函数功能:创建新的节点
** 形式参数:该节点的数据
** 返回值 :创建的新节点的指针
**
*************************************************/
static QUEUE_NODE *create_node (int data)
{
QUEUE_NODE *node = malloc(sizeof(QUEUE_NODE));
node->data = data;
node->next = NULL;/*队列是先进先出的,新加的在后面*/
return node;
}
/*************************************************
**
** 函数名称:destroy_node()
** 函数功能:删除节点
** 形式参数:该节点的数据
** 返回值 :节点的下一下指针
**
*************************************************/
static QUEUE_NODE *destroy_node (QUEUE_NODE *node)
{
QUEUE_NODE *next = node->next;
free(node);
return next;/*返回的是后节点的指针,因为删除的front指针指向的节点*/
}
/*************************************************
**
** 函数名称:queue_init()
** 函数功能:初始化队列
** 形式参数:队列指针
** 返回值 :无
**
*************************************************/
void queue_init(QUEUE *queue)
{
queue->front = NULL;
queue->rear = NULL;
}
/*************************************************
**
** 函数名称:queue_deinit()
** 函数功能:释放剩余节点,恢复到初始状态的队列
** 形式参数:队列指针
** 返回值 :无
**
*************************************************/
void queue_deinit(QUEUE *queue)
{
while(queue->front)
{
queue->front = destroy_node(queue->front);
/*这边最后会把front置空*/
}
queue->rear = NULL;/*防止野指针*/
}
/*************************************************
**
** 函数名称:queue_empty()
** 函数功能:判断是否是空
** 形式参数:队列指针
** 返回值 :1 - 空的队列
**
*************************************************/
int queue_empty(QUEUE *queue)
{
return ! queue->front && ! queue->rear;
}
/*************************************************
**
** 函数名称:queue_push()
** 函数功能:压入一个数据
** 形式参数:队列指针,压入的数据
** 返回值 :无
**
*************************************************/
void queue_push(QUEUE *queue,int data)
{
QUEUE_NODE *new = create_node(data);
/*非空队列*/
if(queue->rear)
{
queue->rear->next = new;
}
/*空的队列*/
else
{
queue->front = new;
}
queue->rear = new;
}
/*************************************************
**
** 函数名称:queue_pop()
** 函数功能:弹出一个节点
** 形式参数:队列指针
** 返回值 :弹出的数据
**
*************************************************/
int queue_pop(QUEUE *queue)
{
int data = queue->front->data;
/*如果删除的是最后一个节点*/
if(!(queue->front = destroy_node(queue->front)))
{
queue->rear = NULL;/*rear也要防止变成野指针*/
}
return data;
}
/*************************************************
**
** 函数名称:queue_front()
** 函数功能:取出队首的数据
** 形式参数:队列指针
** 返回值 :取出数据,但不弹出
**
*************************************************/
int queue_front(QUEUE *queue)
{
return queue->front->data;
}
/*************************************************
**
** 函数名称:queue_size()
** 函数功能:队列中数据个个数
** 形式参数:队列指针
** 返回值 :个数
**
*************************************************/
size_t queue_size(QUEUE *queue)
{
size_t size = 0;
QUEUE_NODE *node = NULL;
for(node = queue->front;node;node = node->next)
{
++size;
}
return size;
}
/*************************************************
**
** 文件名称:ql.h
** 文件功能:ql.c的头文件
** 文件作者:紫瞳标
** 文件时间:2014-1-8
**
*************************************************/
#ifndef _QL_H
#define _QL_H
#include <sys/types.h>
/*节点*/
typedef struct QueueNode {
int data;/*数据*/
struct QueueNode *next;/*后指针*/
} QUEUE_NODE;
/*队列*/
typedef struct Queue {
QUEUE_NODE *front;/*前端*/
QUEUE_NODE *rear;/*后端*/
} QUEUE;
void queue_init(QUEUE *);/*初始化队列为空队列*/
void queue_deinit(QUEUE *);/*是放剩余节点并回复到初始状态*/
int queue_empty(QUEUE *);/*判断是否是空队列*/
void queue_push(QUEUE *,int);/*压入一个数*/
int queue_pop(QUEUE *);/*弹出一个数*/
int queue_front(QUEUE *);/*取出队首的数据*/
size_t queue_size(QUEUE *);/*得到队列的数据个数*/
#endif/*_QL_H*/
makefile如下
ql:ql.o ql_test.o
gcc ql.o ql_test.o -o ql
ql.o:
gcc -c ql.c
ql_test.o:
gcc -c ql_test.c
clean:
rm ql.o ql_test.o ql