分享一下自己写的数据结构的顺序循环队列嗯

分享一下自己写的数据结构的顺序队列嗯

很多大学刚学数据结构的小伙伴,对于这门课程理解不够深刻,在上机实验中会遇到各种困难,作为过来的小萌新,写下这篇blog希望对需要的朋友有所帮助。咳咳,话不多说,让我们来看看(顺序)队列叭!

什么是队列

详见数据结构课本。通俗的说是一种具有先进先出特性的线性表。
在许多场景下,非常实用。

详细代码如下

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

#define TRUE 1
#define FALSE 0

#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2

typedef int Status;
Status表示一种状态值

typedef int QElemType;//定义队列的结构体

#define QUEUE_INIT_SIZE 3 //定义队列的初始大小
#define QUEUEINCREMENT 1 //定义队列的增量

//以上是数据结构用的前置条件

typedef struct {
	QElemType *base;
	int front;
	int rear;
	int MAXQSIZE;
}SqQueue;

//定义队列的结构体此处我写的是顺序队列 链表型的队列代码更简单

//由于我们要做的是循环队列
Status InitQueue(SqQueue &Q)
{
	Q.base = (QElemType *)malloc(QUEUE_INIT_SIZE*sizeof(QElemType));
	if(!Q.base) exit(OVERFLOW);
	Q.front = Q.rear = 0;
	Q.MAXQSIZE=QUEUE_INIT_SIZE;
	return OK;
}

//判断队列是否为空 若空返回TRUE 不空则返回FALSE;
Status QueueEmpty(SqQueue Q)
{
	if(Q.front==Q.rear)
		return TRUE;
	else return FALSE;
}

//输出函数
void putoutQueue(SqQueue Q)
{
	if(!QueueEmpty(Q))
	{
		printf("当前队列的元素有:");
		int i = Q.front;
		while (i != Q.rear)
		{
			printf("%3d",Q.base[i]);
			i=(i+1)%Q.MAXQSIZE;
		}
		printf("\n");
	}
	else printf("当前队列为空\n");
}

//求队列长度
int QueueLength(SqQueue Q)
{
	return (Q.rear - Q.front + Q.MAXQSIZE)%Q.MAXQSIZE;
}


// 循环队列,的插入元素问题 等会解释
Status EnQueue(SqQueue &Q,QElemType e)
{
	int i,j,k;
	if((Q.rear+1)%Q.MAXQSIZE == Q.front)	//队列满 追加空间
	{
		Q.base = (QElemType *)realloc(Q.base,(Q.MAXQSIZE + QUEUEINCREMENT)* sizeof(QElemType));
		if(!Q.base)
			exit(OVERFLOW);		//分配内存失败
		if(Q.rear<Q.front)		//若rear<front  将front之后元素移动到新增空间
		{		//
			for(i=Q.MAXQSIZE-1,j=Q.MAXQSIZE+QUEUEINCREMENT-1;i>=Q.front;i--,j--)	
				Q.base[j]=Q.base[i];			
			k=Q.MAXQSIZE-Q.front;
			Q.MAXQSIZE+=QUEUEINCREMENT;
			Q.front=Q.MAXQSIZE-k;
		}
		else
			Q.MAXQSIZE+=QUEUEINCREMENT;
	}
	Q.base[Q.rear]=e;
	Q.rear = (Q.rear+1)%Q.MAXQSIZE;
	return OK;
}

Status DeQueue(SqQueue &Q,QElemType &e)
{
	if(Q.front==Q.rear)
		return ERROR;
	e=Q.base[Q.front];
	Q.front = (Q.front+1)%Q.MAXQSIZE;
	return OK;
}

Status GetHead(SqQueue &Q,QElemType &e)
{
	if(Q.front==Q.rear)
		return ERROR;
	e=Q.base[Q.front];
	return OK;
}

void ClearQueue(SqQueue &Q)
{
	QElemType e;
	while(!QueueEmpty(Q))
		DeQueue(Q,e);
	printf("清空完成\n");
}


