受限线性表--队列

本文详细介绍了队列的基本概念,包括其作为先进先出(FIFO)的数据结构特性。接着,通过C/C++代码展示了如何使用动态数组实现顺序存储的队列,包括初始化、插入、删除、获取队头和队尾元素等操作。此外,还探讨了链式存储的队列实现,利用结点结构体和队列结构体完成入队、出队等操作。这些实现有助于理解数据结构在实际问题中的应用。
摘要由CSDN通过智能技术生成

目录

一、队列基本概念

二、队列的顺序存储

三、队列的链式存储


C/C++Linux服务器开发/后台架构师【零声教育】-学习视频教程-腾讯课堂

一、队列基本概念

队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。

队列是一种先进先出的t(First In First Out)的线性表,简称FIFO。允许插入的一端为队尾,允许删除的一端为队头。

二、队列的顺序存储

  • 基本概念:队列也是一种特殊的线性表;可以用线性表顺序存储来模拟队列。

代码如下:

dynamicArray.h

#pragma  once
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>

//动态数组结构体
struct dynamicArray
{
	void ** pAddr; //维护真实在堆区创建的数组的指针

	int m_capacity;  // 数组容量

	int m_size;   //数组大小
};

//初始化数组
struct dynamicArray * init_DynamicArray(int capacity);

//插入数组
void insert_DynamicArray(struct dynamicArray * array, int pos, void * data);

//删除数组  按位置删除
void removeByPos_DynamicArray(struct dynamicArray * array, int pos);

//销毁数组
void destroy_DynamicArray(struct dynamicArray* array);

dynamicArray.c

#include "dynamicArray.h"

//初始化数组
struct dynamicArray * init_DynamicArray(int capacity)
{
	if (capacity <= 0)
	{
		return NULL;
	}

	//给数组分配空间

	struct dynamicArray * array = malloc(sizeof(struct dynamicArray));
	if (array == NULL)
	{
		return NULL;
	}

	//给数组初始化
	array->pAddr = malloc(sizeof(void *)* capacity);
	array->m_capacity = capacity;
	array->m_size = 0;

	return array;
}

//插入数组
void insert_DynamicArray(struct dynamicArray * array, int pos, void * data)
{
	if (array == NULL)
	{
		return;
	}
	if (data == NULL)
	{
		return;
	}

	//无效位置  尾插
	if (pos < 0 || pos > array->m_size)
	{
		pos = array->m_size;
	}

	//判断是否满了,如果满动态扩展
	if (array->m_size == array->m_capacity)
	{
		//1、计算新空间大小
		int newCapacity = array->m_capacity * 2;

		//2、创建新空间
		void ** newSpace = malloc(sizeof(void *)* newCapacity);

		//3、将原有数据拷贝到新空间下
		memcpy(newSpace, array->pAddr, sizeof(void *)* array->m_capacity);

		//4、释放原有内存空间
		free(array->pAddr);

		//5、更新新空间指向
		array->pAddr = newSpace;

		//6、更新新容量
		array->m_capacity = newCapacity;
	}

	//插入新元素

	//移动元素 进行插入新元素
	for (int i = array->m_size - 1; i >= pos; i--)
	{
		//数据向后移动
		array->pAddr[i + 1] = array->pAddr[i];
	}

	//将新元素 插入到指定位置上
	array->pAddr[pos] = data;
	//更新大小
	array->m_size++;
}


//删除数组  按位置删除
void removeByPos_DynamicArray(struct dynamicArray * array, int pos)
{
	if (NULL == array)
	{
		return;
	}

	if (pos < 0 || pos > array->m_size - 1)
	{
		return;
	}

	//数据前移
	for (int i = pos; i < array->m_size - 1; i++)
	{
		array->pAddr[i] = array->pAddr[i + 1];
	}

	//更新数组大小
	array->m_size--;

}

//销毁数组
void destroy_DynamicArray(struct dynamicArray* array)
{
	if (array == NULL)
	{
		return;
	}

	if (array->pAddr != NULL)
	{
		free(array->pAddr);
		array->pAddr = NULL;
	}


	free(array);
	array = NULL;
}

seqQueue.h

#pragma  once 
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include "dynamicArray.h"
#define  MAX  1024

typedef void * seqQueue;

//初始化队列
seqQueue init_SeqQueue();
//入队
void push_SeqQueue(seqQueue queue, void * data);
//出队
void pop_SeqQueue(seqQueue queue);
//返回队列大小
int size_SeqQueue(seqQueue queue);
//判断队列是否为空
int isEmpty_SeqQueue(seqQueue queue);
//返回队头元素
void * front_SeqQueue(seqQueue queue);
//返回队尾元素
void * back_SeqQueue(seqQueue queue);
//销毁队列
void destroy_SeqQueue(seqQueue queue);

