通用循环队列的实现

通用循环队列,这儿是我的笔记,希望大家可以友好交流!!谢谢#__#

有好几天没写了,一直和朋友玩,都没空看了。

今天得空写了一下队列的实现,还是和之前一样,有链表的方式和数组的方式两种。

先是数组的形式吧,队列结构:

struct XHqueue
{
    int capacity;//由用户来定义容量大小
    int len_queue;
    int front;
    int rear;
    OPERATE callback;
    void ** data;
};

队列一般实现为循环的,即有固定大小的,可以节省空间。这里仍然像实现栈那样,先动态分配一片固定大小的空间给队列。

数组式的实现接口如下:

#include<stdlib.h>
#include<stdio.h>
#include<memory.h>
typedef (*OPERATE)();
typedef enum
{
    false = 0,
    true,
}bool;
struct XHqueue;
typedef struct XHqueue XHQUEUE;
typedef struct XHqueue* XHQUEUE_T;

XHQUEUE_T Queue_Init(XHQUEUE_T Que,int N);
bool Queue_IsEmpty(const XHQUEUE_T Que);
bool Queue_IsFull(const XHQUEUE_T);
void* Queue_Front(const XHQUEUE_T Que);//直插询
bool Queue_DeQueue(XHQUEUE_T Que, OPERATE op, void** data);
bool Queue_EnQueue(XHQUEUE_T Que,void* data);
bool Queue_DeleteAll(XHQUEUE_T Que,OPERATE op, void** data);
int Queue_GetCapacity(XHQUEUE_T Que);
int Queue_GetLen(XHQUEUE_T Que);
#endif 

XHQUEUE_T Queue_Init(XHQUEUE_T Que,int N);
队列初始化时将front指向0,rear指向-1,因为每次入列前rear先加1;
bool Queue_IsEmpty(const XHQUEUE_T Que);
判空函数,判断标志由len是否为0(因为每次入列是len+1,出列时len-1)
bool Queue_IsFull(const XHQUEUE_T);
判满函数,capacity和len是否相等
void* Queue_Front(const XHQUEUE_T Que);
只查询队首元素
bool Queue_DeQueue(XHQUEUE_T Que, OPERATE op, void** data);
出队列函数,其实就是front+1;
bool Queue_EnQueue(XHQUEUE_T Que,void* data);
入队函数
bool Queue_DeleteAll(XHQUEUE_T Que,OPERATE op, void** data);
删除整个队列,包括队列结构
int Queue_GetCapacity(XHQUEUE_T Que);
int Queue_GetLen(XHQUEUE_T Que);

接着实现的接口

#include"tongyongxunhuanduilie.h"
struct XHqueue
{
    int capacity;//由用户来定义
    int len_queue;
    int front;
    int rear;
    OPERATE callback;
    void ** data;
};
XHQUEUE_T Queue_Init(XHQUEUE_T Que,int N)
{
    Que = (XHQUEUE_T)malloc(sizeof(XHQUEUE));
    if(Que == NULL) return NULL;
    Que->data = (void**)malloc(sizeof(void*)*N);
    if(Que->data==NULL)
    {
        free(Que);
        return NULL;
    }
    else
    {
        Que->capacity = N;
        Que->len_queue = 0;
        Que->front = 0;
        Que->rear = -1;
        Que->callback = NULL;
        return Que;
    }
}
bool Queue_IsEmpty(const XHQUEUE_T Que)
{
    if(Que == NULL) exit(0);
    return Que->len_queue == 0 ? true : false;
}
bool Queue_IsFull(const XHQUEUE_T Que)
{
    /**因为入队就+1,出队就减1,所以用size来*/
    return Que->len_queue == Que->capacity ? true :false;
}
void* Queue_Front(const XHQUEUE_T Que)//只查询
{
    if(Queue_IsEmpty(Que)) return NULL;
    return Que->data[Que->front];
}
bool Queue_DeQueue(XHQUEUE_T Que, OPERATE op, void** data)
{
    if(Queue_IsEmpty(Que)) return false;
    if(op != NULL && data != NULL)
    {
        *data = Que->data[Que->front];
        Que->callback = op;
        Que->callback(*data);
    }
    Que->front = (Que->front++)%Que->capacity;
    Que->len_queue--;
    return true;
}

bool Queue_EnQueue(XHQUEUE_T Que,void* data)
{
    if(Queue_IsFull(Que)) return false;
    Que->rear =(Que->rear++)%Que->capacity;
    Que->data[Que->rear] = data;
    Que->len_queue++;
    return true;
}
bool Queue_DeleteAll(XHQUEUE_T Que,OPERATE op, void** data)
{
    while(!Queue_IsEmpty(Que))
    {
        Queue_DeQueue(Que,op,data);
    }
    free(Que->data);
    Que->data = NULL;
    free(Que);
    Que= NULL;
    return true;
}
int Queue_GetCapacity(XHQUEUE_T Que)
{
    if(Que == NULL) exit(0);
    return Que->capacity;
}
int Queue_GetLen(XHQUEUE_T Que)
{
    if(Que == NULL) exit(0);
    return Que->len_queue;
}

以上是数组式的队列,我们还可以实现为链式循环队列
队列结构

struct node
{
    void *data;
    struct node* next;
};
struct XHqueue
{
    int capacity;
    int len;
    struct node* front;
    struct node* tail;
};

