数据结构 | 详解栈实现队列&队列实现栈

1. 232. 用队列实现栈

⛱️

🌴深度剖析

1️⃣最关键的push和pop过程如何模拟?

pop:

step0.先利用假设法假定非空队列notempty和空队列empty,再利用MyStackEmpty函数对进行修正

step1:将notempty队列中的前size-1个元素依次push到empty队列中,再进行删除,实现移动操作

step2:此时非空队列中剩下的唯一一个数就是“栈顶”元素,使用QueueFront进行·取值后,直接进行QueuePop删除。

🥳代码实现

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过程如何模拟?

🥳代码实现

方法一(推荐)

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);
*/

方法二

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);
*/

  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值