<Estructura de datos> Implementación de cola

contenido

prefacio

        concepto de cola

        La estructura de la cola.

        Escenarios de aplicación de cola

Implementación de la cola.

        Crear estructura de cola

        inicialización de la cola

        Destrucción de colas

        poner en cola

        sacar de la cola

        la cola está vacía

        Obtener el número de elementos de la cola

        Obtener el elemento de cabeza de cola

        Obtener el elemento al final de la cola

codigo total

        Archivo Queue.h

        Archivo Queue.c

        Archivo de prueba.c


prefacio

concepto de cola

  • Queue: Una tabla lineal especial que solo permite operaciones de inserción de datos en un extremo y operaciones de eliminación de datos en el otro extremo.La cola tiene un First In First Out (primero en entrar, primero en salir)
  • Encolar: El extremo que realiza la operación de inserción se llama la cola de la cola
  • Dequeue: el extremo que realiza la operación de eliminación se denomina cabeza de la cola.

Todavía hay una cierta diferencia entre la cola y la pila aprendida en el artículo anterior.La cola señala claramente el primero en entrar, el primero en salir. Si el orden de entrada de una cola es ABCD, entonces el orden de salida de la cola debe ser ABCD, porque si entras y luego sales en A, luego B entra y sale, luego CD entra y sale o similar, no afectará su orden final de Dequeue ABCD. Esto sigue siendo diferente de la pila, después de todo, la pila es LIFO.

La estructura de la cola.

Escenarios de aplicación de cola

cola:

  1. cola justa
  2. Recorrido primero en anchura...

pila:

  1. resolver coincidencia de paréntesis
  2. Solucionador de expresión polaca inversa
  3. De recursivo a no recursivo...

Implementación de la cola.

  • Antes de implementar, primero debemos considerar qué estructura usar, si usar una estructura de matriz o una estructura de cadena. La pila que usamos arriba es una estructura de matriz, ¿deberíamos usar también la cola?
  • en realidad no. Se debe utilizar una estructura encadenada. Los datos de eliminación de pila anteriores no necesitan mover los datos, la estructura de matriz se puede usar para satisfacer las necesidades, y la cola necesita mover los siguientes datos al frente al eliminar datos, es muy fácil usar la estructura de cadena, simplemente cambie el punto de nodo, y la matriz es muy problemática para la estructura para realizar datos en movimiento. En resumen, el uso de una estructura de cadena es óptimo. Además, una lista con un solo enlace puede cumplir los requisitos y no es necesario utilizar otras estructuras de cadena más complejas.

Crear estructura de cola

  •  Ideas:

Aquí para definir dos estructuras, además de definir una estructura de cadena para registrar cada nodo, sino también para definir una estructura para registrar la cabeza y la cola de la cola. De esta manera, es conveniente que la cola posterior de la cola ingrese datos y la cabeza de la cola genere datos.

  • Archivo Queue.h:
//创建队列结构
typedef int QDataType; //方便后续更改存储数据类型,本文以int为例
 //创建队列节点
typedef struct QueueNode
{
	QDataType data; //存储数据
	struct QueueNode* next; //记录下一个节点
}QNode;
 //保存队头和队尾
typedef struct Queue
{
	QNode* head; //头指针
	QNode* tail; //尾指针
}Queue;

inicialización de la cola

  •  Ideas:

La cola puede estar vacía, pero la estructura que gestiona los punteros de cabeza y cola no puede estar vacía, por lo que debe afirmarse al principio. En segundo lugar, antes de insertar datos, la cola debe estar vacía, así que simplemente vacíe el puntero principal y el puntero final.

  • Archivo Queue.h:
//初始化队列
void QueueInit(Queue* pq);
  • Archivo Queue.c:
//初始化队列
void QueueInit(Queue* pq)
{
	assert(pq);
	pq->head = pq->tail = NULL;
}

Destrucción de colas

  •  Ideas:

