>>> 队列的顺序存储
前提:利用之前已经写好的动态数组实现队列的顺序存储,数组首地址做对头。
两个头文件:动态数组头文件和队列的头文件
//dynamic_array.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//动态数组结构体
struct dynamicArray
{
void** pAddr;
int m_capacity;
int m_size;
};
//初始化数组
struct dynamicArray* initDynamicArray(int capacity);
//插入
void insertDynamicArray(struct dynamicArray* arry, int pos, void* data);
//遍历数组
void foreachDynamicArray(struct dynamicArray* arry, void(*myPrint)(void*));
//按位置删除数组元素
void removeByPosDynamicArray(struct dynamicArray* arry, int pos);
//按值删除
void removeByValueDynamicArray(struct dynamicArray* arry, void* data, int(*myCompare)(void*, void*));
//销毁数组
void destroyDynamicArray(struct dynamicArray* arry);
//seq_queue.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dynamic_array.h"
#define MAX 1024 //队列容量
typedef void* SeqQueue;
//初始化队列
SeqQueue initSeqQueue();
//出队
void popSeqQueue(SeqQueue queue);
//入队
void pushSeqQueue(SeqQueue queue, void* data);
//返回队列大小
int sizeSeqQueue(SeqQueue queue);
//判断队列是否为空
int isEmptySeqQueue(SeqQueue queue);
//返回队头元素
void* frontSeqQueue(SeqQueue queue);
//返回队尾元素
void* backSeqQueue(SeqQueue queue);
//销毁队列
void destroySeqQueue(SeqQueue queue);
三个源文件:动态数组的具体实现文件、队列的具体实现文件和测试文件
//dynamic_array.c
#include "dynamic_array.h"
//初始化数组
struct dynamicArray* initDynamicArray(int capacity)
{
//1.判断输入容量
if (capacity <= 0)
{
return NULL;
}
//2.给数组结构体分配空间
struct dynamicArray* arry = (struct dynamicArray*) malloc(sizeof(struct dynamicArray));
if (arry == NULL)
{
return NULL;
}
//3.数组结构体属性初始化
arry->pAddr = (void**)malloc(sizeof(void*) * capacity);
arry->m_capacity = capacity;
arry->m_size = 0;
return arry;
}
//插入
void insertDynamicArray(struct dynamicArray* arry, int pos, void* data)
{
//1.判断输入参数的有效性
if (arry == NULL || data == NULL)
{
return;
}
if (pos < 0 || pos > arry->m_size) //pos越界,默认尾插
{
pos = arry->m_size;
}
//2.判断数组是否已满,满了动态扩展
if (arry->m_size == arry->m_capacity)
{
int new_capacity = arry->m_capacity * 2; //新空间大小
void** new_space = (void**)malloc(sizeof(void*) * new_capacity); //开辟新空间
memcpy(new_space, arry->pAddr, sizeof(void*) * arry->m_capacity); //将原有数据拷贝到新空间
free(arry->pAddr); //释放原来空间
arry->pAddr = new_space; //指向新空间
arry->m_capacity = new_capacity; //更新容量
}
//3.pos位置后的元素向后移动一位,注意:从右向左移动方便
for (int i = arry->m_size - 1; i >= pos; i--)
{
arry->pAddr[i + 1] = arry->pAddr[i];
}
//4.插入
arry->pAddr[pos] = data;
arry->m_size++; //更新数组大小
}
//遍历数组
void foreachDynamicArray(struct dynamicArray* arry, void(*myPrint)(void*))
{
if (arry == NULL || myPrint == NULL)
{
return;
}
if (arry->m_size == 0)
{
return;
}
for (int i = 0; i < arry->m_size; i++)
{
myPrint(arry->pAddr[i]);
}
}
//按位置删除数组元素
void removeByPosDynamicArray(struct dynamicArray* arry, int pos)
{
//1.判断
if (arry == NULL)
{
return;
}
if (arry->m_size == 0)
{
return;
}
if (pos < 0 || pos >= arry->m_size)
{
return;
}
//2. 删除, 向前覆盖
for (int i = pos; i < arry->m_size - 1; i++) //删除最后一个元素直接m_size--即可
{
arry->pAddr[i] = arry->pAddr[i + 1];
}
//3.更新
arry->m_size--;
}
//按值删除
void removeByValueDynamicArray(struct dynamicArray* arry, void* data, int(*myCompare)(void*, void*))
{
//1.判断
if (arry == NULL || data == NULL || myCompare == NULL)
{
return;
}
if (arry->m_size == 0)
{
return;
}
//2.删除
for (int i = 0; i < arry->m_size; i++)
{
if (myCompare(arry->pAddr[i], data))
{
//如果找到要删除的数据,i就是要删除的具体位置
removeByPosDynamicArray(arry, i);
break; //只删除第一次出现的
}
}
//3.更新,removeByPosDynamicArray中已经更新过了
}
//销毁数组
void destroyDynamicArray(struct dynamicArray* arry)
{
if (arry == NULL)
{
return;
}
//先销毁属性的指针,再销毁结构体指针
if (arry->pAddr != NULL)
{
free(arry->pAddr);
arry->pAddr = NULL;
}
free(arry);
arry = NULL;
}
//seq_queue.c
#include "seq_queue.h"
//初始化
SeqQueue initSeqQueue()
{
struct dynamicArray* arry = (struct dynamicArray*)initDynamicArray(MAX);
return arry;
}
//出队
void popSeqQueue(SeqQueue queue)
{
if (queue == NULL)
{
return;
}
struct dynamicArray* myqueue = (struct dynamicArray*)queue;
if (myqueue->m_size <= 0)
{
return;
}
removeByPosDynamicArray(myqueue, 0); //本质是头删
}
//入队
void pushSeqQueue(SeqQueue queue, void* data)
{
if (queue == NULL || data == NULL)
{
return;
}
struct dynamicArray* myqueue = (struct dynamicArray*)queue;
if (myqueue->m_size == MAX)
{
return;
}
insertDynamicArray(myqueue, myqueue->m_size, data); //本质是尾插
}
//返回队列大小
int sizeSeqQueue(SeqQueue queue)
{
if (queue == NULL)
{
return NULL;
}
struct dynamicArray* myqueue = (struct dynamicArray*)queue;
return myqueue->m_size;
}
//判断队列是否为空
int isEmptySeqQueue(SeqQueue queue)
{
if (queue == NULL)
{
return NULL;
}
struct dynamicArray* myqueue = (struct dynamicArray*)queue;
if (myqueue->m_size == 0)
{
return 1;
}
return 0;
}
//返回队头元素
void* frontSeqQueue(SeqQueue queue)
{
if (queue == NULL)
{
return NULL;
}
struct dynamicArray* myqueue = (struct dynamicArray*)queue;
return myqueue->pAddr[0];
}
//返回队尾元素
void* backSeqQueue(SeqQueue queue)
{
if (queue == NULL)
{
return NULL;
}
struct dynamicArray* myqueue = (struct dynamicArray*)queue;
return myqueue->pAddr[myqueue->m_size-1];
}
//销毁队列
void destroySeqQueue(SeqQueue queue)
{
if (queue == NULL)
{
return;
}
struct dynamicArray* myqueue = (struct dynamicArray*)queue;
destroyDynamicArray(myqueue);
}
//test.c
#include "seq_queue.h"
//自定义类型
struct Person
{
char name[64];
int age;
};
int main()
{
SeqQueue* myqueue = initSeqQueue();
struct Person p1 = { "san", 11 };
struct Person p2 = { "si", 22 };
struct Person p3 = { "wu", 33 };
struct Person p4 = { "wu", 33 };
pushSeqQueue(myqueue, &p1);
pushSeqQueue(myqueue, &p2);
pushSeqQueue(myqueue, &p3);
pushSeqQueue(myqueue, &p4);
printf("queue size:%d\n", sizeSeqQueue(myqueue));
while (!isEmptySeqQueue(myqueue))
{
struct Person* pFront = frontSeqQueue(myqueue);
printf("front:name[%s] age[%d]\n", pFront->name, pFront->age);
struct Person* pBack = backSeqQueue(myqueue);
printf("back:name[%s] age[%d]\n", pBack->name, pBack->age);
popSeqQueue(myqueue);
}
printf("queue size:%d\n", sizeSeqQueue(myqueue));
return 0;
}
>>> 队列的链式存储
//link_queue.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//定义企业版链表节点结构体
struct QueueNode
{
struct QueueNode* next;
};
//队列结构体
struct LQueue
{
struct QueueNode pHeader;
int m_size;
struct QueueNode* pTail; //尾节点指针,因为队列尾部需要频繁插入
};
typedef void* LinkQueue;
//初始化队列
LinkQueue initLinkQueue();
//出队
void popLinkQueue(LinkQueue queue);
//入队
void pushLinkQueue(LinkQueue queue, void* data);
//返回队列大小
int sizeLinkQueue(LinkQueue queue);
//判断队列是否为空
int isEmptyLinkQueue(LinkQueue queue);
//返回队头元素
void* frontLinkQueue(LinkQueue queue);
//返回队尾元素
void* backLinkQueue(LinkQueue queue);
//销毁队列
void destroyLinkQueue(LinkQueue queue);
//link_queue.c
#include "link_queue.h"
//初始化队列
LinkQueue initLinkQueue()
{
struct LQueue* myQueue = (struct LQueue*)malloc(sizeof(struct LQueue));
if (myQueue == NULL)
{
return NULL;
}
myQueue->pHeader.next = NULL;
myQueue->m_size = 0;
myQueue->pTail = &myQueue->pHeader; //开始时尾节点指针指向头节点
return myQueue;
}
//出队
void popLinkQueue(LinkQueue queue)
{
if (queue == NULL)
{
return;
}
struct LQueue* myQueue = (struct LQueue*)queue;
if (myQueue->m_size == 0)
{
return;
}
if (myQueue->m_size == 1)
{
myQueue->pHeader.next = NULL;
myQueue->pTail = &myQueue->pHeader; //1个节点的时候,要将尾节点还原到头
myQueue->m_size--;
return;
}
struct QueueNode* pDel = myQueue->pHeader.next;
myQueue->pHeader.next = pDel->next;
myQueue->m_size--;
}
//入队
void pushLinkQueue(LinkQueue queue, void* data)
{
if (queue == NULL || data == NULL)
{
return;
}
struct LQueue* myQueue = (struct LQueue*)queue;
struct QueueNode* newNode = (struct QueueNode*)data;
newNode->next = NULL;
myQueue->pTail->next = newNode; //更改指针指向
myQueue->pTail = newNode; //更新新的尾节点
myQueue->m_size++;
}
//返回队列大小
int sizeLinkQueue(LinkQueue queue)
{
if (queue == NULL)
{
return NULL;
}
struct LQueue* myQueue = (struct LQueue*)queue;
return myQueue->m_size;
}
//判断队列是否为空
int isEmptyLinkQueue(LinkQueue queue)
{
if (queue == NULL)
{
return NULL;
}
struct LQueue* myQueue = (struct LQueue*)queue;
if (myQueue->m_size == 0)
{
return 1;
}
return 0;
}
//返回队头元素
void* frontLinkQueue(LinkQueue queue)
{
if (queue == NULL)
{
return NULL;
}
struct LQueue* myQueue = (struct LQueue*)queue;
return myQueue->pHeader.next;
}
//返回队尾元素
void* backLinkQueue(LinkQueue queue)
{
if (queue == NULL)
{
return NULL;
}
struct LQueue* myQueue = (struct LQueue*)queue;
return myQueue->pTail;
}
//销毁队列
void destroyLinkQueue(LinkQueue queue)
{
if (queue == NULL)
{
return;
}
free(queue);
queue = NULL;
}
//test.c
#include "link_queue.h"
//自定义类型
struct Person
{
void* node;
char name[64];
int age;
};
int main()
{
LinkQueue myqueue = initLinkQueue();
struct Person p1 = {NULL, "san", 11 };
struct Person p2 = {NULL, "si", 22 };
struct Person p3 = {NULL, "wu", 33 };
struct Person p4 = {NULL, "wu", 33 };
pushLinkQueue(myqueue, &p1);
pushLinkQueue(myqueue, &p2);
pushLinkQueue(myqueue, &p3);
pushLinkQueue(myqueue, &p4);
printf("queue size:%d\n", sizeLinkQueue(myqueue));
while (!isEmptyLinkQueue(myqueue))
{
struct Person* pFront = frontLinkQueue(myqueue);
printf("front:name[%s] age[%d]\n", pFront->name, pFront->age);
struct Person* pBack = backLinkQueue(myqueue);
printf("back:name[%s] age[%d]\n", pBack->name, pBack->age);
popLinkQueue(myqueue);
}
printf("queue size:%d\n", sizeLinkQueue(myqueue));
return 0;
}