佇列之迴圈佇列詳解(C語言版)
阿新 • • 發佈:2021-02-16
文章目錄
前言
大家好,越努力,越幸運。本篇文章小猿將跟您分享資料結構佇列中的迴圈佇列,希望對您有所幫助。
一、迴圈佇列的定義
順序佇列在使用過程中容易出現虛假的滿狀態, 為了解決這個問題,就產生了一個較巧妙的方法,將順序佇列臆造為一個環狀的空間,稱之為迴圈佇列。迴圈佇列中指標和佇列元素之間的關係不變,我們只需要利用模運算就可以很容易實現指標的迴圈移動。但是迴圈佇列中存在一個問題,在迴圈佇列中只憑頭指標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));
}