void assign(SqQueue &Q)
{
	int m,i;
	QElemType e;
	printf("输入队列中元素个数: ");
	scanf("%d",&m);
	for(i=0;i<m;i++)
	{
		printf("请输入元素: ");
		scanf("%d",&e);
		EnQueue(Q,e);
	}

}
void feibo(SqQueue &Q,int k)
{
	InitQueue(Q);
	for(int i=0;i<k;i++)
	{
		if(i<2)			//出口
		{
			Q.base[Q.rear] = 1;
			Q.rear = (Q.rear+1)%Q.MAXQSIZE;
		}
		else
		{
			if((Q.rear+1)%Q.MAXQSIZE == Q.front)	//队列满 追加空间
			{
				Q.base = (QElemType *)realloc(Q.base,(Q.MAXQSIZE + QUEUEINCREMENT)* sizeof(QElemType));
				if(!Q.base)
					exit(OVERFLOW);		//分配内存失败

				//
				int a,b;
				if(Q.rear<Q.front)		//若rear<front  将front之后元素移动到新增空间
				{		//
					for(a=Q.MAXQSIZE-1,b=Q.MAXQSIZE+QUEUEINCREMENT-1;a>=Q.front;a--,b--)	
						Q.base[b]=Q.base[a];			
					int m=Q.MAXQSIZE-Q.front;
					Q.MAXQSIZE+=QUEUEINCREMENT;
					Q.front=Q.MAXQSIZE-m;
				}
				else
					Q.MAXQSIZE+=QUEUEINCREMENT;
			}
	
			Q.base[Q.rear] = Q.base[(Q.rear-1)%Q.MAXQSIZE]+Q.base[(Q.rear-2)%Q.MAXQSIZE];
			Q.rear = (Q.rear+1)%Q.MAXQSIZE;
		}
	}
	putoutQueue(Q);
	printf("执行完毕\n");
	ClearQueue(Q);
}


Status menu()
{
	int code;
	printf("\n\t菜单\n");
	printf("1)--初始化队列\t2)--给队列赋值\n");
	printf("3)--入队\t4)--出队		\n");
	printf("5)--清空队列  \t6)--队列长度	\n");
	printf("7)--对头元素  \t8)--打印队列	\n");
	printf("9)--斐波那契  \t10)--退出		\n");
	printf("----------------------------------------\n");
	printf("你的选择:(1 ~ 10) ");
	fflush(stdin);
	scanf("%d",&code);
	return code;
}

void main()
{
	int code;
	int k,length;
	QElemType e;
	SqQueue Q;
	Q.base = NULL;
	do
	{
		code=menu();
		switch(code)
		{
		case 1: if(InitQueue(Q))
					printf("初始化成功\n");
				break;
		case 2:if(Q.base)
					assign(Q);
				else printf("请初始化队列\n");
				break;
		case 3: if(Q.base)
				{
					printf("请输入入队元素值: ");
					scanf("%d",&e);
					if(EnQueue(Q,e))
						printf("%d入队成功\n",e);
					else printf("入队失败\n");
				}
				else printf("请初始化队列\n");
				break;
		case 4: if(Q.base)
				{
					if(DeQueue(Q,e))
						printf("出队成功!出队元素是%d\n",e);
					else printf("出队失败\n");
				}
				else printf("请初始化队列\n");
				break;
		case 5: ClearQueue(Q);
				break;
		case 6: if(Q.base)
				{
					length = QueueLength(Q);
					printf("当前队列长度为:%d",length);
				}
				else printf("请初始化队列\n");
				break;
		case 7: if(Q.base)
				{
					if(GetHead(Q,e))
						printf("读取成功队头元素是%d\n",e);
					else printf("读取失败\n");
				}
				else printf("请初始化队列\n");
				break;
		case 8: if(Q.base)
					putoutQueue(Q);
				else printf("请初始化队列\n");
				break;
		case 9: printf("Thanks for using!\n");
				exit(0);
		}
	}while(code>=0 && code<10);
	printf("Thanks for using!\n");
}

我觉得吧已经鸽了很久的介绍。太不走心了。
简单解释下循环队列追加空间什么的问题。
经过和小伙伴们的讨论分析,对于满队列追加空间的重新定位有两种解决办法(一种是固定队首,一种是固定队尾),怎么理解具体看下图吧。画的不好见谅。
主要是为了解决有其他元素入出队列的队首队尾重定位
主要是为了解决有其他元素入出队列的队首队尾重定位问题
把一个定长的顺序列拉成一个圈,可以清晰的认知。队首队尾虽然在变,但在顺序列中是有固定的标号的。主要是计算新增空间后各个元素的位置应该怎么移动,队首队尾如何变化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值