[Estructura de datos] ¿Cómo implementar una cola con una pila? Análisis gráfico (LeetCode)

Enlace LeetCode: 232. Implementación de colas con pilas - LeetCode

Nota: Este artículo establece de forma predeterminada que los lectores dominan las operaciones básicas de pilas y colas.

Puede leer este artículo para familiarizarse con los puntos de conocimiento: [Estructura de datos] Stack y Queue_Blog Byte-CSDN vinculado Blog

Tabla de contenido

Ideas de preguntas

Código

1. Mi cola

2. miColaCrear

3. miQueuePush

4. miQueuePeek

5. miQueuePop

6. miColaVacía

7. miQueueFree

todos los codigos


Ideas de preguntas

En pocas palabras, se trata de transferir los datos de una pila ( pila 1 ) a otra pila ( pila 2 ), y en este momento ( pila 2 ) el orden de salida de los datos es el mismo que el de la cola.

Para que sea más fácil de entender, haré un dibujo para demostrar las ideas específicas.

Necesitamos dos pilas para implementar la cola:

  • push stack : una pila dedicada a la entrada de datos
  • pila pop : una pila dedicada a los datos de salida

Como se muestra abajo:

Insertar datos: insertar directamente en la pila de inserción

Insertar datos en la pila push : 1, 2, 3, 4, 5

Eliminar datos: es necesario insertar los datos de la pila de inserción en la pila emergente

  • La pila es el último en entrar, el primero en salir.
  • Cuando los datos de la pila push ingresan a la pila pop, el orden de los datos cambiará

Como se muestra abajo:

Se puede observar que el orden de los datos está invertido.

Pero ¿cuál es la conexión entre estas operaciones de la pila y la cola ?

Echemos un vistazo a la comparación entre la pila emergente y la cola :

Se puede ver que el orden en que se extraen los datos de la pila es el mismo que el de la cola.

La idea aquí es muy clara: necesitamos dos pilas, una para push y otra para pop . Después de eliminar los datos, el orden de extracción de los datos de la pila es el mismo que el de la cola .

Entonces, ¿cómo utilizar el código (C) para realizar esta idea?


Código

Como estamos usando lenguaje C, no podemos usar operaciones de pila directamente.

Así que primero copie la pila que se ha simulado antes:

//C语言模拟实现栈

typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;
	int capacity;
}ST;

//初始化栈
void STInit(ST* ps);
//销毁栈
void STDestroy(ST* ps);
//入栈
void STPush(ST* ps, STDataType x);
//出栈
void STPop(ST* ps);
//获取栈顶元素
STDataType STTop(ST* ps);
//获取栈中有效元素个数
int STSize(ST* ps);
//检测栈是否为空,如果为空返回非零结果,如果不为空返回0
bool STEmpty(ST* ps);

void STInit(ST* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->capacity = 0;
	ps->top = 0;
}

void STDestroy(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->capacity = 0;
	ps->top = 0;
}

void STPush(ST* ps, STDataType x)
{
	assert(ps);
	if (ps->top == ps->capacity)
	{
		int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newCapacity);
		if (tmp == NULL)
		{
			perror("realloc fail");
			exit(-1);
		}
		ps->a = tmp;
		ps->capacity = newCapacity;
	}
	ps->a[ps->top] = x;
	ps->top++;
}

void STPop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);
	ps->top--;
}

STDataType STTop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);
	return ps->a[ps->top - 1];
}

int STSize(ST* ps)
{
	assert(ps);
	return ps->top;
}

bool STEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0;
}

Una vez completada la copia, es el contenido clave de esta pregunta.

Esta pregunta requiere:

Clase de implementación  MyQueue :

  • void push(int x) empujar el elemento x al final de la cola
  • int pop() elimina y devuelve un elemento desde el principio de la cola
  • int peek() devolver el elemento al comienzo de la cola
  • boolean empty() Si la cola está vacía, regresa  true ; en caso contrario, regresa false

1. Mi cola

Ya que estamos implementando una cola con dos pilas.

Entonces aquí necesitas definir dos pilas.

//两个栈模拟实现队列
typedef struct
{
    ST pushst;
    ST popst;
} MyQueue;

2. miColaCrear

Esta función requiere que asignemos espacio e inicialicemos la pila.

//开辟空间并初始化
MyQueue* myQueueCreate()
{
    MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));
    STInit(&obj->pushst);
    STInit(&obj->popst);
    return obj;
}

3. miQueuePush

Simplemente inserte los datos directamente en la pila de inserción.

//将元素X推到队列的末尾
void myQueuePush(MyQueue* obj, int x)
{
    STPush(&obj->pushst, x);
}

4. miQueuePeek

