数据结构-顺序队列和链式队列的实现

上篇博客说的栈是操作受限制的线性表,同样的,队列也是操作受限制的线性表,不同于栈,它的头和尾两头都受限制,只能在一端进行插入(只进不出),我们称为队尾,在另一端进行删除(只出不进),称作队首。
遵循的原则是:”先进先出“(first in first out),简称”FIFO”.我们生活中的排队现象就是队列的一种应用,先来的人先进入队伍亦先买到东西离开,即先进先出。
队列也有顺序和链式两种存储结构。
1.顺序队列的实现
顺序存储如图:
这里写图片描述
顺序存储的存储空间是静态分配的,所以有可能没有剩余空间的情况,用循环列表可以解决这一问题。
头文件声明:

seqqueue.h
#pragma once

#include<stddef.h>

#define SeqQueueMaxSize 1000//队列的最大长度
typedef char SeqQueueType;
typedef struct SeqQueue
{
    SeqQueueType data[SeqQueueMaxSize];
    size_t head;
    size_t tail;
    size_t size;
}SeqQueue;

void SeqQueueInit(SeqQueue* q);//初始化

void SeqQueueDestroy(SeqQueue* q);//销毁

void SeqQueuePush(SeqQueue* q,SeqQueueType value);//入队列

void SeqQueuePop(SeqQueue* q);//出队列

int SeqQueueFront(SeqQueue* q,SeqQueueType* value);//取队首元素

具体实现及测试代码:

seqqueue.c
#include"seqqueue.h"

void SeqQueueInit(SeqQueue* q)
{
    if(q == NULL)
    {
        return;    //非法输入
    }
    q->head = 0;
    q->tail= 0;
    q->size = 0;
    return;
}

void SeqQueueDestroy(SeqQueue* q)
{
    if(q == NULL)
    {
        return; //非法输入
    }
    q->head = 0;
    q->tail = 0;
    q->size = 0;
}

void SeqQueuePush(SeqQueue* q,SeqQueueType value)
{
    if(q == NULL)
    {
        return;//非法输入
    }
    if(q->size >= SeqQueueMaxSize)
    {
        return;//队列已满
    }
    q->data[q->tail++] = value;//将value赋给tail指向的位置,tail指向它的下一个位置

    if(q->tail == SeqQueueMaxSize)//如果尾指针指向的位置大于队列最大容量,则将它指向下标为0的位置
    {
        q->tail = 0;
    }
    q->size++;
}

void SeqQueuePop(SeqQueue* q)
{
    if(q == NULL)
    {
        return;//非法输入
    }
    if(q->size == 0)
    {
        return;//空列表
    }
    ++q->head;

    if(q->head == SeqQueueMaxSize)
    {
        q->head = 0;
    }
    --q->size;
    return;
}

int SeqQueueFront(SeqQueue* q,SeqQueueType* value)
{
    if(q == NULL||value == NULL)
    {
        return 0;//非法输入
    }
    if(q->size == 0)
    {
        return 0;//空队列
    }
    *value = q->data[q->head];
    return 1;
}
////////////////////////////////////////
/////////以下是测试代码////////////////
///////////////////////////////////////
#if 1
#include<stdio.h>
#define TEST_HEADER printf("\n==================%s================\n",__FUNCTION__)
void TestQueue()
{
    TEST_HEADER;
    SeqQueue queue;
    SeqQueueInit(&queue);
    SeqQueuePush(&queue,'a');
    SeqQueuePush(&queue,'b');
    SeqQueuePush(&queue,'c');
    SeqQueuePush(&queue,'d');

    SeqQueueType value;
    int ret = SeqQueueFront(&queue,&value);
    printf("ret expected 1,actual %d\n",ret);
    printf("value expected a,actual %c\n",value);

    SeqQueuePop(&queue);
    SeqQueuePop(&queue);
    ret = SeqQueueFront(&queue,&value);
    printf("ret expected 1,actual %d\n",ret);
    printf("value expected c,actual %c\n",value);

    SeqQueuePop(&queue);
    SeqQueuePop(&queue);
    ret = SeqQueueFront(&queue,&value);
    printf("ret expected 0,actual %d\n",ret);

}
int main()
{
    TestQueue();
    printf("\n");
    return 0;
}
#endif

2.链式队列的实现
头文件声明:

linkqueue.h
#pragma once

