队列是一种特殊的线性表,队列是一种先进先出(FIFO)队列。仅在线性表的两端进行操作,一头插入数据(队尾),一头去除数据(队头),不允许在中间部位进行插入删除操
作。队列是一种特殊的线性表,可以用线性表的顺序存储和链式存储模拟队列的顺序存储和链式存储。首先,我们先模拟队列的链式存储。用链表(线性表的链式存储)来模拟队
列的顺序存储,需要限链表的操作。入队列相当于从链表的尾部插入,出队列相当于从链表的头部删除元素。
借助于我们之前实现的链表操作,在工程中再加入如下文件:
linkqueue.h
#ifndef _MY_LINKQUEUE_H_
#define _MY_LINKQUEUE_H_
typedef void LinkQueue;
LinkQueue* LinkQueue_Create();
void LinkQueue_Destroy(LinkQueue* queue);
void LinkQueue_Clear(LinkQueue* queue);
int LinkQueue_Append(LinkQueue* queue, void* item);
void* LinkQueue_Retrieve(LinkQueue* queue);
void* LinkQueue_Header(LinkQueue* queue);
int LinkQueue_Length(LinkQueue* queue);
#endif //_MY_LINKQUEUE_H_
linkqueue.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include<stdio.h>
#include <string.h>
#include "linklist.h"
#include "linkqueue.h"
//添加如下结构体 包含链表节点LinkListNode和队列业务节点item
typedef struct _tag_LinkQueueNode
{
LinkListNode node;
void* item;
}TLinkQueueNode;
//创建队列 相等于创建链表
LinkQueue* LinkQueue_Create()
{
return LinkList_Create();
}
//销毁
void LinkQueue_Destroy(LinkQueue* queue)
{
LinkQueue_Clear(queue);
LinkList_Destroy(queue) ;
}
//如果清空队列 需要显示地把队列的所有节点 出队列
//释放每一个结点 因为结点都是malloc出来的
//结点生命周期管理
void LinkQueue_Clear(LinkQueue* queue)
{
if (queue==NULL)
{
printf("queue=NULL\n");
return;
}
while (LinkList_Length(queue)>0)
{
LinkQueue_Retrieve(queue);
}
LinkList_Clear(queue);
}
//向队列添加元素 相等于向链表尾部插入元素
//每向队列添加一个结点 就malloc一个
int LinkQueue_Append(LinkQueue* queue, void* item)
{
TLinkQueueNode* tmp = NULL;
int ret = 0;
tmp = (TLinkQueueNode*)malloc(sizeof(TLinkQueueNode));
if (tmp == NULL)
{
ret= -1;
printf("func LinkQueue_Append() err :malloc(sizeof(TLinkQueueNode))\n");
return ret;
}
memset(tmp,0,sizeof(TLinkQueueNode));//做一个负责人的程序员
//tmp->node.next = NULL;
//tmp->item = NULL;
tmp->item = item;
//需要把队列的业务节点item转化成链表的LinkListNode
//这个地方节点类型转化要细细体会!!!!!
ret = LinkList_Insert(queue,(LinkListNode*)tmp,LinkList_Length(queue));
if (ret !=0)
{
printf("func LinkList_Insert() err:%d\n",ret);
if (tmp!=NULL)
{
free(tmp);
}
return ret;
}
return ret;
}
//从队列删除元素(出队列) 相当于从链表头部删除一个元素
void* LinkQueue_Retrieve(LinkQueue* queue)
{
void *ret;
TLinkQueueNode* tmp = NULL;
tmp = (TLinkQueueNode*)LinkList_Delete(queue,0);
if (tmp==NULL)
{
printf("func LinkList_Delete() err:\n");
return NULL;
}
//释放前 缓存 以便返回
ret = tmp->item;
free(tmp);
return ret;
}
//获取队头 相当于从链表头部取数据
void* LinkQueue_Header(LinkQueue* queue)
{
void *ret;
TLinkQueueNode* tmp = NULL;
tmp = (TLinkQueueNode*)LinkList_Get(queue,0);
if (tmp==NULL)
{
printf("func LinkList_Get() err:\n");
return NULL;
}
ret = tmp->item;
return ret;
}
int LinkQueue_Length(LinkQueue* queue)
{
return LinkList_Length(queue);
}
test.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include<stdio.h>
#include <string.h>
#include "linklist.h"
#include "linkqueue.h"
int main()
{
LinkQueue *queue = NULL;
int i,a[6];
queue = LinkQueue_Create();
if (queue == NULL)
{
return;
}
for (i = 0;i<6;i++)
{
a[i] = i+1;
LinkQueue_Append(queue,&a[i]);
}
printf("len :%d\n",LinkQueue_Length(queue));
printf("header:%d\n",*((int*)LinkQueue_Header(queue)));
while (LinkQueue_Length(queue)>0)
{
int *tmp ;
tmp = (int*)LinkQueue_Retrieve(queue);
printf("tmp:%d\n",*tmp);
}
LinkQueue_Destroy(queue);
system("pause");
return 0;
}