数据结构中队列的实现(基于顺序表循环队列)

    在学习数据结构中,队列也是一个重要的数据结构,我们今天来用基于顺序表的队列(Queue),

在基于顺序表队列如果是不循环的顺序表,则在出队列时,时间复杂度是O(n),所以我们用循环队列来

实现,怎么解释基于循环顺序表的队列呢?

我们上图:

 

上图是在不循环顺序表中出队。这样不难看出时间复杂度不是很好。

所以我们来顺序循环队列,把顺序表让它循环利用。

看图


上图就是顺序表循环队列,a就是队首,d就是队尾,这样可以避免出队后移位,所以就时间复杂度更小。

那么咱们来看代码:

先是声明:

#pragma once

#include<stdio.h>
#define MAXREPOSITORY 10

#define TEAM_HEAD printf("\n===========%s==========\n",__FUNCTION__)

typedef char QueueType;

typedef struct SeqQueue{
	size_t count;
	size_t size;
	QueueType data[MAXREPOSITORY];
}SeqQueue;

// 初始化。
void InitSeqQueue(SeqQueue *seq);

// 入队。
void PushQueue(SeqQueue *seq,QueueType value);

// 出队。
void PopQueue(SeqQueue *seq);

// 取队首元素。
QueueType FindHead(SeqQueue *seq);

// 取队尾元素。
QueueType FindBottom(SeqQueue *seq);

// 销毁。
void DestoryQueue(SeqQueue *seq);

看定义:

#include"SeqQueue.h"


// 初始化。
void InitSeqQueue(SeqQueue *seq)
{
	if (seq == NULL)
	{
		return;
	}
	seq->size = 0;
	seq->count = 0;
}


// 入队。
void PushQueue(SeqQueue *seq,QueueType value)
{
	if (seq == NULL)
	{
		return;
	}
	if (seq->count == MAXREPOSITORY)
	{
		// 队列满。
		return;
	}
	// 当循环顺序队循环完但队未满时,进行循环。
	if (seq->size > MAXREPOSITORY) 
	{
		seq->size = 0;
	}
	seq->data[seq->size] = value;
	++seq->size;
	++seq->count;
}

// 出队。
void PopQueue(SeqQueue *seq)
{
	if (seq == NULL)
	{
		return;
	}
	if (seq->count == 0)
	{
		// 空队列。
		return;
	}
	--seq->count;
}


// 取队尾元素。
QueueType FindButtom(SeqQueue *seq)
{
	if (seq == NULL)
	{
		printf("输入错误\n");
		return 0;
	}
	if (seq->count == 0)
	{
		printf("队为空\n");
		return 0;
	}
	return seq->data[seq->size-1];
}


// 取队首元素。
QueueType FindHead(SeqQueue *seq)
{
	if (seq == NULL)
	{
		printf("输入错误\n");
		return 0;
	}
	if (seq->count == 0)
	{
		printf("队为空\n");
		return 0;
	}
	if (seq->size >= seq->count)
	{
		return seq->data[seq->size - seq->count];
	}
	else 
	{
		size_t tmp = seq->count-seq->size;
		size_t size = MAXREPOSITORY;
		return seq->data[size-tmp];
	}
}


// 销毁。
void DestoryQueue(SeqQueue *seq)
{
	if (seq == NULL)
	{
		return;
	}
	seq->size = 0;
	seq->count = 0;
}


//以下为测试代码


void PrintSeqQueue(SeqQueue *seq)
{
	if (seq == NULL)
	{
		return;
	}
	printf("[队尾]->");
	size_t count = 0;
	size_t size = seq->size;
	if (size != 0)
	{
		while (seq->count > count)
		{
			printf("[%c]->",seq->data[size-count-1]);
			count++;
		}
//		for (; count < seq->count; ++count)
//		{
//			printf("[%c]<-",seq->data[count]);
//		}
	}
	else
	{
		while (seq->count > count)
		{
			// 当循环到最大size但是队未满。
			if (size - count - 1 == 0)
			{
				printf("[%c]->",seq->data[size-count-1]);
				size = MAXREPOSITORY;
				count++;
			}
			else
			{
				printf("[%c]->",seq->data[size-count-1]);
				count++;
			}
		}
//		for(; count < seq->count; ++count)
//		{
//			if (size-count == 0)
//			{
//				size = MAXREPOSITORY;
//			}
//			printf("[%c]<-",seq->data[size-count]);
//		}
	}
	printf("[队头]\n");
}


