数据结构之队列

什么是队列

队列(Queue)也是一种运算受限的线性表,它限定在表的一端进行插入操作,在表的另一端进行删除操作。队列的结构特性是:先进先出FIFO ( First In First Out)。队列又被称为先进先出表。

队尾:允许插入的一端称作队尾(Rear)

队首:允许删除的一端称作队首(Front)

队列为空的时候 队头front和队尾tail都是0的位置,入队的时候队尾tail往后移动,出队的时候front往队列tail靠拢

因为front的移动,导致数组队列存在伪溢出现象。可以通过循环队列的方式解决伪溢出问题。

链式队列可以通过无表头链表记录头尾的方式实现,插入队列用表尾法插入,遍历表头法删除写法

队列基本操作

  • 创建栈:create_queue

  • 入队: push_queue

  • 出队: pop_queue

  • 获取队头元素:front_queue

  • 队列是否为空:empty_queue

  • 队列元素个数: size_queue

队列应用

具体来说,队列有以下几个用途:

  • 任务调度:队列可以用于任务调度,将任务按照它们被提交的顺序排队等待执行。

  • 消息传递:队列可以用于消息传递,例如在分布式系统中,可以使用队列来传递消息。

  • 广度优先搜索:队列可以用于实现广度优先搜索算法,其中队列用于存储待访问的节点。

  • 缓存:队列可以用于实现缓存,例如在计算机网络中,可以使用队列来缓存数据包等。

普通队列(实现队列的基本功能)

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
//循环队列
typedef int DataType;
typedef struct 
{
	DataType* data;
	int front;
	int tail;
	int count;
	int maxSize;
}Queue;
Queue* create_queue(int maxSize)
{
	Queue* q = (Queue*)calloc(1, sizeof(Queue));
	assert(q);
	q->data = (DataType*)calloc(maxSize, sizeof(DataType));
	q->maxSize = maxSize;
	q->front = 0;
	q->tail = 0;
	q->count = 0;
	return q;
}
bool empty_queue(Queue* q) 
{
	return q->count == 0;
}
int size_queue(Queue* q) 
{
	return q->count;
}
void push_queue(Queue* q, DataType data) 
{
	if (q->count == q->maxSize) 
	{
		printf("满了!\n");
		return;
	}
	q->data[q->tail] = data;
	//q->tail++;
	q->tail = (q->tail + 1) % q->maxSize;
	q->count++;
}
int front_queue(Queue* q) 
{
	return q->data[q->front];
}

void pop_queue(Queue* q) 
{
	if (q->count == 0) 
	{
		printf("空的!\n");
		return;
	}
	//q->front++;
	q->front = (q->front + 1) % q->maxSize;
	q->count--;
}
int main() 
{
	Queue* q = create_queue(5);
	for (int i = 0; i < 4; i++) 
	{
		push_queue(q, i);
	}
	pop_queue(q);
	pop_queue(q);
	push_queue(q, 100);
	push_queue(q, 200);
	push_queue(q, 300);
	while (!empty_queue(q)) 
	{
		printf("%d ", front_queue(q));
		pop_queue(q);
	}
	printf("\n");
	return 0;
}

链式队列(设置前后节点)

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <assert.h>
//链式队列:表尾插入+表头删除,记录头和尾的方式
typedef int DataType;
typedef struct Node
{
	DataType data;
	struct Node* next;
}Node;
Node* create_node(DataType data) 
{
	Node* newNode = (Node*)calloc(1, sizeof(Node));
	assert(newNode);
	newNode->data = data;
	newNode->next = NULL;
	return newNode;
}

typedef struct 
{
	int count;
	Node* frontNode;
	Node* tailNode;
}Queue;


Queue* create_queue() 
{
	Queue* q = (Queue*)calloc(1, sizeof(Queue));
	assert(q);
	q->count = 0;
	q->frontNode = NULL;
	q->tailNode = NULL;
	return q;
}

bool empty_queue(Queue* q) 
{
	return q->count == 0;
}
int size_queue(Queue* q) 
{
	return q->count;
}

