队列的实现

队列,和一样,也是一种对数据的"存"和"取"有严格要求的线性存储结构。

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

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

栈有顺序存储和链式存储,那么队列也有顺序存储和链式存储。

与栈不同的是,队列元素的出列是在队头,即下表为0的位置,那就意味着队列中所有的元素都要向前移动。以保证队头不为空,此时时间复杂度为O(n)。

但是想一想,出队列时为什么元素非要全部移动呢?那么队头不一定要在下表为0的地方。

那么这时当front=rear时,队列就为空队列。

循环队列:把头尾相接的队列叫做循环队列。

#include <stdio.h>
#include<assert.h>
#define _CRT_SECURE_NO_WARNINGS

#define SIZE 10
typedef struct Queue
{
	int elem[SIZE];
	int front;
	int rear;
}Queue;

void InitQueue(Queue* queue)//初始化
{
	assert(queue != NULL);
	queue->front = 0;
	queue->rear = 0;
}
bool IsFull(Queue* queue)
{
	return (queue->rear + 1) % SIZE == queue->front;
}

bool Push(Queue* queue, int val)
{
	if (IsFull(queue))
	{
		return false;
	}
	queue->elem[queue->rear] = val;
	queue->rear = (queue->rear + 1) % SIZE;
	return true;
}

bool IsEmpty(Queue* queue)
{
	return queue->front == queue->rear;
}

bool Pop(Queue* queue, int *rtv)
{
	if (IsEmpty(queue))
	{
		return false;
	}
	if (rtv != NULL)
	{
		*rtv = queue->elem[queue->front];
	}
	queue->front = (queue->front + 1) % SIZE;
	return true;
}

void Show(Queue* queue)
{
	for (int i = queue->front; i != queue->rear; i = (i + 1) % SIZE)
	{
		printf("%d ", queue->elem[i]);
	}
	printf("\n");
}

int GetLength(Queue* queue)
{
	return (queue->rear - queue->front + SIZE) % SIZE;
}

void Clear(Queue* queue)
{
	queue->front = queue->rear;
}

int main()
{
	Queue qu;
	InitQueue(&qu);
	for (int i = 0; i < 10; i++)
	{
		Push(&qu, i);//0-8
	}
	Show(&qu);
	int tmp = 0;
	Pop(&qu, &tmp);
	printf("%d\n", tmp);//0
	Pop(&qu, &tmp);
	printf("%d\n", tmp);//1
	Pop(&qu, &tmp);
	printf("%d\n", tmp);//2
	Show(&qu);//3-8
	int len = GetLength(&qu);
	printf("%d\n", len);
	return 0;
}

接下来看一下链式队列。

队列的链式存储结构,就是线性表的简单单链表,只能尾进头出。

当队列为空时,front和rear都指向头结点。

#include <stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<time.h>
#define _CRT_SECURE_NO_WARNINGS

typedef struct QNode
{
	int data;
	struct QNode *next;
}node;

typedef struct Queue
{
	node* front;
	node* rear;
	int size;
}queue;



//初始化
void QueueInit(queue *q, node *p)
{
	assert(q != nullptr&&p != nullptr);
	q->front = q->rear = nullptr;
	p->next = nullptr;
	q->size = 0;
}

int getSize(queue *q)
{
	return q->size;
}

bool isEmpty(queue *q)
{
	if (q->size == 0)
	{
		return true;
	}

	return false;
}

//头插节点
void creatNode(queue *q,int val)
{
	QNode * get = (QNode *)malloc(sizeof(QNode));
	assert(get != nullptr);
	get->data = val; 
	get->next = nullptr;

	if (isEmpty(q))
	{
		q->front = get;
		q->rear = get;
	}
	else
	{
		q->rear->next = get;
		q->rear = get;
	}

	q->size++;
}

int getfront(queue *q)
{
	if (isEmpty(q))
	{
		printf("队列已为空");
		return 0;
	}
	return q->front->data;
}

node *del(queue *q)
{
	if (isEmpty(q))
	{
		printf("队列为空,删除错误!\n");
		return nullptr;
	}

	node *temp = q->front;
	q->front = temp->next;
	q->size--;

	return temp;
}


int getrear(queue *q)
{
	if (isEmpty(q))
	{
		printf("队列已为空");
		return 0;
	}
	return q->rear->data;
}

void clear(queue *q)
{
	q->front = NULL;
	q->rear = NULL;
	q->size = 0;
	printf("\n队列已清空!\n");
}

int main()
{
	queue lq;
	node p;
	QueueInit(&lq, &p);
	
	srand((unsigned)time(0));
	printf("入队30个元素\n");
	int i;
	for (i = 0; i < 20; i++)
		creatNode(&lq, rand() % 300);
	printf("队头元素为:%d\n", getfront(&lq));
	printf("队尾元素为:%d\n", getrear(&lq));
	printf("队列大小为:%d\n", getSize(&lq));
	
	for (i = 0; i < 20; i++)
	{
		if (i % 10 == 0)
			printf("\n");

		printf("%3d  ", *((int *)del(&lq)));
	}

	clear(&lq);
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值