Link LeetCode: 232. Implementando filas com pilhas - LeetCode
Nota: Este artigo assume como padrão que os leitores dominam as operações básicas de pilhas e filas
Você pode ler este artigo para se familiarizar com os pontos de conhecimento: [Estrutura de dados] Stack e Queue_Blog Linked Byte-CSDN Blog
Índice
Ideias para perguntas
Simplificando, trata-se de transferir os dados de uma pilha ( pilha 1 ) para outra pilha ( pilha 2 ) e, neste momento ( pilha 2 ), a ordem de saída dos dados é a mesma da fila.
Para facilitar a compreensão, farei um desenho para demonstrar as ideias específicas.
Precisamos de duas pilhas para implementar a fila:
- push stack : uma pilha dedicada à entrada de dados
- pilha pop : uma pilha dedicada aos dados de saída
Como mostrado abaixo:
Inserir dados: insira diretamente na pilha push
Insira dados na pilha push : 1, 2, 3, 4, 5
Excluir dados: é necessário enviar os dados da pilha push para a pilha pop
- A pilha é o último a entrar, primeiro a sair
- Quando os dados da pilha push entram na pilha pop, a ordem dos dados muda
Como mostrado abaixo:
Pode-se ver que a ordem dos dados é invertida
Mas qual é a conexão entre essas operações da pilha e da fila ?
Vamos dar uma olhada na comparação entre a pilha pop e a fila :
Pode-se ver que a ordem de retirada dos dados da pilha é a mesma da fila
A ideia aqui é muito clara: precisamos de duas pilhas, uma para push e outra para pop . Depois que os dados são removidos, a ordem de retirada dos dados da pilha é a mesma da fila .
Então, como usar o código (C) para concretizar essa ideia?
Código
Como estamos usando a linguagem C, não podemos usar operações de pilha diretamente
Então primeiro copie a pilha que foi simulada 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;
}
Após a conclusão da cópia, é o conteúdo principal desta questão.
Esta questão requer:
Classe de implementação
MyQueue
:
void push(int x)
empurre o elemento x para o final da filaint pop()
remove e retorna um elemento do início da filaint peek()
retornar o elemento no início da filaboolean empty()
Se a fila estiver vazia, retornetrue
; caso contrário, retornefalse
1. MinhaFila
Como estamos implementando uma fila com duas pilhas
Então aqui você precisa definir duas pilhas
//两个栈模拟实现队列
typedef struct
{
ST pushst;
ST popst;
} MyQueue;
2. myQueueCreate
Esta função exige que aloquemos espaço e inicializemos a pilha
//开辟空间并初始化
MyQueue* myQueueCreate()
{
MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));
STInit(&obj->pushst);
STInit(&obj->popst);
return obj;
}
3. myQueuePush
Basta inserir os dados diretamente na pilha push
//将元素X推到队列的末尾
void myQueuePush(MyQueue* obj, int x)
{
STPush(&obj->pushst, x);
}
4. myQueuePeek
Esta função é necessária para retornar o elemento no início da fila
- Se a pilha pop estiver vazia: o primeiro elemento da fila deve ser encontrado empurrando os dados da pilha push para a pilha pop
- Se a pilha pop não estiver vazia: o elemento superior da pilha pop é o primeiro elemento da fila
//返回队列开头的元素
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. meuQueuePop
- É necessário excluir o elemento head da fila , ou seja, o elemento superior da pilha pop , basta excluí-lo diretamente
- E para retornar o valor do elemento head , você precisa definir uma variável temporária para salvar o valor do elemento head
- Finalmente retorne esta variável temporária
//从队列的开头移除并返回元素
int myQueuePop(MyQueue* obj)
{
int front = myQueuePeek(obj);
STPop(&obj->popst);
return front;
}
6. minhaQueueEmpty
Determine se a fila está vazia e retorne um valor bool (verdadeiro/falso)
Se a pilha push e a pilha pop estiverem vazias, a fila estará vazia
//如果队列为空,返回true;否则,返回false
bool myQueueEmpty(MyQueue* obj)
{
return STEmpty(&obj->popst) && STEmpty(&obj->pushst);
}
7. minhaQueueFree
destruir fila
- Destrua a pilha push e a pilha pop
- Libere espaço alocado dinamicamente
//销毁队列
void myQueueFree(MyQueue* obj)
{
STDestroy(&obj->popst);
STDestroy(&obj->pushst);
free(obj);
}
Até agora, todas as funções foram implementadas, envie o código:
aprovado com sucesso
A seguir, reunirei todo o código desta questão e enviarei.
todos os códigos
//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);
}
fim do artigo