int front_queue(Queue* queue) 
{
	return queue->frontNode->data;
}

void push_queue(Queue* q, DataType data) 
{
	Node* newNode = create_node(data);
	if (q->count == 0) 
	{
		q->frontNode = newNode;
	}
	else 
	{
		q->tailNode->next = newNode;
	}
	q->tailNode = newNode;
	q->count++;
}
void pop_queue(Queue* q) 
{
	if (q == NULL || q->count == 0) 
	{
		printf("队空!\n");
		return;
	}
	Node* nextNode = q->frontNode->next;
	free(q->frontNode);
	q->frontNode = nextNode;
	nextNode == NULL ? (q->tailNode = NULL) : 0;//只有一个节点的话 就需要表尾也置为空
	q->count--;
}
int main() 
{
	Queue* q = create_queue();
	for (int i = 0; i < 10; i++) 
	{
		push_queue(q, i);
	}
	while (!empty_queue(q)) 
	{
		printf("%d ", front_queue(q));
		pop_queue(q);
	}
	printf("\n");
	return 0;
}

双向队列(数据可以从队列的前和后面传入或者删除)

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int DataType;

typedef struct Node 
{
	DataType data;
	struct Node* prev;
	struct Node* next;
}Node;

Node* create_node(DataType data) 
{
	Node* newNode = (Node*)calloc(1, sizeof(Node));
	assert(newNode);
	newNode->data = data;
	newNode->prev = NULL;
	newNode->next = NULL;
	return newNode;
}

typedef struct 
{
	int count;
	Node* frontNode;
	Node* tailNode;
}Deque;

Deque* create_queue() 
{
	Deque* q = (Deque*)calloc(1, sizeof(Deque));
	assert(q);
	q->count = 0;
	q->frontNode = NULL;
	q->tailNode = NULL;
	return q;
}

bool empty_queue(Deque* q) 
{
	return q->count == 0;
}
int size_queue(Deque* q) 
{
	return q->count;
}
void push_front(Deque* q,DataType data) 
{
	Node* newNode = create_node(data);
	if (q->count == 0) 
	{
		q->tailNode = newNode;
		//q->frontNode = newNode;
	}
	else 
	{
		newNode->next = q->frontNode;
		q->frontNode->prev = newNode;
		//q->frontNode = newNode;
	}
	q->frontNode = newNode;
	q->count++;
}
void push_back(Deque* q, DataType data) 
{
	Node* newNode = create_node(data);
	if (q->count == 0)
	{
		q->frontNode = newNode;
		//q->tailNode = newNode;
	}
	else
	{
		q->tailNode->next = newNode;
		newNode->prev = q->tailNode;
		//q->tailNode = newNode;
	}
	q->tailNode = newNode;
	q->count++;
}
void pop_front(Deque* q) 
{
	if (q == NULL || q->count == 0) 
	{
		printf("队空!\n");
		return;
	}
	Node* nextNode = q->frontNode->next;
	free(q->frontNode);
	q->frontNode = nextNode;
	nextNode == NULL ? (q->tailNode = NULL):(nextNode->prev=NULL);
	q->count--;
}
void pop_back(Deque* q) 
{
	if (q == NULL || q->count == 0)
	{
		printf("队空!\n");
		return;
	}
	Node* prevNode = q->tailNode->prev;
	free(q->tailNode);
	q->tailNode = prevNode;
	prevNode == NULL ? (q->frontNode = NULL) : (prevNode->next = NULL);
	q->count--;
}
DataType front_queue(Deque* q) 
{
	return q->frontNode->data;
}
DataType back_queue(Deque* q) 
{
	return q->tailNode->data;
}
int main() 
{
	Deque* q = create_queue();
	push_front(q, 1);		//3 2 1 66 88 99
	push_front(q, 2);
	push_front(q, 3);
	push_back(q, 66);
	push_back(q, 88);
	push_back(q, 99);
	while (!empty_queue(q)) 
	{
		printf("%d ", front_queue(q));
		pop_front(q);
	}
	printf("\n");
	return 0;
}

