队列:
队列是一种特殊的线性表,只能在两端进行操作
队头:取出数据的一端
队尾: 插入数据的一端
先进先出
操作:
创建
销毁
清空
入队
出队
获取队头
栈的实现:
//queue.h
#ifndef __LINKQUEUE_H__
#define __LINKQUEUE_H__
typedef struct linkqueuenode
{
struct linkqueuenode *next;
void *item;
}LinkQueueNode; //队节点
typedef struct linkqueue
{
//在队头中定义两个指针的好处在于效率高,可以同时指向第一个和最后一个,可以很快找到我们,和插入,删除节点
LinkQueueNode *front; //一直指向第一个节点
LinkQueueNode *rear; //指向对后一个节点
int length;
}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 //__LINKQUEUE_H__
//queue.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "queue.h"
LinkQueue *LinkQueue_Create()
{
LinkQueue *ret = NULL;
ret = malloc(sizeof(LinkQueue));
if(ret!=NULL)
{
ret->length = 0;
ret->front = NULL;
ret->rear = NULL;
}
return ret;
}
void LinkQueue_Destroy(LinkQueue *queue)
{
LinkQueue_Clear(queue);
free(queue);
}
void LinkQueue_Clear(LinkQueue *queue)
{
while ( LinkQueue_Length(queue) > 0 )
{
LinkQueue_Retrieve(queue);
}
}
//入队
int LinkQueue_Append(LinkQueue *queue,void *item)
{
LinkQueueNode *node = malloc(sizeof(LinkQueueNode));
int ret = queue!=NULL && item!=NULL && node!=NULL;
if(ret) //初始化
{
node->item = item; //指向item传过来的数据
node->next = NULL;
if( queue->length > 0 ) //有节点的时候,
{
queue->rear->next = node; //rear一直在变动
queue->rear = node; //一直指向最后一个节点
}
else //没有节点的时候
{
queue->front =node; //front一直指向队列0位置
queue->rear = node;
}
queue->length++;
}
if( !ret )
free(node);
return ret;
}
//出队
void *LinkQueue_Retrieve(LinkQueue *queue)
{
LinkQueueNode *node = NULL;
void *item = NULL;
if( queue != NULL && queue->length > 0 )
{
node = queue->front;
item = node->item; //这是别人的东西,我们不许要去管他,
queue->front = node->next;
free(node); //释放的时候只释放我们申请的空间node
//在释放之前我们要把item保存起来
queue->length--;
if( queue->length == 0 )
{
queue->front = NULL;
queue->rear =NULL;
}
}
return item;
}
//队头
void *LinkQueue_Header(LinkQueue *queue)
{
void *item = NULL;
if( queue!=NULL && queue->length > 0 )
{
item = queue->front->item;
}
return item;
}
int LinkQueue_Length(LinkQueue *queue)
{
int ret = -1;
if( queue!=NULL )
{
ret = queue->length;
}
return ret;
}
//main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "queue.h"
int main( void )
{
LinkQueue *queue = LinkQueue_Create();
int i;
int a[5] = {11,22,33,44,55};
for(i=0; i<5; i++)
{
LinkQueue_Append(queue, a+i);
}
while ( LinkQueue_Length(queue) > 0 )
{
printf("%d ",*(int *)LinkQueue_Retrieve(queue));
}
printf("\n");
LinkQueue_Destroy(queue);
return 0;
}
Makefile
CC=gcc
main:queue.o main.o
$(CC) $^ -o $@
.PHANY: main clean
clean:
rm -rf *.o main
上面这个队列比下面用链表实现的这个队列效率要高点,因为他在头节点中定义了两个指针,一个指向第一个节点,一个一直都指向最后一个节点,这样,无论是插入还是删除,查找都提高了效率。
用链表来实现队列:
//linklist.h
#ifndef __LINKLIST_H__
#define __LINKLIST_H__
typedef struct linklistnode
{
struct linklistnode *next;
int item;
}LinkListNode; //数据节点
typedef struct linklist
{
LinkListNode header;
int length;
}LinkList; //头节点
LinkList *LinkList_Create();
void LinkList_Destroy(LinkList *list);
void LinkList_Clear(LinkList *list);
int LinkList_Length(LinkList *list);
int LinkList_Insert(LinkList *list, LinkListNode *node, int pos);
LinkListNode *LinkList_Get(LinkList *list,int pos);
LinkListNode *LinkList_Delete(LinkList *list,int pos);
#endif //__LINKLIST_H__
//linklist.c
#include <stdlib.h>
#include "linklist.h"
LinkList *LinkList_Create()
{
LinkList *ret = NULL;
ret = malloc(sizeof(LinkList));
if(ret!=NULL)
{
ret->length = 0;
ret->header.next = NULL;
}
return ret;
}
void LinkList_Destroy(LinkList *list)
{
free(list);
}
void LinkList_Clear(LinkList *list)
{
if(list!=NULL)
{
list->length =0;
list->header.next = NULL;
}
}
int LinkList_Length(LinkList *list)
{
int ret = -1;
if( list!=NULL )
{
ret = list->length;
}
return ret;
}
int LinkList_Insert(LinkList *list, LinkListNode *node, int pos)
{
int ret = list!=NULL && node!=NULL && pos>=0;
if( ret )
{
int i;
LinkListNode *cur = (LinkListNode *)list;
for(i=0;i<pos && cur->next!=NULL;i++)
{
cur = cur->next;
}
node->next = cur->next;
cur->next = node;
list->length++;
}
return ret;
}
LinkListNode *LinkList_Get(LinkList *list,int pos)
{
LinkListNode *ret = NULL;
if( list!=NULL && (0<=pos && pos<list->length) )
{
int i;
LinkListNode *cur = (LinkListNode *)list;
for(i=0; i<pos; i++)
cur = cur->next;
ret = cur->next; //因为从0开始计数的,要第三个数,那么就是第二个数的next
}
return ret;
}
LinkListNode *LinkList_Delete(LinkList *list,int pos)
{
LinkListNode *ret = NULL;
if(list!=NULL && (0<=pos&&pos<list->length) )
{
int i;
LinkListNode *cur = (LinkListNode *)list;
for(i=0; i<pos; i++)
cur = cur->next;
ret = cur->next; //单项链表是从0开始排的。
cur->next = ret->next;
list->length--;
}
return ret;
}
//linkqueue.h
#ifndef __LINKQUEUE_H__
#define __LINKQUEUE_H__
typedef void LinkQueue;
typedef struct linkqueuenode
{
struct linkqueuenode *next;
void *item;
}LinkQueueNode;
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 //__LINKQUEUE_H__
//linkqueue.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "linklist.h"
#include "linkqueue.h"
LinkQueue *LinkQueue_Create()
{
return LinkList_Create();
}
void *LinkQueue_Destroy(LinkQueue *queue)
{
LinkQueue_Clear(queue);
LinkList_Destroy(queue);
}
void *LinkQueue_Clear(LinkQueue *queue)
{
while ( LinkQueue_Length(queue) > 0 )
LinkQueue_Retrieve(queue); //出队
}
//入队
int LinkQueue_Append(LinkQueue *queue, void *item)
{
int ret;
LinkQueueNode *node = malloc(sizeof(LinkQueueNode));
memset(node, 0x00, sizeof(*node));
ret = queue!=NULL && item!=NULL && node!=NULL;
if( ret )
{
node->item = item;
node->next = NULL;
ret = LinkList_Insert(queue, (LinkListNode *)node, LinkList_Length(queue));
}
return ret;
}
//出队
void *LinkQueue_Retrieve(LinkQueue *queue)
{
LinkQueueNode *node = (LinkQueueNode *)LinkList_Delete(queue, 0);
void *ret = NULL;
if( queue!=NULL && node!=NULL )
{
ret = node->item;
}
return ret;
}
//求队头
void *LinkQueue_Header(LinkQueue *queue)
{
LinkQueueNode *node = (LinkQueueNode *)LinkList_Get(queue, 0);
void *ret = NULL;
if( queue!=NULL && node!=NULL )
{
ret = node->item;
}
return ret;
}
//队长
int LinkQueue_Length(LinkQueue *queue)
{
int ret = -1;
if( queue!=NULL )
{
ret = LinkList_Length(queue);
}
return ret;
}
//main.c
#include <stdio.h>
#include <stdlib.h>
#include "linkqueue.h"
int main( void )
{
LinkQueue *queue = LinkQueue_Create();
int a[4] = {11,22,33,44};
int i = 0;
for (i=0; i<4; i++)
{
LinkQueue_Append(queue, a+i);
}
while( LinkQueue_Length(queue) > 0 )
{
int *p = (int *)LinkQueue_Retrieve(queue);
printf("%d ",*p);
}
printf("\n");
LinkQueue_Destroy(queue);
}
Makefile
cc :=gcc
main : main.o linklist.o linkqueue.o
gcc $^ -o $@
.PHONY : main clean
clean:
rm -rf *.o main