1. 程式人生 > 其它 >佇列之迴圈佇列詳解(C語言版)

佇列之迴圈佇列詳解(C語言版)

技術標籤:資料結構與演算法資料結構

文章目錄


前言

大家好,越努力,越幸運。本篇文章小猿將跟您分享資料結構佇列中的迴圈佇列,希望對您有所幫助。

在這裡插入圖片描述

一、迴圈佇列的定義

順序佇列在使用過程中容易出現虛假的滿狀態, 為了解決這個問題,就產生了一個較巧妙的方法,將順序佇列臆造為一個環狀的空間,稱之為迴圈佇列。迴圈佇列中指標和佇列元素之間的關係不變,我們只需要利用模運算就可以很容易實現指標的迴圈移動。但是迴圈佇列中存在一個問題,在迴圈佇列中只憑頭指標front等於尾指標rear無法判別佇列空間是“空”還是“滿”,可有兩種處理方法:其一是另設一個標誌位以區別佇列是“空”還是“滿”;其二是少用一個元素空間,約定以“佇列頭指標在佇列尾指標的下一位置(指環狀的下一位置)上”作為佇列呈“滿”狀態的標誌。此處使用方法二來解決這個問題。

二、迴圈佇列的結構

結構圖
在這裡插入圖片描述

程式碼描述

//資料型別
#define ElemType int
//佇列的最大空間
#define MAXSIZE 8
//佇列的管理結構
typedef struct Queue
{
	ElemType *base; //指向佇列空間的基址
	int       front; //頭指標
	int       rear; //尾指標
}Queue;

三、迴圈佇列的常用操作

初始化