优先队列(设置优先等级)

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <assert.h>
#define MAX 100
typedef struct Data 
{
	int priority;
	char name[20];
}Data;

typedef struct 
{
	int count;
	Data data[MAX];
}Priqueue;
Priqueue* create_queue() 
{
	Priqueue* q = (Priqueue*)calloc(1, sizeof(Priqueue));
	assert(q);
	return q;
}
int size_queue(Priqueue* q) 
{
	return q->count;
}
bool empty_queue(Priqueue* q) 
{
	return q->count == 0;
}
void push_queue(Priqueue* q, Data data) 
{
	if (q->count == MAX) 
	{
		printf("队满");
	}
	else 
	{
		q->data[q->count++] = data;
	}
}
void pop_queue(Priqueue* q, Data* data) 
{
	if (q == NULL || q->count == 0)
		return;
	Data minData = q->data[0];
	int minIndex = 0;
	for (int i = 1; i < q->count; i++) 
	{
		if (minData.priority > q->data[i].priority) 
		{
			minData = q->data[i];
			minIndex = i;
		}
	}
	*data = minData;
	for (int i = minIndex; i < q->count; i++) 
	{
		q->data[i] = q->data[i + 1];
	}
	q->count--;
}
int main() 
{
	Priqueue* q = create_queue();
	Data arr[5] = { {1,"张三"},{4,"里斯"},{9,"小美"},{3,"小帅"},{5,"老王"} };
	for (int i = 0; i < 5; i++) 
	{
		push_queue(q, arr[i]);
	}
	while (!empty_queue(q)) 
	{
		Data temp;
		pop_queue(q, &temp);
		printf("%d:%s\n", temp.priority, temp.name);
	}
	return 0;
}

链式优先队列

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>
#include <string.h>
typedef struct Data 
{
	int priority;
	char name[20];
}Data;

typedef struct Node 
{
	Data data;
	struct Node* next;
}Node;
Node* create_node(Data data) 
{
	Node* newNode = (Node*)calloc(1, sizeof(Node));
	newNode->data = data;
	newNode->next = NULL;
	return newNode;
}
typedef struct 
{
	int count;
	Node* headNode;
}PriQueue;

PriQueue* create_queue() 
{
	PriQueue* q = (PriQueue*)calloc(1, sizeof(PriQueue));
	assert(q);
	q->count = 0;
	q->headNode = NULL;
	return q;
}
bool empty_queue(PriQueue* q) 
{
	return q->count == 0;
}
int size_queue(PriQueue* q) 
{
	return q->count;
}
void push_queue(PriQueue* q,Data data) 
{
	Node* newNode = create_node(data);
	if (q->count == 0) 
	{
		q->headNode = newNode;
	}
	else 
	{
		Node* preNode = NULL;
		Node* curNode = q->headNode;
		//1 3 8
		//4
		while (curNode != NULL && curNode->data.priority < data.priority) 
		{
			preNode = curNode;
			curNode = preNode->next;
		}
		if (preNode == NULL) 
		{
			newNode->next = q->headNode;
			q->headNode = newNode;
		}
		else 
		{
			preNode->next = newNode;
			newNode->next = curNode;
		}
	}
	q->count++;
}
void pop_queue(PriQueue* q, Data* data) 
{
	if (q == NULL || q->count == 0) 
	{
		return;
	}
	Node* nextNode = q->headNode->next;
	*data = q->headNode->data;
	free(q->headNode);
	q->headNode = nextNode;
	q->count--;
}
int main()
{
	PriQueue* q = create_queue();
	Data arr[5] = { {1,"张三"},{4,"里斯"},{9,"小美"},{3,"小帅"},{5,"老王"} };
	for (int i = 0; i < 5; i++)
	{
		push_queue(q, arr[i]);
	}
	while (!empty_queue(q))
	{
		Data temp;
		pop_queue(q, &temp);
		printf("%d:%s\n", temp.priority, temp.name);
	}
	return 0;
}

 

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值