seqQueuec.c

#include "seqQueue.h"

//初始化队列
seqQueue init_SeqQueue()
{
	struct dynamicArray * arr = init_DynamicArray(MAX);

	return arr;
}
//入队
void push_SeqQueue(seqQueue queue, void * data)
{
	//本质  尾插

	if (queue == NULL)
	{
		return;
	}
	if (data == NULL)
	{
		return;
	}
	struct dynamicArray * myQueue = (struct dynamicArray *)queue;
	if (myQueue->m_size == MAX)
	{
		return;
	}

	insert_DynamicArray(myQueue, myQueue->m_size, data);

}
//出队
void pop_SeqQueue(seqQueue queue)
{
	//本质  头删

	if (queue == NULL)
	{
		return;
	}

	struct dynamicArray * myQueue = (struct dynamicArray *)queue;

	if (myQueue->m_size <= 0)
	{
		return;
	}

	removeByPos_DynamicArray(myQueue, 0);

}
//返回队列大小
int size_SeqQueue(seqQueue queue)
{
	if (queue == NULL)
	{
		return -1;
	}

	struct dynamicArray * myQueue = (struct dynamicArray *)queue;

	return myQueue->m_size;

}
//判断队列是否为空
int isEmpty_SeqQueue(seqQueue queue)
{
	if (queue == NULL)
	{
		return -1;
	}
	struct dynamicArray * myQueue = (struct dynamicArray *)queue;

	if (myQueue->m_size == 0)
	{
		return 1;
	}
	return 0;


}
//返回队头元素
void * front_SeqQueue(seqQueue queue)
{
	if (queue == NULL)
	{
		return NULL;
	}
	struct dynamicArray * myQueue = (struct dynamicArray *)queue;

	return myQueue->pAddr[0];

}
//返回队尾元素
void * back_SeqQueue(seqQueue queue)
{
	if (queue == NULL)
	{
		return NULL;
	}
	struct dynamicArray * myQueue = (struct dynamicArray *)queue;

	return myQueue->pAddr[myQueue->m_size - 1];
}
//销毁队列
void destroy_SeqQueue(seqQueue queue)
{
	if (queue == NULL)
	{
		return;
	}

	destroy_DynamicArray((struct dynamicArray *)queue);

}

main.c

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include "seqQueue.h"

struct Person
{
	char name[64];
	int age;
};
void test01()
{
	//初始化队列
	seqQueue myQueue = init_SeqQueue();

	//准备数据
	struct Person p1 = { "aaa", 10 };
	struct Person p2 = { "bbb", 20 };
	struct Person p3 = { "ccc", 30 };
	struct Person p4 = { "ddd", 40 };


	//入队
	push_SeqQueue(myQueue, &p1);
	push_SeqQueue(myQueue, &p2);
	push_SeqQueue(myQueue, &p3);
	push_SeqQueue(myQueue, &p4);
	printf("队列大小为:%d\n", size_SeqQueue(myQueue));
	while (isEmpty_SeqQueue(myQueue) == 0)
	{
		//访问队头
		struct Person * pFront = (struct Person *)front_SeqQueue(myQueue);
		printf("队头元素 -- 姓名:%s  年龄: %d\n", pFront->name, pFront->age);
		//访问队尾
		struct Person * pBack = (struct Person *)back_SeqQueue(myQueue);
		printf("队尾元素 -- 姓名:%s  年龄: %d\n", pBack->name, pBack->age);
		//出队
		pop_SeqQueue(myQueue);
	}

	printf("队列大小为:%d\n", size_SeqQueue(myQueue));

	//销毁队列
	destroy_SeqQueue(myQueue);

}

int main() {
	test01();


	system("pause");
	return EXIT_SUCCESS;
}

三、队列的链式存储

  • 基本概念队列也是一种特殊的线性表;可以用线性表链式存储来模拟队列的链式存储。

linkQueue.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

//结点结构体
struct QueueNode {
	struct QueueNode* next;
};

//队列结构体
struct LinkQueue
{
	//头结点
	struct QueueNode pHeader;
	//尾结点
	struct QueueNode * pTail;

	int m_size;
};

typedef  void*  LinkQueue;

//初始化队列
LinkQueue init_LinkQueue();

//入队
void push_LinkQueue(LinkQueue queue , void* data);