Destruir la cola es destruir todos los datos en la cola, luego debe atravesar la lista vinculada para destruir uno por uno. Primero defina un puntero cur como pq->head, que se usa para guardar los primeros datos, atravesar cur y, si no está vacío, libre. Finalmente, deja la cola y la cabeza vacías.

  • Archivo Queue.h:
//销毁队列
void QueueDestory(Queue* pq);
  • Archivo Queue.c:
//销毁队列
void QueueDestory(Queue* pq)
{
	assert(pq);
	QNode* cur = pq->head;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->head = pq->tail = NULL;
}

poner en cola

  •  Ideas:

Ingresar a la cola es realmente muy simple. Solo necesita insertar la cola. Primero, necesita crear un nuevo nodo para guardar los datos recién insertados. Pero antes de la inserción de la cola, se debe considerar que si la cola no tiene datos al principio y está vacía, solo necesita apuntar los nodos de cabeza y cola al nuevo nodo newnode node. Por el contrario, si hay datos al principio, entonces solo es necesario apuntar el siguiente de la cola al nuevo nodo newnode, y luego asignar el newnode a la cola.

  • Archivo Queue.h:
//入队列
void QueuePush(Queue* pq, QDataType x);
  •  Archivo Queue.c:
//入队列
void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	//创建一个新节点保存数据
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	//暴力检测newnode,因为malloc的都要检测
	assert(newnode);
	newnode->next = NULL;
	newnode->data = x;
	//如果一开始没有数据,为空的情况
	if (pq->tail == NULL)
	{
		assert(pq->head == NULL);
		pq->head = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
}

sacar de la cola

  •  Ideas:

Casos especiales:

Aquí, al eliminar datos, primero debemos considerar casos especiales. Cuando solo quede un dato, elimínelo nuevamente. En este momento, los datos se han ido, pero la cabeza está vacía y la cola se convierte en un puntero salvaje. Para evitar este fenómeno La generación de , discutido por separado y vacío de pies y manos.

generalmente:

En este punto, solo necesita definir un puntero siguiente para guardar el siguiente nodo del encabezado, mover el encabezado al siguiente y vaciar el encabezado anterior.

  •  Archivo Queue.h:
//出队列
void QueuePop(Queue* pq);
  • Archivo Queue.c:
//出队列
void QueuePop(Queue* pq)
{
	assert(pq);
	assert(pq->head && pq->tail); //tail和head均不能为空
	//特殊:当删到head=tail的位置时
	if (pq->head->next == NULL)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	//一般情况
	else
	{
		//保存head的下一个节点
		QNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}
}

la cola está vacía

  •  Ideas:

Si la cabeza está vacía o la cola está vacía, es una condición vacía, simplemente regrese directamente.

  • Archivo Queue.h:
//判空
bool QueueEmpty(Queue* pq);
  • Archivo Queue.c:
//判空
bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->head == NULL;
}

Obtener el número de elementos de la cola

  •  Ideas:

No es difícil encontrar el número de elementos, simplemente defina un puntero cur como el primer dato pq->head y defina el tamaño variable para registrar el número. Traverse cur a su vez, si no está vacío, el tamaño es ++. La idea de este recorrido no es complicada, pero la complejidad del tiempo llega a O(N), lo cual no es muy bueno.Si quieres O(1), puedes definir directamente una variable de tamaño adicional cuando definas la estructura. al principio, que se usa especialmente para registrar el número de elementos válidos.Número, cada vez en el tamaño de la cola ++, fuera del tamaño de la cola--. Esta implementación es mejor, pero para encapsularla en un módulo independiente, todavía se usa el método transversal. como sigue:

  • Archivo Queue.h:
//获取有效元素个数
size_t QueueSize(Queue* pq);
  • Archivo Queue.c:
//获取有效元素个数
size_t QueueSize(Queue* pq)
{
	assert(pq);
	QNode* cur = pq->head;
	size_t size = 0;
	while (cur)
	{
		size++;
		cur = cur->next;
	}
	return size;
}