// 顺序队的初始化。
void TestInitSeqQueue()
{
	TEAM_HEAD;
	SeqQueue seq;
	InitSeqQueue(&seq);
}

void TestPushQueue()
{
	TEAM_HEAD;
	SeqQueue seq;
	InitSeqQueue(&seq);
	PushQueue(&seq, 'a');
	PushQueue(&seq, 'b');
	PushQueue(&seq, 'c');
	PushQueue(&seq, 'd');
	PrintSeqQueue(&seq);
}

void TestPopQueue()
{
	TEAM_HEAD;
	SeqQueue seq;
	InitSeqQueue(&seq);
	PushQueue(&seq, 'a');
	PushQueue(&seq, 'b');
	PushQueue(&seq, 'c');
	PushQueue(&seq, 'd');
	PushQueue(&seq, 'e');
	PrintSeqQueue(&seq);
	PopQueue(&seq);
	PopQueue(&seq);
	PopQueue(&seq);
	PopQueue(&seq);
	PrintSeqQueue(&seq);
	PushQueue(&seq, 'f');
	PushQueue(&seq, 'g');
	PushQueue(&seq, 'h');
	PushQueue(&seq, 'i');
	PushQueue(&seq, 'j');
	PushQueue(&seq, 'k');
	PrintSeqQueue(&seq);
}

void TestFindButtom()
{
	TEAM_HEAD;
	SeqQueue seq;
	InitSeqQueue(&seq);
	PushQueue(&seq, 'a');
	PushQueue(&seq, 'b');
	PushQueue(&seq, 'c');
	PushQueue(&seq, 'd');
	PushQueue(&seq, 'e');
	PrintSeqQueue(&seq);
	QueueType ret = FindButtom(&seq);
	printf("except e actual %c",ret);
}

void TestFindHead()
{
	TEAM_HEAD;
	SeqQueue seq;
	InitSeqQueue(&seq);
	PushQueue(&seq, 'a');
	PushQueue(&seq, 'b');
	PushQueue(&seq, 'c');
	PushQueue(&seq, 'd');
	PushQueue(&seq, 'e');
	PrintSeqQueue(&seq);
	PopQueue(&seq);
	PopQueue(&seq);
	PopQueue(&seq);
	PopQueue(&seq);
	PrintSeqQueue(&seq);
	PushQueue(&seq, 'f');
	PushQueue(&seq, 'g');
	PushQueue(&seq, 'h');
	PushQueue(&seq, 'i');
	PushQueue(&seq, 'j');
	PushQueue(&seq, 'k');
	PrintSeqQueue(&seq);
	QueueType ret = FindHead(&seq);
	printf("except e actual %c",ret);
}

void TestDestoryQueue()
{
	TEAM_HEAD;
	SeqQueue seq;
	InitSeqQueue(&seq);
	PushQueue(&seq, 'a');
	PushQueue(&seq, 'b');
	PushQueue(&seq, 'c');
	PushQueue(&seq, 'd');
	PushQueue(&seq, 'e');
	PrintSeqQueue(&seq);
	DestoryQueue(&seq);
	PrintSeqQueue(&seq);
}

int main()
{
	TestInitSeqQueue();
	TestPushQueue();
	TestPopQueue();
	TestFindButtom();
	TestFindHead();
	TestDestoryQueue();
	return 0;
}

顺序表循环队列中,最需要注意的就是在顺序表到达最大位置时,

需要将size置为0,所以我们添加了一个变量count来计数队中元素的个数,

这样就可以判断队列是否满,还有在打印队列中也需要注意打印的顺序,是从前往后打印还是相反

要明确。我呢,是采用从队尾打印,也就是先打印呢size值大的。

如有不足请多多指教。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值