队列有一些特殊的队列:循环队列、阻塞队列、并发队列,基本都用数组实现....这篇是链表
队列用于什么地方呢?
大家都知道,CPU 资源是有限的,过多的线程反而会导致 CPU 频繁切换,处理性能下降。所以,线程池的大小一般都是综合考虑要处理任务的特点和硬件环境,来事先设置的。
当我们向固定大小的线程池中请求一个线程时,如果线程池中没有空闲资源了,这个时候线程池是拒绝请求还是排队请求?各种处理策略又是怎么实现的呢?都会用到队列
个人理解的线程,就是你的要求,你打开QQ,微信,浏览器等等这些相当于给CPU任务,CPU会给你执行,但是一下子打开太多,没有多余空间了,这个时候是拒绝呢,还是排队,有空了给你执行?
目录
1. 头文件
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
2. 结构体
/*结点*/
typedef struct ListQueueNode {
int data;
struct ListQueueNode* next;
}stListQueueNode;
/*列表*/
typedef struct ListQueue {
int num;
stListQueueNode* head;
stListQueueNode* tail;
}stListQueue;
3. 创建空队列
stListQueue* listQueue_create() {
stListQueue* queue = NULL;
queue = (stListQueue*)malloc(sizeof(stListQueue));
if (queue == NULL) {
return NULL;
}
queue->num = 0;
queue->head = NULL;
queue->tail = NULL;
return queue;
}
4. 摧毁队列链表
void listQueue_destory(stListQueue* queue){
int data = 0;
if (queue == NULL || queue->num == 0) {
return;
}
while (queue->num != 0) {
listQueue_dequeue(queue, &data);
queue->num--;
}
free(queue);
return;
}
5. 插入队列元素
int listQueue_enqueue(stListQueue* queue, int data) {
stListQueueNode* ptmp = NULL;
if (queue == NULL) {
return -1;
}
ptmp = (stListQueueNode*)malloc(sizeof(stListQueueNode));
if (ptmp == NULL) {
return -1;
} //以上创建空链表
ptmp->data = data;
ptmp->next = NULL; //赋值
/*注意,空队列情况!!*/
if(queue->head == NULL){
queue->head = ptmp;
}
else {
queue->tail->next = ptmp;
}
queue->tail = ptmp;
queue->num++; //将队列数加一
return 0;
}
6. 删除队列元素
int listQueue_dequeue(stListQueue* queue, int* data) {
stListQueueNode* ptmp = NULL;
if (queue == NULL || queue->num == NULL || data == NULL) {
return -1;
}
/*返回删除值*/
*data = queue->head->data;
ptmp = queue->head;
queue->head = ptmp->next;
queue->num--;
/*队列是否为空*/
if (queue->head == NULL) {
queue->tail = NULL;
}
/*不要忘记释放空间*/
free(ptmp);
return 0;
}
7. 输出队列元素
void listQueue_dump(stListQueue* queue) {
stListQueueNode* ptmp = NULL;
if (queue == NULL || queue->num == 0) {
return;
}
ptmp = queue->head;
while (ptmp != NULL) {
printf("%d ", ptmp->data);
ptmp = ptmp->next;
}
printf("\n");
return;
}
8. 主函数
int main() {
int data = 0;
int ret = 0;
stListQueue* queue = NULL; //创建空队列
queue = listQueue_create();
if (queue == NULL) {
printf("queue create falied.\n");
return 0;
}
int q = 0; //从键盘读入数据
printf("请输入插入队列的值(输入100结束插入):\n");
while (q != 100) {
scanf_s("%d", &q);
listQueue_enqueue(queue, q);
}
listQueue_dump(queue);
ret = listQueue_dequeue(queue, &data); //删除队列元素(先入先出)
if (ret != 0) {
printf("queue %d falied\n", data);
}
printf("queue dequeue %d\n", data);
listQueue_dump(queue);
listQueue_destory(queue); //销毁队列
return 0;
}
循环队列 和 普通数组队列的【差别】在于:
结束条件 : head == tail ==== 》 (tail+1)%n=head
假设数组大小为n == 10 ,当 tail == 5 时 ,(5+1)%10 = 6 ,但当 tail == 9 时,(9+1)% 10= 0 ,队列的第一个元素 ,开始循环了
开始条件 head = 0, tail = 0, 加元素 tail 向后移,去元素 head 向后移
结束条件 head = 6 , tail = 5 , 再加一个元素 (5+1)% 10 == 6 , 队满 , (tail+1)%n=head 。