12 队列的实现-顺序队列与链式队列

1. 队列

队列是限制在两端进行插入操作和删除操作的线性表。
允许进行存入操作的一端称为“队尾” 允许进行删除操作的一端称为“队头” 当线性表中没有元素时,称为“空队”。
特点 :先进先出(FIFO)。

2. 循环队列

规定:front指向队头元素的位置; rear指向队尾元素的下一个位置。
在队列操作过程中,为了提高效率,以调整指针代替队列元素的移动,并将数组作为循环队列的操作空间。
为区别空队和满队,满队元素个数比数组元素个数少一个
在这里插入图片描述

3. 顺序队列

需要进行判满判空
sq->front = sq->rear = 0; // 空队列
(sq->rear + 1) % N == sq->front // 判断队满

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

sequeue * queue_create(); // 创建
int enqueue(sequeue *sq,datatype value); // 入队
datatype dequeue(sequeue *sq); // 出队
int queue_empty(sequeue *sq); // 判读空队
int queue_full(sequeue *sq); // 判读队满
int queue_clear(sequeue *sq); // 清空队列
sequeue * queue_free(sequeue *sq); // 释放队列

实现框架
sequeue.h

typedef int datatype;
#define N 128

typedef struct{
	datatype data[N];
	int front;
	int rear;
}sequeue;

sequeue * queue_create();                // 创建
int enqueue(sequeue *sq,datatype value); // 入队
datatype dequeue(sequeue *sq);           // 出队
int queue_empty(sequeue *sq);            // 判读空队
int queue_full(sequeue *sq);             // 判读队满
int queue_clear(sequeue *sq);            // 清空队列
sequeue * queue_free(sequeue *sq);       // 释放队列

sequeue.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sequeue.h"

sequeue * queue_create()
{
	sequeue *sq;

	if((sq = (sequeue *)malloc(sizeof(sequeue))) == NULL){
		printf("malloc failed\n");
		return NULL;
	}

	memset(sq->data, 0 ,sizeof(sq->data));
	// 这一步很关键
	sq->front = sq->rear = 0; // 空队列
	
	return sq;
}

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

	if((sq->rear + 1) % N == sq->front){ //队满
		printf("sequeue is full\n");
		return -1;
	}

	sq->data[sq->rear] = value;
	sq->rear = (sq->rear+1) % N;

	return 0;

}

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

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

	return t;
}

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

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

}

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

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

	return 0;
}

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

	free(sq);
	//需要置空,不然成野指针
	sq = NULL;
	
	return NULL;
}

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

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

test.c

#include <stdio.h>
#include "sequeue.h"

int main(int argc, const char *argv[])
{
	sequeue *sq;
	
	sq = queue_create();
	if(sq == NULL){
		return -1;
	}

	enqueue(sq,10);
	enqueue(sq,20);
	enqueue(sq,30);
	enqueue(sq,40);
	enqueue(sq,50);
	enqueue(sq,666);

	while(!queue_empty(sq)){
		printf("dequeue:%d\n",dequeue(sq));
	
	}

	queue_free(sq);


	return 0;
}

4. 链式队列

插入操作在队尾进行,删除操作在队头进行,由队头指针和队尾指针控制队列的操作。
问题:链式队列有假溢出么?链式队列需要判空判满么?为什么?
答:
(1)没有假溢出。因为在进行队列的操作时,只能从队尾进行入队,队头进行出队。
(2)需要判空,因为链式队列可能没有元素。不需要判满,因为入队是从队尾实现,链式队列可以申请动态空间。

结构体说明:
typedef int datatype;

typedef struct node{
datatype data;
struct node * next;
}listnode,*linklist;

typedef struct{
linklist front;
linklist rear;
}linkqueue;

创建空队列 :
linkqueue_t *CreateQueue()
{
linkqueue_t *lq = (linkqueue_t *)malloc(sizeof(linkqueue_t));
lq->front = lq->rear = (linklist_t)malloc(sizeof(linknode_t));
lq->front->next = NULL ; /置空队/
return lq; /返回队列指针/
}

判断队列空 :
int EmptyQueue(linkqueue_t *lq) {
return ( lq->front = = lq->rear) ;
}

入队 :
void EnQueue (linkqueue_t *lq, data_t x)
{
加粗样式 lq->rear->next = (linklist_t)malloc(sizeof(linknode_t)) ;
lq->rear = lq->rear->next; /修改队尾指针/
lq->rear->data = x ; /新数据存入新节点/
lq->rear->next = NULL ; /新节点为队尾/
return;
}

出队
data_t DeQueue(linkqueue_t *lq)
{
data_t x;
linklist_t p; /定义一个指向队头结点的辅助指针/
p = lq->front->next ; /将它指向队头结点/
lq->front->next = p->next ; /*删除原先队头结点
x = p->data;
free§ ; /释放原队头结点/
if (lq->front->next == NULL) lq->rear = lq->front;
return x;
}

实现框架
linkqueue.h

typedef int datatype;

typedef struct node{
	datatype data;
	struct node * next;
}listnode,*linklist;

typedef struct{
	linklist front;
	linklist rear;
}linkqueue;

linkqueue * queue_create();
int enqueue(linkqueue *lq,datatype x);
datatype dequeue(linkqueue *lq);
int queue_empty(linkqueue *lq);
int queue_clear(linkqueue *lq);
linkqueue * queue_free(linkqueue *lq); //返回linkqueue * 目的是防止程序还进行其他队列操作

linkqueue.c

#include <stdio.h>
#include <stdlib.h>
#include "linkqueue.h"

linkqueue * queue_create()
{
	linkqueue *lq;

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

	// 两次malloc不一样
	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;
	
}


int enqueue(linkqueue *lq,datatype x)
{
	linklist p;

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

	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;

}

datatype dequeue(linkqueue *lq)
{
	linklist p;

	if(lq == NULL){
		printf("lq is NULL\n");
		return -1;
	}
	
	p = lq->front;
	lq->front = p->next;
	free(p);
	p = NULL;

	return (lq->front->data);
}

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

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

}

int queue_clear(linkqueue *lq)
{
	linklist p;

	if(lq == NULL){
		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;

}

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

	if(lq == NULL){
		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;

}

test.c

#include <stdio.h>
#include "linkqueue.h"


int main(int argc, const char *argv[])
{
	linkqueue *lq;

	lq = queue_create();
	if (lq == NULL) 
		return -1;

	enqueue(lq, 10);
	enqueue(lq, 20);
	enqueue(lq, 30);
	enqueue(lq, 40);

	//while (!queue_free_empty(lq)) {
	printf("dequeue:%d\n", dequeue(lq));
	}
	queue_clear(lq);
	
	lq = queue_free(lq);
	enqueue(lq, 50);
	
	return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值