#include<stddef.h>

typedef char LinkType;

typedef struct LinkNode
{
    LinkType data;
    struct LinkNode* next;
}LinkNode;

typedef struct LinkQueue
{
    LinkNode* head;
    LinkNode* tail;
}LinkQueue;

void LinkQueueInit(LinkQueue* queue);//初始化

void LinkQueueDestroy(LinkQueue* queue);//销毁

void LinkQueuePush(LinkQueue* queue,LinkType value);//入队列

void LinkQueuePop(LinkQueue* queue);//出队列

int LinkQueueFront(LinkQueue* queue,LinkType* value);//取队首元素

具体实现及测试代码:

linkqueue.c
#include"linkqueue.h"
#include<stdlib.h>
#include<stdio.h>
LinkNode* CreateLinkNode(LinkType value)
{
    LinkNode* new_node = (LinkNode*)malloc(sizeof(LinkNode));//为新结点开辟空间
    if(new_node == NULL)//开辟空间失败
    {
        printf("error\n");
        exit(-1);
    }
    new_node->data = value;
    new_node->next = NULL;

    return new_node;
}

void LinkQueueInit(LinkQueue* q)
{
    if(q == NULL)
    {
        return;
    }
    q->head = q->tail = NULL;
    return;
}

void LinkQueueDestroy(LinkQueue* q)
{
    LinkNode* cur = q->head->next;
    //循环释放链表结点
    while(cur != q->head)
    {
        LinkNode* to_delete = cur;
        free(to_delete);
        cur = cur->next;
    }
}

void LinkQueuePush(LinkQueue* q,LinkType value)
{
    if(q == NULL)
    {
        return;//非法输入
    }

    LinkNode* new_node = CreateLinkNode(value);//创建一个新结点

    if(q->head == NULL)//队列里没有元素
    {
        q->head = q->tail = new_node;//头指针和尾指针都指向新结点
    }
    q->tail->next = new_node;//将新结点插入到尾指针之后
    q->tail = new_node;//更新尾指针
    q->tail->next = NULL;
    return;
} 

void LinkQueuePop(LinkQueue* q)
{
    if(q == NULL)
    {
        return;//非法输入
    }
    LinkNode* to_delete = q->head;
    q->head = to_delete->next;//更新头结点
    free(to_delete);//释放以前的头指针
    to_delete = NULL;
    return;

}

int LinkQueueFront(LinkQueue* q,LinkType* value)
{
    if(q == NULL)
    {
        return 0;//非法输入
    }
    if(q->head == NULL)
    {
        return 0;//空队列
    }
    *value = q->head->data;
    return 1;
}
///
///以下是测试代码/
/
#if 1
#include<stdio.h>
#define TEST_HEADER printf("\n===========================%s==============================\n",__FUNCTION__);
void LinkQueuePrintChar(LinkQueue* q,char* msg)
{
    if(q == NULL)
    {
        return;
    }
    printf("[%s]\n",msg);
    LinkNode* cur = q->head;
    while(cur != q->tail->next)
    {
        printf("[%c] ",cur->data);
        cur = cur->next;
    }
    printf("\n");
    return;

}
void TestQueue()
{
    TEST_HEADER;
    LinkQueue queue;
    LinkQueueInit(&queue);
    LinkQueuePush(&queue,'a');
    LinkQueuePush(&queue,'b');
    LinkQueuePush(&queue,'c');
    LinkQueuePush(&queue,'d');
    LinkQueuePrintChar(&queue,"入队列四个元素");

    LinkType value;
    int ret = LinkQueueFront(&queue,&value);
    printf("ret expected 1,actual %d\n",ret);
    printf("value expected a,actual %c\n",value);

    LinkQueuePop(&queue);
    LinkQueuePop(&queue);
    LinkQueuePrintChar(&queue,"出队列两个元素");
    ret = LinkQueueFront(&queue,&value);
    printf("ret expected 1,actual %d\n",ret);
    printf("value expected c,actual %c\n",value);

    LinkQueuePop(&queue);
    LinkQueuePop(&queue);
    LinkQueuePrintChar(&queue,"再出队列两个元素");
    ret = LinkQueueFront(&queue,&value);
    printf("ret expected 0,actual %d\n",ret);

}

int main()
{
    TestQueue();
    printf("\n");
    return 0;
}
#endif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值