Obtener el elemento de cabeza de cola

  •  Ideas:

En primer lugar, es necesario afirmar que la cabeza no puede estar vacía. Si la cabeza está vacía, ¿cómo podemos obtener el elemento de la cabeza y luego devolver directamente los datos de la cabeza?

  • Archivo Queue.h:
//获取队头元素
QDataType QueueFront(Queue* pq);
  • Archivo Queue.c:
//获取队头元素
QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(pq->head); //头部不能为空
	return pq->head->data;
}

Obtener el elemento al final de la cola

  •  Ideas:

Con la experiencia de obtener los elementos de la cabeza de la cola, la cola de la cola es más simple, simplemente cambie la cabeza a la cola, y la estructura es la misma que la anterior.

  • Archivo Queue.h:
//获取队尾元素
QDataType QueueBack(Queue* pq);
  • Archivo Queue.c:
//获取队尾元素
QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(pq->tail); //尾部不能为空
	return pq->tail->data;
}

codigo total

Archivo Queue.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>

//创建队列结构
typedef int QDataType; //方便后续更改存储数据类型,本文以int为例
 //创建队列节点
typedef struct QueueNode
{
	QDataType data; //存储数据
	struct QueueNode* next; //记录下一个节点
}QNode;
 //保存队头和队尾
typedef struct Queue
{
	QNode* head; //头指针
	QNode* tail; //尾指针
}Queue;

//初始化队列
void QueueInit(Queue* pq);

//销毁队列
void QueueDestory(Queue* pq);

//入队列
void QueuePush(Queue* pq, QDataType x);

//出队列
void QueuePop(Queue* pq);

//判空
bool QueueEmpty(Queue* pq);

//获取有效元素个数
size_t QueueSize(Queue* pq);

//获取队头元素
QDataType QueueFront(Queue* pq);

//获取队尾元素
QDataType QueueBack(Queue* pq);

Archivo Queue.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"Queue.h"

//初始化队列
void QueueInit(Queue* pq)
{
	assert(pq);
	pq->head = pq->tail = NULL;
}

//销毁队列
void QueueDestory(Queue* pq)
{
	assert(pq);
	QNode* cur = pq->head;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->head = pq->tail = NULL;
}

//入队列
void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	//创建一个新节点保存数据
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	//暴力检测newnode,因为malloc的都要检测
	assert(newnode);
	newnode->next = NULL;
	newnode->data = x;
	//如果一开始没有数据,为空的情况
	if (pq->tail == NULL)
	{
		assert(pq->head == NULL);
		pq->head = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
}

//出队列
void QueuePop(Queue* pq)
{
	assert(pq);
	assert(pq->head && pq->tail); //tail和head均不能为空
	//特殊:当删到head=tail的位置时
	if (pq->head->next == NULL)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	//一般情况
	else
	{
		//保存head的下一个节点
		QNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}
}

//判空
bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->head == NULL;
}

//获取有效元素个数
size_t QueueSize(Queue* pq)
{
	assert(pq);
	QNode* cur = pq->head;
	size_t size = 0;
	while (cur)
	{
		size++;
		cur = cur->next;
	}
	return size;
}

//获取队头元素
QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(pq->head); //头部不能为空
	return pq->head->data;
}

//获取队尾元素
QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(pq->tail); //尾部不能为空
	return pq->tail->data;
}

Archivo de prueba.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"Queue.h"
void TestQueue()
{
	Queue q;
	QueueInit(&q);
	//插入数据
	QueuePush(&q, 1);
	QueuePush(&q, 2);
	QueuePush(&q, 3);
	QueuePush(&q, 4);
	//打印
	while (!QueueEmpty(&q))
	{
		printf("%d ", QueueFront(&q));
		QueuePop(&q);
	}
	printf("\n");
}
int main()
{
	TestQueue();
	return 0;
}

Supongo que te gusta

Origin blog.csdn.net/bit_zyx/article/details/123967787
Recomendado
Clasificación