队列的实现

队列:

队列是一种特殊的线性表,只能在两端进行操作
队头:取出数据的一端
队尾: 插入数据的一端
先进先出

操作:

创建
销毁
清空
入队
出队
获取队头

栈的实现:

//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

用栈来实现队列:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值