Esta función es necesaria para devolver el elemento al principio de la cola.

  • Si la pila emergente está vacía: el primer elemento de la cola se debe encontrar insertando los datos de la pila push en la pila emergente
  • Si la pila emergente no está vacía: el elemento superior de la pila emergente es el primer elemento de la cola

//返回队列开头的元素
int myQueuePeek(MyQueue* obj)
{
    if (STEmpty(&obj->popst))
    {
        //捯数据
        while (!STEmpty(&obj->pushst))
        {
            STPush(&obj->popst, STTop(&obj->pushst));
            STPop(&obj->pushst);
        }
    }
    return STTop(&obj->popst);
}

5. miQueuePop

  • Es necesario eliminar el elemento principal de la cola , es decir, el elemento superior de la pila emergente , simplemente elimínelo directamente
  • Y para devolver el valor del elemento principal , debe definir una variable temporal para guardar el valor del elemento principal.
  • Finalmente devuelve esta variable temporal
//从队列的开头移除并返回元素
int myQueuePop(MyQueue* obj)
{
    int front = myQueuePeek(obj);
    STPop(&obj->popst);
    return front;
}

6. miColaVacía

Determinar si la cola está vacía y devolver un valor bool (verdadero/falso)

Si tanto la pila push como la pop están vacías, la cola está vacía

//如果队列为空,返回true;否则,返回false
bool myQueueEmpty(MyQueue* obj)
{
    return STEmpty(&obj->popst) && STEmpty(&obj->pushst);
}

7. miQueueFree

destruir cola

  • Destruye la pila de empuje y la pila de pop
  • Liberar espacio asignado dinámicamente
//销毁队列
void myQueueFree(MyQueue* obj)
{
    STDestroy(&obj->popst);
    STDestroy(&obj->pushst);
    free(obj);
}

Hasta ahora, se han implementado todas las funciones, envíe el código:

Superado exitosamente

A continuación, reuniré todo el código de esta pregunta y lo enviaré.


todos los codigos

//C语言模拟实现栈

typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;
	int capacity;
}ST;

//初始化栈
void STInit(ST* ps);
//销毁栈
void STDestroy(ST* ps);
//入栈
void STPush(ST* ps, STDataType x);
//出栈
void STPop(ST* ps);
//获取栈顶元素
STDataType STTop(ST* ps);
//获取栈中有效元素个数
int STSize(ST* ps);
//检测栈是否为空,如果为空返回非零结果,如果不为空返回0
bool STEmpty(ST* ps);

void STInit(ST* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->capacity = 0;
	ps->top = 0;
}

void STDestroy(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->capacity = 0;
	ps->top = 0;
}

void STPush(ST* ps, STDataType x)
{
	assert(ps);
	if (ps->top == ps->capacity)
	{
		int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newCapacity);
		if (tmp == NULL)
		{
			perror("realloc fail");
			exit(-1);
		}
		ps->a = tmp;
		ps->capacity = newCapacity;
	}
	ps->a[ps->top] = x;
	ps->top++;
}

void STPop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);
	ps->top--;
}

STDataType STTop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);
	return ps->a[ps->top - 1];
}

int STSize(ST* ps)
{
	assert(ps);
	return ps->top;
}

bool STEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0;
}

//=======================================================================

//两个栈模拟实现队列
typedef struct
{
    ST pushst;
    ST popst;
} MyQueue;

//开辟空间并初始化
MyQueue* myQueueCreate()
{
    MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));
    STInit(&obj->pushst);
    STInit(&obj->popst);
    return obj;
}

//将元素X推到队列的末尾
void myQueuePush(MyQueue* obj, int x)
{
    STPush(&obj->pushst, x);
}

//返回队列开头的元素
int myQueuePeek(MyQueue* obj)
{
    if (STEmpty(&obj->popst))
    {
        //捯数据
        while (!STEmpty(&obj->pushst))
        {
            STPush(&obj->popst, STTop(&obj->pushst));
            STPop(&obj->pushst);
        }
    }
    return STTop(&obj->popst);
}

//从队列的开头移除并返回元素
int myQueuePop(MyQueue* obj)
{
    int front = myQueuePeek(obj);
    STPop(&obj->popst);
    return front;
}

//如果队列为空,返回true;否则,返回false
bool myQueueEmpty(MyQueue* obj)
{
    return STEmpty(&obj->popst) && STEmpty(&obj->pushst);
}

//销毁队列
void myQueueFree(MyQueue* obj)
{
    STDestroy(&obj->popst);
    STDestroy(&obj->pushst);
    free(obj);
}

fin del artículo

Supongo que te gusta

Origin blog.csdn.net/m0_73156359/article/details/132416254
Recomendado
Clasificación