数据结构----队列

>>> 队列的顺序存储

前提:利用之前已经写好的动态数组实现队列的顺序存储,数组首地址做对头。

两个头文件:动态数组头文件和队列的头文件

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值