數據結構_循環隊列(C語言)

(一)循環隊列圖文解析

隊列,顧名思義就像我們平時排隊打飯一樣,隊尾有人不斷來排隊打飯,隊頭不斷有人打完飯離開隊頭

順序隊列用順序存儲結構,即數組存儲,分別包含倆個變量front和rear分別代表隊頭和隊尾,爲了防止數組越界溢出,我們將順序隊列變成一個環狀的空間,即循環隊列,超出數組界隊尾重新回到數組的開頭,以此防止數組溢出報錯。
在這裏插入圖片描述
通過取模,我們可以讓順序隊列的存儲空間循環使用;假設數組最大空間爲6,當Q.front=4,Q.rear=5,則隊列長度爲1,未達到最大隊列長度,如果我們還需要入隊,此刻隊尾不能再繼續在數組中添加數據元素了,那麼我們可以使Q.rear=(Q.rear+1)%6,即Q.rear=0,重新回到數組的初始地址,繼續入隊,於是這就形成了循環隊列。

(二) 循環隊列代碼解析

(1) 循環隊列的基本操作

1.1 循環隊列的存儲結構

#define MAXQSIZE 100
typedef struct{
	int *base;//存儲數據元素的數組
	int front;//頭指針
	int rear;//尾指針
}SqQueue;

1.2 循環隊列的初始化

void InitQueue(SqQueue &Q)
{
	Q.base=(int*)malloc(MAXQSIZE*sizeof(int));//爲隊列分配空間
	if(!Q.base)
		printf("內存分配失敗!\n");
	else
		Q.front=Q.rear=0;//初始化頭尾指針都爲0,隊列爲空
}

1.2 循環隊列的入隊

void EnQueue(SqQueue &Q,int e)
{
	if((Q.rear+1)%MAXQSIZE==Q.front)
		printf("隊滿!\n");
	else
	{
		Q.base[Q.rear]=e; //隊尾入隊,給隊尾數據賦值
		Q.rear=(Q.rear+1)%MAXQSIZE;	//隊尾指針加1
	}
}

1.3 循環隊列的出隊

void DeQueue(SqQueue &Q,int &e)
{
	if(Q.front==Q.rear)
		printf("隊空!");
	else
	{
		e=Q.base[Q.front];//隊頭出隊,清除隊頭數據
		Q.front=(Q.front+1)%MAXQSIZE;//隊頭指針加1
	}
}

1.4 循環隊列的長度

int QueueLength(SqQueue Q)
{
	return (Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;
	//對於循環隊列,隊尾隊頭的差值也有可能爲負值,所以加上MAXQSIZE再與MAXQSIZE取模
}

1.5 循環隊列的頭元素

int GetHead(SqQueue Q)
{
	return Q.base[Q.front];
}

1.6 循環隊列的尾元素

int GetTail(SqQueue Q)
{
	return Q.base[Q.rear-1];
}

(2) 循環隊列源代碼及測試

2.1 源代碼:

#include<stdio.h>
#include<malloc.h>
#define MAXQSIZE 100
typedef struct{
	int *base;
	int front;
	int rear;
}SqQueue;


void InitQueue(SqQueue &Q)
{
	Q.base=(int*)malloc(MAXQSIZE*sizeof(int));
	if(!Q.base)
		printf("內存分配失敗!\n");
	else
		Q.front=Q.rear=0;
}

void EnQueue(SqQueue &Q,int e)
{
	if((Q.rear+1)%MAXQSIZE==Q.front)
		printf("隊滿!\n");
	else
	{
		Q.base[Q.rear]=e;
		Q.rear=(Q.rear+1)%MAXQSIZE;
	}
}
void DeQueue(SqQueue &Q,int &e)
{
	if(Q.front==Q.rear)
		printf("隊空!");
	else
	{
		e=Q.base[Q.front];
		Q.front=(Q.front+1)%MAXQSIZE;
	}
}
int QueueLength(SqQueue Q)
{
	return (Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;
}

int GetHead(SqQueue Q)
{
	return Q.base[Q.front];
}
int GetTail(SqQueue Q)
{
	return Q.base[Q.rear-1];
}
int main()
{
	int e;
	SqQueue Q;
	InitQueue(Q);

	printf("依次入隊1,2,3\n");
	EnQueue(Q,1);
	EnQueue(Q,2);
	EnQueue(Q,3);
	printf("隊列長度:%d\n",QueueLength(Q));
	printf("隊頭元素:%d\n",GetHead(Q));
	printf("隊尾元素:%d\n",GetTail(Q));

	printf("出隊一次\n");
	DeQueue(Q,e);
	printf("隊列長度:%d\n",QueueLength(Q));
	printf("隊頭元素:%d\n",GetHead(Q));
	printf("隊尾元素:%d\n",GetTail(Q));
	return 0;
}

2.2 測試結果:

測試環境 : Windows 10
編譯軟件 : Visual C++ 6.0

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章