//出队
void pop_LinkQueue(LinkQueue queue);

//返回队列大小
int size_LinkQueue(LinkQueue queue);

//判断是否为空
int isEmpty_LinkQueue(LinkQueue queue);

//返回队头
LinkQueue front_LinkQueue(LinkQueue queue);

//返回队尾
LinkQueue back_LinkQueue(LinkQueue queue);

//销毁队列
void destroy_LinkQueue(LinkQueue queue);

linkQueue.c

#include "linkQueue.h"

//初始化队列
LinkQueue init_LinkQueue()
{
	struct LinkQueue * myQueue = malloc(sizeof(struct  LinkQueue));

	if (myQueue == NULL)
	{
		return NULL;
	}

	myQueue->pHeader.next = NULL;
	myQueue->pTail = &myQueue->pHeader;
	myQueue->m_size = 0;

	return myQueue;
}

//入队
void push_LinkQueue(LinkQueue queue, void* data)
{
	if(queue == NULL)
	{
		return;
	}
	if (data == NULL)
	{
		return;
	}
	//本质 尾插
	struct LinkQueue * myQueue = queue;
	struct QueueNode * myNode = data;

	//更改指针指向
	myQueue->pTail->next = myNode;
	myNode->next = NULL;

	//更新尾节点
	myQueue->pTail = myNode;

	myQueue->m_size++;
}

//出队
void pop_LinkQueue(LinkQueue queue)
{
	if (queue == NULL)
	{
		return;
	}
	struct LinkQueue * myQueue = queue;

	if (myQueue->m_size == 0)
	{
		return;
	}

	//1个节点的时候,要将尾节点还原到头
	if (myQueue->m_size == 1)
	{
		myQueue->pHeader.next = NULL;
		myQueue->pTail = &myQueue->pHeader;
		myQueue->m_size--;
	}

	//记录第一个有数据的节点
	struct QueueNode * pFirst = myQueue->pHeader.next;

	//更改指针指向
	myQueue->pHeader.next = pFirst->next;

	myQueue->m_size--;
}

//返回队列大小
int size_LinkQueue(LinkQueue queue)
{
	if (queue == NULL)
	{
		return -1;
	}

	struct LinkQueue * myQueue = queue;
	return myQueue->m_size;
}

//判断是否为空
int isEmpty_LinkQueue(LinkQueue queue)
{
	if (queue == NULL)
	{
		return -1;
	}

	struct LinkQueue * myQueue = queue;
	if (myQueue->m_size == 0)
	{
		return 1;
	}
	return 0;
}

//返回队头
LinkQueue front_LinkQueue(LinkQueue queue)
{
	if (queue == NULL)
	{
		return NULL;
	}

	struct LinkQueue * myQueue = queue;

	return myQueue->pHeader.next;
}

//返回队尾
LinkQueue back_LinkQueue(LinkQueue queue)
{
	if (queue == NULL)
	{
		return NULL;
	}

	struct LinkQueue * myQueue = queue;
	return myQueue->pTail;
}

//销毁队列
void destroy_LinkQueue(LinkQueue queue)
{
	if (queue == NULL)
	{
		return;
	}

	free(queue);
	queue = NULL;
}

main.c

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "linkQueue.h"

struct Person
{
	void * node;
	char name[64];
	int age;
};


int main(void)
{
	//初始化队列
	LinkQueue myQueue = init_LinkQueue();

	//准备数据
	struct Person p1 = { NULL,"aaa", 10 };
	struct Person p2 = { NULL,"bbb", 20 };
	struct Person p3 = { NULL,"ccc", 30 };
	struct Person p4 = { NULL,"ddd", 40 };

	//入队
	push_LinkQueue(myQueue, &p1);
	push_LinkQueue(myQueue, &p2);
	push_LinkQueue(myQueue, &p3);
	push_LinkQueue(myQueue, &p4);
	printf("队列大小为:%d\n", size_LinkQueue(myQueue));
	while (isEmpty_LinkQueue(myQueue) == 0)
	{
		//访问队头
		struct Person * pFront = front_LinkQueue(myQueue);
		printf("链式存储::队头元素 -- 姓名:%s  年龄: %d\n", pFront->name, pFront->age);
		//访问队尾
		struct Person * pBack = back_LinkQueue(myQueue);
		printf("链式存储::队尾元素 -- 姓名:%s  年龄: %d\n", pBack->name, pBack->age);
		//出队
		pop_LinkQueue(myQueue);
	}

	//销毁队列
	destroy_LinkQueue(myQueue);

	system("pause");
	return EXIT_SUCCESS;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值