注意实现是带有头结点和尾结点(即这两个结点实际上是不存储data的,方便队列操作和实现的,所以容量实际比最大有效长度多2 ),因此,在访问队首元素是也是要用front->next来访问。
接口:

typedef (*OPERATE)();
typedef enum
{
    false = 0,
    true,
}bool;
struct node;
typedef struct node NODE;
typedef struct node* NODE_T;

struct Queue;
typedef struct XHqueue XHQUEUE;
typedef struct XHqueue* XHQUEUE_T;

XHQUEUE_T Queue_Init(XHQUEUE_T Que,int N);
bool Queue_IsEmpty(const XHQUEUE_T Que);
bool Queue_IsFull(const XHQUEUE_T);
void* Queue_Front(const XHQUEUE_T Que);
bool Queue_DeQueue(XHQUEUE_T Que, OPERATE op, void** data);
bool Queue_EnQueue(XHQUEUE_T Que,void* data);
bool Queue_DeleteAll(XHQUEUE_T Que,OPERATE op, void** data);
int Queue_GetCapacity(XHQUEUE_T Que);
int Queue_GetLen(XHQUEUE_T Que);
NODE_T Que_NodePOrevious(XHQUEUE_T Que,NODE_T nd);
#endif

功能从函数名称可以看出,还有具体的细节和前面几篇文章其实是相同的,所以直接上实现

#include"tongyongxunhuanlianshi.h"
struct node
{
    void *data;
    struct node* next;
};
/**发现还是要带头尾部节点比较好*/
struct XHqueue
{
    int capacity;
    int len;
    struct node* front;
    struct node* tail;
};
XHQUEUE_T Queue_Init(XHQUEUE_T Que,int N)
{
    if(N<0) return NULL;
    Que = (XHQUEUE_T)malloc(sizeof(struct XHqueue));
    if(Que==NULL) return NULL;
    Que->capacity = N;
    Que->len = 0;
    Que->front = (NODE_T)malloc(sizeof(NODE));
    Que->tail = (NODE_T)malloc(sizeof(NODE));
    if(Que->front == NULL ||Que->tail == NULL)
    {
        free(Que);
        Que = NULL;
        return NULL;
    }
    Que->front->next = Que->tail;
    Que->tail->next = Que->front;

    Que->front->data = NULL;
    Que->tail->data = NULL;
    Que->len = 0 ;
    return Que;


}
bool Queue_IsEmpty(const XHQUEUE_T Que)
{
    if(Que == NULL) return false;
   return Que->front->next== Que->tail&&Que->tail->next== Que->front ? true : false;


}
bool Queue_IsFull(const XHQUEUE_T Que)
{
    if(!Queue_IsEmpty(Que))
    {
        return Que->len >= Que->capacity ? true : false;
    }
    return false;
}
void* Queue_Front(const XHQUEUE_T Que)
{
    if(Queue_IsEmpty(Que)) NULL;
    return Que->front->next->data;
}
bool Queue_DeQueue(XHQUEUE_T Que, OPERATE op, void** data)
{
    NODE_T tmp = NULL;
    if(Queue_IsEmpty(Que)) return false;

    tmp = Que->front->next;
    Que->front->next = tmp->next;
    if(op!=NULL&&data!=NULL)
    {
        *data = tmp->data;
        op(*data);
    }
    free(tmp);
    tmp = NULL;
    Que->len--;
    return true;
}
bool Queue_EnQueue(XHQUEUE_T Que,void* data)
{
    NODE_T newnode = (NODE_T)malloc(sizeof(NODE));
    NODE_T pre = NULL;
    if(newnode==NULL) return false;
    newnode->data = data;
    newnode->next = NULL;
    if(Queue_IsFull(Que))
    {
            free(newnode);
            newnode = NULL;
            return false;
    }
    else
    {
            pre = Que_NodePOrevious(Que,Que->tail);
            newnode->next = Que->tail;
            pre->next = newnode;
            Que->len++;
                return true;
    }
}

NODE_T Que_NodePOrevious(XHQUEUE_T Que,NODE_T nd)
{
    NODE_T Head;
    if(Que==NULL) return NULL;
    Head = Que->front;
    while(Head->next != Que->front)
    {
        if(Head->next == nd) return Head;
        Head = Head->next;
    }
    if(Head->next != Que->front) return NULL;
}
bool Queue_DeleteAll(XHQUEUE_T Que,OPERATE op, void** data)
{
    if(Que == NULL) return false;
    while(!Queue_IsEmpty(Que))
    {
        Queue_DeQueue(Que,op,data);
        if(Queue_IsEmpty(Que)) break;
    }
    if(op!=NULL&&data!=NULL)
    {
        *data = Que->tail->data;
        op(*data);

        *data = Que->front->data;
        op(*data);
    }
        free(Que->tail);
        free(Que->front);
        free(Que);
        Que=NULL;
        return true;
}
int Queue_GetCapacity(XHQUEUE_T Que)
{
    if(Que == NULL) exit(0);
    return Que->capacity;
}
int Queue_GetLen(XHQUEUE_T Que)
{
    if(Que == NULL) exit(0);
    return Que->len;
}

至此就完成两种方式的实现了!(线性数据结构终于看完了^_^)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值