コメントの読み取り、コードの入力、データ構造-循環キューの学習

Xiaomengxinは今日、循環キューとは何かについて皆に話しました。さっそく始めましょう。

循環キューを使用してキューの誤った完全状態を解決できる場合、誤った完全状態とは何ですか?

現在のシーケンシャルキューに割り当てられている最大スペースが6であるとすると、キューのテールポインターが5の添え字から6の添え字に変化すると(6の添え字は実際には存在しません)、キューはこの時点でいっぱいですが、デキュー操作は引き続き実行できます。キューはシーケンシャルスタックのように配列スペースを格納および再割り当てできないため、キューの実際に使用可能なスペースがいっぱいではありません。

循環キューは、図に示すように、順次キューを循環キュースペースに構築します。
ここに画像の説明を挿入

注:

このポインタは、フロントでの時間、= REARポインタでは、キューが満杯または空のスペースないと判断され、2つの解決策があります
また、キューが満杯または空のスペースであるフラグビットがあります1。
2.小さいスペースに合意しています」キューヘッドポインターは、キューフルステータスフラグとしてキューテールポインターの隣にあります。

さあ!図に示すように、栗を取ってみましょう:
[Case 1]
ここに画像の説明を挿入
初期化、チームヘッドポインターの前部とテールポインターの後部はすべて0の添え字を指します。
データ要素1が格納されると、チームテールの後部ポインターは0の添え字から1の添え字になります。
データ要素2が格納されている場合、テールポインターの後部は1添え字から2添え字までです。
データ要素3が格納されている場合、テールポインター後部は2添え字から3添え字までです。
データ要素4が格納されている場合、 3インデックスから後ろのテールポインターは4インデックスを指します

データ要素8が格納されている場合、7インデックスから後ろのテールポインターは0インデックスを指します(キューがいっぱいです)
フロントポインターとリアポインターを判断する方法後方が一致する場合、キューは空ですか、それともいっぱいですか?フラグを使用してチームヘッドポインターフロントとチームテールポインターリアの一致状態をマークする場合、フラグ= 0の場合:キューは空であり、フラグ= 1の場合、キューはいっぱいであることを規定します。

【事例2】
ここに画像の説明を挿入
データを格納せずに添え字7個分のスペースを残すデータ要素7が添え字6個分のスペースに入ると、テールポインタ後方が添え字7個分のスペースを指す(現時点では添え字7個分のスペースは空) )、理論的には、8つのスペースは7つのスペースのみを使用しますが、論理的には、現時点ではキューがいっぱいであることを規定しています。リア+ 1、チームヘッドポインターの前部がチームテールポインターの後部と一致している場合、この時点でキュースペースロジックがいっぱいであることを示します。最初に、チームヘッドポインターが指すスペースの要素をチームの外に置き、チームヘッドポインターが1の添え字に進みます。このとき、要素は添え字7でスペースに入力され、チームポインターの後部が前方に移動します(0の添え字を指します)。後部+ 1の場合、チームヘッドポインターの前部とチームテールポインターの後部が再び一致し、このときのキュースペースのロジックを示します。再び満杯になり、順番に前後に繰り返し、チームを離れます—>チームヘッドの頭が前方に移動します>>チームに参加します>>チームの尾が後方ポインターを前方に移動します(判定条件が後方+ 1の後で、チームヘッドの前方とチームポインターの尾)リアが一致してもしなくても、チームに参加し続けることができます)。

ただし、コンピューターには循環ストレージスペースがなく、直線的に保存されます。コンピューターは、テールポインターとヘッドポインターが再びオーバーラップするタイミングをどのように決定しますか?

————— OK!つまり、モジュロ演算——————

特定のモジュラー演算がどのように実装されるかによって、テキストは青白くて弱く見えますが、それでもその文はコードを実行し、ゆっくりと実現します!

#include <stdio.h>
#include <malloc.h>
#include <assert.h>

#define MAXSIZE 8//定义队列初始化存放8个数据元素
typedef int ElmeType;

/*给出顺序队列的结构*/
typedef struct Queue
{
	ElmeType *base;//指针base指向有效的队列空间
	int      front;//队头指针
	int      rear;//队尾指针指向下一个有效的空间
}Queue;

/*初始化顺序队列*/
void InitQueue(Queue *Q)
{
	Q->base=(ElmeType *)malloc(sizeof(ElmeType)*MAXSIZE);//开辟队列空间
	assert(Q->base!=NULL);//断言——是否开辟空间成功
	Q->front=Q->rear=0;//队头指针和队尾指针都指向队列的0下标,此时队列为空
}

