Leer comentarios, escribir código, aprender estructura circular de datos-cola

Xiaomengxin habló con todos hoy sobre lo que es una cola circular. Sin más preámbulos, ¡comencemos!

Si la cola circular se puede utilizar para resolver el estado completo falso de la cola, ¿cuál es el estado completo falso?

Suponiendo que el espacio máximo asignado en la cola secuencial actual es 6, cuando el puntero de cola de la cola cambia del subíndice 5 al subíndice 6 (el subíndice 6 en realidad no existe), significa que la cola está llena en este momento, pero la operación de eliminación de cola aún puede realizarse. La cola no puede almacenar y reasignar el espacio de la matriz como una pila secuencial, por lo que el espacio disponible real de la cola no está lleno.

La cola circular es construir la cola secuencial en un espacio de cola circular, como se muestra en la figura:
Inserte la descripción de la imagen aquí

Nota:

En este momento, cuando el puntero está delante = puntero TRASERO, la cola se determina no está lleno o vacío, hay dos soluciones:
1. También hay bits de una bandera cola está llena o el espacio vacío;
2. un menor espacio, han acordado " El puntero de la cola de la cola está al lado del puntero de cola de la cola "como el indicador de estado completo de la cola.

Vamos! Tomemos un castaño, como se muestra en la figura:
[Caso 1]
Inserte la descripción de la imagen aquí
Inicialización, la parte frontal del puntero de la cabeza del equipo y la parte posterior del puntero de la cola apuntan al subíndice 0;
cuando se almacena el elemento de datos 1, el puntero trasero de la cola del equipo del subíndice 0 al subíndice 1;
Cuando se almacena el elemento de datos 2, la parte posterior del puntero de cola es de 1 subíndice a 2 subíndice;
cuando se almacena el elemento de datos 3, la parte posterior del puntero de cola es de 2 subíndice a 3 subíndice;
cuando el elemento de datos 4 se almacena, El puntero trasero desde los 3 puntos de índice hasta el índice 4;
...
Cuando se almacena el elemento de datos 8, el puntero trasero desde los 7 puntos de índice hasta el índice 0; (la cola está llena)
cómo juzgar los punteros delantero y trasero Cuando la parte trasera coincide, ¿la cola está vacía o llena? Si usamos flag para marcar el estado de coincidencia del puntero de la cabeza del equipo delante y el puntero de la cola del equipo atrás, estipulamos que cuando flag = 0: la cola está vacía; cuando flag = 1, la cola está llena.

[Caso 2]
Inserte la descripción de la imagen aquí
Dejamos el espacio de 7 subíndices sin almacenar datos. Cuando el elemento de datos 7 ingresa al espacio de 6 subíndices, el puntero posterior apunta al espacio de 7 subíndices (el espacio de 7 subíndices está vacío en este momento) ), Teóricamente, 8 espacios solo usan 7 espacios, pero lógicamente estipulamos que la cola está llena en este momento. Cuando rear + 1, el frente del puntero de la cabeza del equipo coincide con la parte posterior del puntero de la cola del equipo, lo que indica que la lógica del espacio de cola está llena en este momento, primero colocamos los elementos del espacio señalado por el puntero de la cabeza del equipo fuera del equipo, y el puntero de la cabeza del equipo se mueve hacia adelante al subíndice 1. En este momento, el elemento se ingresa en el espacio con un subíndice de 7, y la parte posterior del puntero del equipo se mueve hacia adelante (apuntando al subíndice 0.) Cuando la parte posterior + 1, el frente del puntero de la cabeza del equipo y la parte posterior del puntero de la cola del equipo coinciden nuevamente, lo que indica la lógica del espacio de cola en este momento Está lleno de nuevo e itera de un lado a otro, dejando al equipo—> la cabeza del equipo se mueve hacia adelante—> luego se une al equipo—> la cola del equipo se mueve hacia atrás (después de que la condición de juicio es trasera + 1, la parte delantera de la cabeza del equipo y la cola del punto del equipo Ya sea que la parte trasera coincida o no, puedes seguir uniéndote al equipo).

Sin embargo, la computadora no tiene un espacio de almacenamiento circular y todavía se almacena de manera lineal ¿Cómo determina la computadora cuándo se vuelven a superponer el puntero de la cola y el puntero de la cabeza?

————— OK! Es decir: operación de módulo ——————

Cómo se implementa la aritmética modular específica, el texto se ve pálido y débil, aún esa oración, ejecuta el código y lentamente te das cuenta.

#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);
}

Resultado de la operación:
Inserte la descripción de la imagen aquí

Publicado 23 artículos originales · elogiado 46 · visitas 2056

Supongo que te gusta

Origin blog.csdn.net/weixin_43964458/article/details/105399987
Recomendado
Clasificación