队列的实现

一、顺序队列的原理

1.1 顺序队列

队列: 队列是一种特殊的线性表,其特点是在其两端进行插入和删除操作受到限制,只允许在一端(称为队尾)进行插入,而在另一端(称为队头)进行删除。

①允许进行存入操作的一端称为“队尾”。
②允许进行删除操作的一端称为“队头”。
③当线性表中没有元素时,称为“空队”。

特点: 先进先出(FIFO)
队列

  1. 规定:front指向队头元素的位置; rear指向队尾元素的下一个位置。

  2. 在队列操作过程中,为了提高效率,以调整指针代替队列元素的移动,并将数组作为循环队列的操作空间。

  3. 为区别空队和满队,满队元素个数比数组元素个数少一个。

1.2 应用

1、计算机系统:用于CPU的作业调度、图遍历的广度优先查找等。
2、消息传递:在生产环境中,多个进程或多个应用程序之间需要高效地传递消息,以协调任务的执行,这时可以使用队列作为消息传递的媒介,实现消息的异步传递和处理。

二、顺序队列的实现

2.1 结构体创建

typedef int datatype;    //定义队列中数据元素的数据类型
#define N 128	    //定义队列的容量
typedef struct{
	datatype data[N];   //用数组作为队列的储存空间
    int front, rear;     //指示队头位置和队尾位置的指针
} sequeue; 	     //顺序队列类型定义

2.2 队列的创建

算法思路:
①申请内存。
②初始化。

sequeue * queue_creat()
{
	sequeue *sq;
	if((sq = (sequeue *)malloc(sizeof(sequeue))) == NULL)
	{
		printf("malloc failed\n");
		return NULL;
	}
	
	memset(sq->data, 0, sizeof(data));
	sq->front = sq->rear = 0;
	return sq;
}

2.3 入队

算法思路:
为了防止rear溢出,这里采用取余循环(rear + 1) % N,这样当到127是,又回到了0。
①判断队列是否满?
②存值,rear++;

int enqueue(sequeue *sq, datatype x)
{
	if((sq->rear + 1) % N == front)
	{
		printf("sq is full\n");
		return -1;
	}
	sq->data[sq->rear] = x;
	sq->rear = (sq->rear + 1) % N;

	return 0;
}

2.4 出队

算法思路:
①判断队列是否空?
②front++.

datatype dequeue(sequeue *sq){
	if(NULL == sq){
		printf("sequeue is NULL\n");
		return -1;
	}

	if(sq->rear == sq->front){
		printf("sequeue is empty!\n");
		return -1;
	}

	datatype ret = sq->data[sq->front];
	sq->front = (sq->front + 1) % N;

	return ret;
}

2.5 判断队列是否空

int queue_empty(sequeue *sq){
	if(NULL == sq){
		printf("sequeue is NULL\n");
		return -1;
	}

	return (sq->front == sq->rear ? 1 : 0);
}

2.6 判断队列是否满

int queue_full(sequeue *sq){
	if(NULL == sq){
		printf("sequeue is NULL\n");
		return -1;
	}

	if((sq->rear + 1) % N == sq->front){
		return 1;
	}
	else{
		return 0i;
	}
}

2.7 清空队列

int queue_clear(sequeue *sq){
	if(NULL == sq){
		printf("sequeue is NULL\n");
		return -1;
	}

	sq->front = sq->rear = 0;

	return 0;
}

2.8 释放队列

sequeue *queue_free(sequeue *sq){
	if(NULL == sq){
		printf("sequeue is NULL\n");
		return NULL;
	}

	free(sq);
	sq = NULL;

	return NULL;
}

三、链式队列的原理

3.1链式队列

插入操作在队尾进行,删除操作在队头进行,由队头指针和队尾指针控制队列的操作。
链式队列
空队

3.2 应用

  • 网络请求队列: 在网络请求中,可以使用链式队列来管理请求的顺序。每个请求都可以以节点的形式加入队列,然后按照先进先出的原则依次处理请求。
  • 任务调度队列: 在多线程任务调度中,可以使用链式队列来管理待执行的任务。每个任务都可以以节点的形式加入队列,并按照一定的优先级规则进行调度。
  • 缓存队列: 在缓存中,可以使用链式队列来管理缓存的数据。每个数据可以以节点的形式加入队列,然后按照一定的容量规则进行淘汰。
  • UI消息队列: 在图形界面开发中,可以使用链式队列来管理UI的更新消息。每个消息都可以以节点的形式加入队列,然后按照先进先出的原则进行处理,保证UI的更新是有序的。
  • 日志队列: 在日志系统中,可以使用链式队列来管理日志的写入和读取。每条日志可以以节点的形式加入队列,然后按照先进先出的原则进行写入和读取,保证日志的顺序性。

四、链式队列的实现

3.1 结构体创建

typedef int datatype;

// 定义链表节点结构体
typedef struct node {
    datatype data;          // 节点数据
    struct node *next;      // 指向下一个节点的指针
} listnode, *linklist;      // listnode为节点类型,linklist为指向节点的指针类型

// 定义链式队列结构体
typedef struct {
    linklist front, rear;   // 队列的前端和后端指针
} linkqueue;

3.2 队列的创建

算法思路:
①申请内存。
②初始化。
③返回值。

linkqueue *queue_create(){
	linkqueue *lq;
	if((lq = (linkqueue *)malloc(sizeof(linkqueue))) == NULL){
		printf("malloc linkqueue failed\n");
		return NULL;
	}

	lq->front = lq->rear = (linklist)malloc(sizeof(listnode));
	if(lq->front == NULL){
		printf("malloc node failed\n");
		return NULL;
	}
	lq->front->data = 0;
	lq->front->next = NULL;

	return lq;
}

3.3 入队

int enqueue(linkqueue *lq, datatype x){
	if(NULL == lq){
		printf("lq is NULL\n");
		return -1;
	}

	linklist p;
	if((p = (linklist)malloc(sizeof(listnode))) == NULL){
		printf("malloc node failed\n");
		return -1;
	}
	p->data = x;
	p->next = NULL;

	lq->rear->next = p;
	lq->rear = p;

	return 0;
}

3.4 出队

datatype dequeue(linkqueue *lq){
	linklist p;

	if(NULL == lq){
		printf("lq is NULL\n");
		return -1;
	}

	p = lq->front;
	lq->front = p->next;
	free(p);
	p = NULL;

	return lq->front->data;
}

3.5 判断队列是否空

int queue_empty(linkqueue *lq){
	if(NULL == lq){
		printf("lq is NULL\n");
		return -1;
	}		

	return (lq->front == lq->rear ? 1 : 0);
}

3.6 清除队列

int queue_clear(linkqueue *lq){
	linklist p;
	if(NULL == lq){
		printf("lq is NULL\n");
		return -1;
	}
	
	while(lq->front->next){
		p = lq->front;
		lq->front = p->next;
		printf("clear free:%d\n", p->data);
		free(p);
		p = NULL;
	}
	return 0;
}

3.7 释放队列

linkqueue * queue_release(linkqueue *lq){
	linklist p;

	if(NULL == lq){
		printf("lq is NULL\n");
		return NULL;
	}

	while(lq->front){
		p = lq->front;
		lq->front = p->next;
		printf("free:%d\n", p->data);
		free(p);
	}

	free(lq);
	lq = NULL;

	return NULL;
}
  • 14
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值