1. 232. 用队列实现栈
⛱️
🌴深度剖析
1️⃣最关键的push和pop过程如何模拟?
pop:
step0.先利用假设法假定非空队列notempty和空队列empty,再利用MyStackEmpty函数对进行修正
step1:将notempty队列中的前size-1个元素依次push到empty队列中,再进行删除,实现移动操作
step2:此时非空队列中剩下的唯一一个数就是"栈顶"元素,使用QueueFront进行·取值后,直接进行QueuePop删除。
🥳代码实现
cpp
typedef int QDataType;
typedef struct QListNode {
struct QListNode* next;
QDataType data;
} QNode;
// 队列的结构
typedef struct Queue {
QNode* phead;
QNode* ptail;
int size;
} Queue;
// 初始化队列
void QueueInit(Queue* q) {
assert(q);
q->phead = q->ptail = NULL;
q->size = 0;
}
// 队尾入队列
void QueuePush(Queue* q, QDataType data) {
assert(q);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL) {
perror("malloc fail!");
exit(1);
} else {
newnode->data = data;
newnode->next = NULL;
if (q->ptail == NULL) {
q->phead = q->ptail = newnode;
q->size++;
} else {
q->ptail->next = newnode;
q->ptail = newnode;
q->size++;
}
}
}
// 队头出队列
void QueuePop(Queue* q) {
assert(q);
assert(q->size != 0);
if (q->phead->next == NULL) {
free(q->ptail);
q->ptail = q->phead = NULL;
q->size--;
} else {
QNode* next = q->phead->next;
free(q->phead);
q->phead = next;
q->size--;
}
}
// 获取队列头部元素
QDataType QueueFront(Queue* q) {
assert(q);
return q->phead->data;
}
// 获取队列队尾元素
QDataType QueueBack(Queue* q) {
assert(q);
return q->ptail->data;
}
// 获取队列中有效元素个数
int QueueSize(Queue* q) {
assert(q);
return q->size;
}
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
int QueueEmpty(Queue* q) {
assert(q);
return !QueueSize(q);
}
// 销毁队列
void QueueDestroy(Queue* q) {
assert(q);
while (q->size) {
QueuePop(q);
}
q->phead = NULL;
q->ptail = NULL;
}
typedef struct {
Queue Q1;
Queue Q2;
} MyStack;
MyStack* myStackCreate() {
MyStack* obj = (MyStack*)malloc(sizeof(MyStack));
QueueInit(&obj->Q1);
QueueInit(&obj->Q2);
return obj;
}
void myStackPush(MyStack* obj, int x) {
if (!QueueEmpty(&obj->Q1)) {
QueuePush(&obj->Q1, x);
} else {
QueuePush(&obj->Q2, x);
}
}
int myStackPop(MyStack* obj) {
// 假设法
Queue* empty = &obj->Q1;
Queue* notempty = &obj->Q2;
if (QueueEmpty(notempty)) {
empty = &obj->Q2;
notempty = &obj->Q1;
}
// 把notempty中前size-1个一到empty
while (QueueSize(notempty) > 1) {
QueuePush(empty, QueueFront(notempty));
QueuePop(notempty);
}
int ret = QueueFront(notempty);
QueuePop(notempty);
return ret;
}
int myStackTop(MyStack* obj) {
if (!QueueEmpty(&obj->Q2)) {
return QueueBack(&obj->Q2);
}else{
return QueueBack(&obj->Q1);
}
}
bool myStackEmpty(MyStack* obj) {
return QueueEmpty(&obj->Q2)&&QueueEmpty(&obj->Q1);
}
void myStackFree(MyStack* obj) {
QueueDestroy(&obj->Q1);
QueueDestroy(&obj->Q2);
free(obj);
}
/**
* Your MyStack struct will be instantiated and called as such:
* MyStack* obj = myStackCreate();
* myStackPush(obj, x);
* int param_2 = myStackPop(obj);
* int param_3 = myStackTop(obj);
* bool param_4 = myStackEmpty(obj);
* myStackFree(obj);
*/
2. 232. 用栈实现队列
⛱️试题链接戳这里!
🌴深度剖析
1️⃣最关键的push和pop过程如何模拟?
🥳代码实现
方法一(推荐)
cpp
typedef int STDataType;
typedef struct stack {
STDataType* a;
int capacity;
int top;
}Stack;
void StackInit(Stack* ps) {
ps->a = NULL;
ps->capacity = ps->top = 0;
}
void StackPush(Stack* ps, STDataType data){
assert(ps);
int newcapacity = 0;
if (ps->top ==ps->capacity) {
newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
STDataType* tmp = (STDataType*)realloc(ps->a, newcapacity * sizeof(STDataType));
if (tmp==NULL) {
perror("realloc fail");
exit(1);
}
else {
ps->a = tmp;
}
}
ps->a[ps->top] = data;
ps->capacity = newcapacity;
ps->top++;
}
void StackPop(Stack* ps) {
assert(ps);
assert(ps->top>0);
ps->top--;
}
// 获取栈顶元素
STDataType StackTop(Stack* ps) {
assert(ps);
int top = ps->top - 1;
return ps->a[top];
}
// 获取栈中有效元素个数
int StackSize(Stack* ps) {
assert(ps);
return ps->top;
}
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
bool StackEmpty(Stack* ps) {
assert(ps);
if (StackSize(ps) == 0)
{
return true;
}
else {
return false;
}
}
// 销毁栈
void StackDestroy(Stack* ps) {
assert(ps);
free(ps->a);
ps->a = NULL;
ps->top = ps->capacity = 0;
}
typedef struct {
Stack pushst;//只用来进
Stack popst;//只用来出
} MyQueue;
MyQueue* myQueueCreate() {
MyQueue* obj=(MyQueue*)malloc(sizeof(MyQueue));
StackInit(&obj->pushst);
StackInit(&obj->popst);
return obj;
}
void myQueuePush(MyQueue* obj, int x) {
StackPush(&obj->pushst, x);
return;
}
int myQueuePop(MyQueue* obj) {
int ret=myQueuePeek(obj);
StackPop(&obj->popst);
return ret;
}
int myQueuePeek(MyQueue* obj) {
if (StackEmpty(&obj->popst)) {//如果popst空了的话,我们就要往里面导入pushst中的数据
while(StackSize(&obj->pushst)){
StackPush(&obj->popst, StackTop(&obj->pushst));
StackPop(&obj->pushst);
}
}
int ret=StackTop(&obj->popst);
return ret;
}
bool myQueueEmpty(MyQueue* obj) {
return StackEmpty(&obj->pushst)&&StackEmpty(&obj->popst);
}
void myQueueFree(MyQueue* obj) {
StackDestroy(&obj->pushst);
StackDestroy(&obj->popst);
free(obj);
return;
}
/**
* Your MyQueue struct will be instantiated and called as such:
* MyQueue* obj = myQueueCreate();
* myQueuePush(obj, x);
* int param_2 = myQueuePop(obj);
* int param_3 = myQueuePeek(obj);
* bool param_4 = myQueueEmpty(obj);
* myQueueFree(obj);
*/
方法二
cpp
typedef int STDataType;
typedef struct stack {
STDataType* a;
int capacity;
int top;
}Stack;
void StackInit(Stack* ps) {
ps->a = NULL;
ps->capacity = ps->top = 0;
}
void StackPush(Stack* ps, STDataType data){
assert(ps);
int newcapacity = 0;
if (ps->top ==ps->capacity) {
newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
STDataType* tmp = (STDataType*)realloc(ps->a, newcapacity * sizeof(STDataType));
if (tmp==NULL) {
perror("realloc fail");
exit(1);
}
else {
ps->a = tmp;
}
}
ps->a[ps->top] = data;
ps->capacity = newcapacity;
ps->top++;
}
void StackPop(Stack* ps) {
assert(ps);
assert(ps->top>0);
ps->top--;
}
// 获取栈顶元素
STDataType StackTop(Stack* ps) {
assert(ps);
int top = ps->top - 1;
return ps->a[top];
}
// 获取栈中有效元素个数
int StackSize(Stack* ps) {
assert(ps);
return ps->top;
}
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
bool StackEmpty(Stack* ps) {
assert(ps);
if (StackSize(ps) == 0)
{
return true;
}
else {
return false;
}
}
// 销毁栈
void StackDestroy(Stack* ps) {
assert(ps);
free(ps->a);
ps->a = NULL;
ps->top = ps->capacity = 0;
}
typedef struct {
Stack s1;
Stack s2;
} MyQueue;
MyQueue* myQueueCreate() {
MyQueue* obj=(MyQueue*)malloc(sizeof(MyQueue));
StackInit(&obj->s1);
StackInit(&obj->s2);
return obj;
}
void myQueuePush(MyQueue* obj, int x) {
StackPush(&obj->s1, x);
}
int myQueuePop(MyQueue* obj) {
Stack* empty = &obj->s1;
Stack* notempty = &obj->s2;
if (StackEmpty(notempty)) {
empty = &obj->s2;
notempty = &obj->s1;
}
while(StackSize(notempty)>1){
StackPush(empty, StackTop(notempty));
StackPop(notempty);
}
int ret=StackTop(notempty);
StackPop(notempty);
while(StackSize(empty)){
StackPush(notempty, StackTop(empty));
StackPop(empty);
}
return ret;
}
int myQueuePeek(MyQueue* obj) {
Stack* empty = &obj->s1;
Stack* notempty = &obj->s2;
if (StackEmpty(notempty)) {
empty = &obj->s2;
notempty = &obj->s1;
}
while(StackSize(notempty)>1){
StackPush(empty, StackTop(notempty));
StackPop(notempty);
}
int ret=StackTop(notempty);
while(StackSize(empty)){
StackPush(notempty, StackTop(empty));
StackPop(empty);
}
return ret;
}
bool myQueueEmpty(MyQueue* obj) {
return StackEmpty(&obj->s1)&&StackEmpty(&obj->s2);
}
void myQueueFree(MyQueue* obj) {
StackDestroy(&obj->s1);
StackDestroy(&obj->s2);
free(obj);
}
/**
* Your MyQueue struct will be instantiated and called as such:
* MyQueue* obj = myQueueCreate();
* myQueuePush(obj, x);
* int param_2 = myQueuePop(obj);
* int param_3 = myQueuePeek(obj);
* bool param_4 = myQueueEmpty(obj);
* myQueueFree(obj);
*/