//佇列初始化
void InitQueue(Queue *Q)
{
	//為佇列分配儲存空間
	Q->base = (ElemType *)malloc(sizeof(ElemType) * MAXSIZE)
; assert(Q->base != NULL); //初始時佇列為空,頭指標和尾指標都指向0位置 Q->front = Q->rear = 0; }

入隊

//入隊操作
void EnQueue(Queue *Q, ElemType x)
{
	//判斷迴圈佇列是否已滿
	if(((Q->rear+1)%MAXSIZE) == Q->front)
		return;
	//佇列未滿,將資料入隊
	Q->base[Q->rear] = x;
	//更改尾指標的指向
	Q->rear = (Q->rear+1)%MAXSIZE;
}

出隊

//出隊操作
void
DeQueue(Queue *Q) { //判斷迴圈佇列是否為空 if(Q->front == Q->rear) return; //如果非空,實現可迴圈出隊 Q->front = (Q->front+1)%MAXSIZE; }

列印佇列資料

//列印迴圈佇列中的資料
void ShowQueue(Queue *Q)
{
	//遍歷迴圈佇列中的元素,並將資料列印
	for(int i=Q->front; i!=Q->rear;)
	{
		printf("%d ",Q->base[i]);
		//此操作是為了實現迴圈遍歷
		i = (i+1)%MAXSIZE;
	}
	printf("\n");
}

獲取隊頭元素

//獲取隊頭元素
void GetHdad(Queue *Q, ElemType *v)
{
	//判斷迴圈佇列是否為空
	if(Q->front == Q->rear)
		return;
	//如果佇列不為空,獲取隊頭元素
	*v = Q->base[Q->front];
}

求佇列長度

//獲取佇列長度(元素個數)
int Length(Queue *Q)
{
	//計算尾指標位置與頭指標位置的差距
	int len= Q->rear - Q->front;
	//如果為正數,那麼len就是佇列的長度;如果為負數,那麼MAXSIZE+len才是佇列的長度
	len = (len>0) ? len : MAXSIZE+len;
	return len;
}

清空佇列

//清空佇列
void ClearQueue(Queue *Q)
{
	//將隊頭指標和隊尾指標都置為0
	Q->front = Q->rear = 0;
}

銷燬佇列

//銷燬佇列
void DestroyQueue(Queue *Q)
{
	//釋放佇列的儲存空間
	free(Q->base);
	//將佇列基址置空
	Q->base = NULL;
}

結語

對迴圈佇列的介紹就到這裡啦,希望這篇文章能給予你一些幫助,感謝各位人才的:點贊、收藏和評論,我們下次見。
在這裡插入圖片描述

附錄

以下提供迴圈佇列的測試程式碼

SeqQueue.h

#ifndef __SEQQUEUE_H__
#define __SEQQUEUE_H__

#include<stdio.h>
#include<malloc.h>
#include<assert.h>
//資料型別
#define ElemType int
//佇列的最大空間
#define MAXSIZE 8
//佇列的管理結構
typedef struct Queue
{
	ElemType *base; //指向佇列空間的基址
	int       front; //頭指標
	int       rear; //尾指標
}Queue;

void InitQueue(Queue *Q);
void EnQueue(Queue *Q, ElemType x);
void ShowQueue(Queue *Q);
void DeQueue(Queue *Q);

void GetHdad(Queue *Q, ElemType *v);
int Length(Queue *Q);
void ClearQueue(Queue *Q);
void DestroyQueue(Queue *Q);


#endif //__SEQQUEUE_H__

SeqQueue.cpp

#include"SeqQueue.h"

//佇列初始化
void InitQueue(Queue *Q)
{
	//為佇列分配儲存空間
	Q->base = (ElemType *)malloc(sizeof(ElemType) * MAXSIZE);
	assert(Q->base != NULL);
	//初始時佇列為空,頭指標和尾指標都指向0位置
	Q->front = Q->rear = 0;
}

//入隊操作
void EnQueue(Queue *Q, ElemType x)
{
	//判斷迴圈佇列是否已滿
	if(((Q->rear+1)%MAXSIZE) == Q->front)
		return;
	//佇列未滿,將資料入隊
	Q->base[Q->rear] = x;
	//更改尾指標的指向
	Q->rear = (Q->rear+1)%MAXSIZE;
}

//列印迴圈佇列中的資料
void ShowQueue(Queue *Q)
{
	//遍歷迴圈佇列中的元素,並將資料列印
	for(int i=Q->front; i!=Q->rear;)
	{
		printf("%d ",Q->base[i]);
		//此操作是為了實現迴圈遍歷
		i = (i+1)%MAXSIZE;
	}
	printf("\n");
}

//出隊操作
void DeQueue(Queue *Q)
{
	//判斷迴圈佇列是否為空
	if(Q->front == Q->rear)
		return;
	//如果非空,實現可迴圈出隊
	Q->front = (Q->front+1)%MAXSIZE;
}

//獲取隊頭元素
void GetHdad(Queue *Q, ElemType *v)
{
	//判斷迴圈佇列是否為空
	if(Q->front == Q->rear)
		return;
	//如果佇列不為空,獲取隊頭元素
	*v = Q->base[Q->front];
}

//獲取佇列長度(元素個數)
int Length(Queue *Q)
{
	//計算尾指標位置與頭指標位置的差距
	int len= Q->rear - Q->front;
	//如果為正數,那麼len就是佇列的長度;如果為負數,那麼MAXSIZE+len才是佇列的長度
	len = (len>0) ? len : MAXSIZE+len;
	return len;
}


//清空佇列
void ClearQueue(Queue *Q)
{
	//將隊頭指標和隊尾指標都置為0
	Q->front = Q->rear = 0;
}

//銷燬佇列
void DestroyQueue(Queue *Q)
{
	//釋放佇列的儲存空間
	free(Q->base);
	//將佇列基址置空
	Q->base = NULL;
}

Main.cpp

#include"SeqQueue.h"

void main()
{
	Queue Q;
	InitQueue(&Q);

	for(int i=1; i<=8; ++i)
	{
		EnQueue(&Q, i);
	}
	ShowQueue(&Q);
	DeQueue(&Q);
	EnQueue(&Q,10);
	DeQueue(&Q);
	EnQueue(&Q,20);
	ShowQueue(&Q);
	printf("%d\n",Length(&Q));
}