/*入队*/
void EnQueue(Queue *Q,ElmeType x)
{
//数据入队后,队尾指针从当前空间指向下一个有效的空间,此时称队尾指针是伪指针;
//当伪指针所指下标+1后正好等于队列空间容量时,此时我们希望伪指针可以重新指向队头,而不是出界,于是进行模运算;

//(Q->rear+1)%MAXSIZE——若模为0,则伪指针恰好指向队列的最后一个有效空间,我们需要让此时的伪指针重新指向0下标而不是最后一个有效空间;
//(始终都要将队列最后一个有效空间空出)循环开始:
	if((Q->rear+1)%MAXSIZE==Q->front)//若伪指针所指下标+1与队头指针指向相同的下标,此时判断为队列逻辑已满
	return;//返回,理论上队列保留了队列最后一个有效空间
	Q->base[Q->rear]=x;//否则队列逻辑不满,继续在队尾指针所指下标进行入队,入队完成后,队尾指针又从当前空间指向下一个有效的空间
	Q->rear=(Q->rear+1)%MAXSIZE;//当逻辑空间满后,模运算实现队尾指针重新指向0下标而不是最后一个有效空间;
}

/*展示顺序队列元素*/
void ShowQueue(Queue *Q)
{
	printf("顺序队列中存放的元素:");
	for(int i=Q->front;i!=Q->rear;)
	{
		printf("%d ",Q->base[i]);//依次打印队头指针所指下标中的数据到队尾指针所指下标中的数据
		i=(i+1)%MAXSIZE;//循环打印,7下标不能打印,重新回到0下标(循环时,队尾下标-队头下标=-1)
	}
	printf("\n");
}

/*出队*/
void DeQueue(Queue *Q)
{
//出队一个元素,队头指针指向下一个有效的数据元素
	if(Q->front==Q->rear)//队头队尾指向相同,队列为空
		return;
	Q->front=(Q->front+1)%MAXSIZE;//队头指针循环,模运算实现队头指针重新指向0下标而不是最后一个有效空间;
}

/*取队头元素*/
void GetHead(Queue *Q,ElmeType *v)//指针v带回队头元素
{
//要获取队头,前提是队列不空
	if(Q->front==Q->rear)//队列为空
	return;
	*v=Q->base[Q->front];//必须在base所指的空间里取元素
}

/*顺序队列的长度*/
int Length(Queue *Q)
{
	return (Q->rear - Q->front);
	//下标0开始存放数据,进队后,队尾指针指向下一个有效的新空间
	//队列中元素的个数正好是队尾队头所指的下标之差
	//但是当队列逻辑空间满后,再存储数据需要先出队,再进行入队,此时队尾队头所指的下标之差为-1
}

/*清除顺序队列*/
void ClearQueue(Queue *Q)
{
	Q->front=Q->rear=0;//队列置为空
}

/*销毁顺序队列*/
void DestroyQueue(Queue *Q)
{
	free(Q->base);//释放base所指的队列空间
	Q->base=NULL;//预防野指针
}
/**/

void main()
{
	Queue Q;
	ElmeType e;//定义队头元素
	InitQueue(&Q);//&Q是传入队列的地址
	printf("将1,2,3,4,5,6,7,8依次入队\n");
	for(int i=1;i<=8;++i)
	{
		EnQueue(&Q,i);
	}
	ShowQueue(&Q);
	printf("顺序队的长度为:%d\n",Length(&Q));
	printf("\n");
	printf("进行出队\n");
	DeQueue(&Q);
	ShowQueue(&Q);
	GetHead(&Q,&e);
	printf("队头元素为:%d\n",e);
	printf("\n");
	printf("将元素10入队\n");
	EnQueue(&Q,10);
	ShowQueue(&Q);
	printf("\n");
	printf("进行出队\n");
	DeQueue(&Q);
	ShowQueue(&Q);
	GetHead(&Q,&e);
	printf("队头元素为:%d\n",e);
	printf("\n");
	printf("将元素20入队\n");
	EnQueue(&Q,20);
	ShowQueue(&Q);
	printf("\n");
	ClearQueue(&Q);
	DestroyQueue(&Q);
}

演算結果:
ここに画像の説明を挿入

元の記事23件を公開 賞賛された46件 2056回の訪問

おすすめ

転載: blog.csdn.net/weixin_43964458/article/details/105399987