Realização mútua de fila e pilha (1)

Este artigo é uma compreensão mais profunda de filas e pilhas, e usa suas próprias propriedades para concluir a conversão entre elas.Antes disso, você deve entender claramente sua implementação e aplicação.

contente

Implementando pilhas com filas

Escrita da fila: 

Análise de implementação da pilha:

 Definir pilha e inicialização de pilha

Elemento na pilha (enfileirar) 

Elemento aparece (desenfileirar) 

retorna o elemento do topo da pilha

Determinando se a pilha está vazia e destruindo a pilha


Link da pergunta: 225. Implementando uma pilha com uma fila - LeetCode (leetcode-cn.com)


Implementando pilhas com filas

Implementamos uma fila com uma lista encadeada simples antes. Sabemos que sua natureza é primeiro a entrar, primeiro a sair. Como usar duas filas para implementar uma pilha? Duas FIFOs podem ser usadas para concluir um último a entrar, primeiro a pilha fora? Agora vamos completar a primeira pergunta: Implementando uma pilha com uma fila

Escrita da fila: 

Lendo a pergunta, podemos ver que devemos primeiro concluir a definição da fila. Este problema é concluído na premissa de ter uma fila. A fila já foi implementada antes, para que possamos concluir diretamente a escrita da fila:

typedef int QDatatype;

//定义单链表结点
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);



//队列初始化
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));
	assert(newnode);
	newnode->data = x;
	newnode->next = NULL;
	if (pq->head == NULL)
	{
		assert(pq->tail==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);

	if (pq->head->next==NULL)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else
	{
		QNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}

}

//判断是否为空
bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->head == NULL&&pq->tail == 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;
}

Análise de implementação da pilha:

A fila é o primeiro a entrar, o primeiro a sair, e o início e o fim são operados. Como as duas filas implementam uma pilha de último a entrar? Dessa forma, você pode não saber o que isso vai fazer. Simplificando:

Enfio 1 2 3 4 5 na fila, como posso tirá-lo da fila 5 4 3 2 1, em duas filas.

O diagrama é o seguinte:

 Definir pilha e inicialização de pilha

Definição: A pilha é implementada por duas filas encapsuladas.

Inicialização: primeiro crie espaço para a pilha para determinar se a criação foi bem-sucedida e, em seguida, inicialize as duas filas na pilha, usando a função de inicialização quando definimos a fila.

typedef struct {
    Queue q1;
    Queue q2;
} MyStack;


MyStack* myStackCreate() {
    MyStack* pst=(MyStack*)malloc(sizeof(MyStack));
    assert(pst);
    QueueInit(&pst->q1);
    QueueInit(&pst->q2);
    return pst;
}

Elemento na pilha (enfileirar) 

Julgue se as duas filas estão vazias, enfileire os dados na fila não vazia e mantenha a fila vazia para facilitar a importação de dados para frente e para trás.

void myStackPush(MyStack* obj, int x) {
    assert(obj);
    if(!QueueEmpty(&obj->q1))
    {
        QueuePush(&obj->q1,x);
    }
    else
    {
        QueuePush(&obj->q2,x);
    }
}

Elemento aparece (desenfileirar) 

Defina duas filas, vazias e não vazias, e atribua-as a 12 filas de cada vez para facilitar as operações subsequentes.

Cada vez que os primeiros elementos Size-1 da fila não vazia são importados para a fila vazia, os dados originais da fila não vazia são excluídos e o último elemento é retirado da fila para concluir o desempilhamento.

Preste atenção aos detalhes: retorne o elemento do topo da pilha, o topo da pilha é o elemento final da fila não vazia e, em seguida, retire o elemento final não vazio, ou seja, o topo da pilha.

int myStackPop(MyStack* obj) {
    assert(obj);
    //判断空和非空是哪个
    Queue* emptyQ=&obj->q1;
    Queue* nonemptyQ=&obj->q2;
    if(!QueueEmpty(&obj->q1))
    {
        emptyQ=&obj->q2;
        nonemptyQ=&obj->q1;
    }

    //把非空队列前N个数据导入空队列
    //剩下一个删除实现后进先出
    while(QueueSize(nonemptyQ)>1)
    {
        QueuePush(emptyQ,QueueFront(nonemptyQ));
        QueuePop(nonemptyQ);
    }
    int top=QueueFront(nonemptyQ);
    QueuePop(nonemptyQ);
    return top;
}

retorna o elemento do topo da pilha

Julgando encontrar uma fila não vazia, você pode se opor diretamente ao elemento final da fila não vazia, e a cauda da fila é o topo da pilha.

int myStackTop(MyStack* obj) {
    assert(obj);
    if(!QueueEmpty(&obj->q1))
    {
        return QueueBack(&obj->q1);
    }
    else
    {
        return QueueBack(&obj->q2);
    }
}

Determinando se a pilha está vazia e destruindo a pilha

Julgamento: A pilha tem duas filas, e a pilha está vazia quando ambas as filas estão vazias, basta retornar.

Destruição: Existem duas filas na pilha, e as duas filas também apontam para dois espaços. Ao destruir, as filas são destruídas primeiro para evitar vazamentos de memória.

bool myStackEmpty(MyStack* obj) {
    assert(obj);
    return QueueEmpty(&obj->q1)&&QueueEmpty(&obj->q2);
}

void myStackFree(MyStack* obj) {
    assert(obj);
    QueueDestory(&obj->q1);
    QueueDestory(&obj->q2);
    free(obj);
}

 

Acho que você gosta

Origin blog.csdn.net/weixin_53316121/article/details/123925994
Recomendado
Clasificación