代码随想录训练营第十天|232.用栈实现队列、225.用队列实现栈

目录

栈:先进后出

队列:先进先出

232.用栈实现队列

225.用队列实现栈


栈:先进后出

栈顶插入、栈顶删除

栈的基本操作

  1. 初始化
  2. 判断栈空
  3. 入栈
  4. 出栈
  5. 销毁

线性栈的实现:

#define stack_size 10
typedef struct{
	int stackTop;
	int stack[stack_size];
}Mystack;
//初始化
void Inite(Mystack * s){
	s->stackTop=-1;
} 
//判断栈空 
bool Is_empty(Mystack * s){
	return (s->stackTop<0)?true:false;
}
//入栈
void push(Mystack * s,int value){
	s->stack[++(s->stackTop)]=value;
} 
//出栈栈顶元素并返回其值
int pop(Mystack * s){
	if(Is_empty(s)){
		printf("栈空\n");
		return EOF;
	}
	return s->stack[(s->stackTop)--];
}
//输出栈内元素 
void Print(Mystack * s){
	for(int i=0;i<=(s->stackTop);i++){
		printf("%d ",s->stack[i]);
	}
	printf("\n");
}
//销毁
void Destroy(Mystack * s){
	s->stackTop=-1;
} 

队列:先进先出

队头插入、队尾删除

队列的基本操作

  1. 初始化
  2. 判断队空
  3. 入队
  4. 出队
  5. 销毁

链队的实现:

#include<stdio.h>
#include<stdlib.h>
#define Queue_size 10
typedef struct QNode{
	int data;
	struct QNode* next;
}QNode;
typedef struct Queue{
	QNode* head;
	QNode* tail;
	int size;
}Queue;
//初始化 
void InitQueue(Queue* Q){
	Q->head=Q->tail=NULL;
	Q->size=0;
}
//判断队空
bool Is_empty(Queue* Q){
	//如果没有size:
	return  Q->head==Q->tail;
//	return !Q->size;
}
//入队
void EnQueue(Queue* Q,int value){
	QNode* NewNode=(QNode*)malloc(sizeof(QNode));
	NewNode->data=value;
	NewNode->next=NULL;
	if(Q->size==0){
		Q->head=Q->tail=NewNode;
	}else{
		Q->tail->next=NewNode;
		Q->tail=NewNode;
	}
	Q->size++;
}
//出队并返回值 
int OutQueue(Queue* Q){
	if(Q->size==0){
		printf("队空,无法出队\n");
		return NULL;
	}
	int value=Q->head->data;
	Q->head=Q->head->next;
	Q->size--;
	return value; 
}
//销毁
void Destroy(Queue* Q){
	Q->head=Q->tail=NULL;
	Q->size=0;
} 
//输出队列
void Print(Queue* Q){
	QNode* temp=Q->head;
	for(int i=0;i<Q->size;i++,temp=temp->next){
		printf("%d ",temp->data);
	}
	putchar('\n');
}
int main(){
	Queue* MyQueue=(Queue*)malloc(sizeof(Queue));
	InitQueue(MyQueue);
	if(Is_empty(MyQueue)){
		printf("队空\n");
	}
	for(int i=0;i<Queue_size;i++){
		EnQueue(MyQueue,i*i);
	}
	Print(MyQueue);
	printf("出队%d\n",OutQueue(MyQueue));
	Print(MyQueue);
	return 0; 
} 

232.用栈实现队列

题目链接:力扣

题目描述:仅使用两个栈实现先入先出队列。

typedef struct{
    //定义入栈、出栈栈顶
    int stackInTop,stackOutTop;
    //定义入栈、出栈
    int stackIn[100],stackOut[100];
} MyQueue;

//创建
MyQueue* myQueueCreate() {
    MyQueue* queue=(MyQueue*)malloc(sizeof(MyQueue));
    //初始两栈顶为0
    queue->stackInTop=-1;
    queue->stackOutTop=-1;
    return queue;
}

void myQueuePush(MyQueue* obj, int x) {
    obj->stackIn[++(obj->stackInTop)]=x;
}

int myQueuePop(MyQueue* obj) {
    int stackInTop=obj->stackInTop;
    int stackOutTop=obj->stackOutTop;
    //从入栈导入出栈
    if(stackOutTop==-1){
        while(stackInTop>=0){
            obj->stackOut[++stackOutTop]=obj->stackIn[stackInTop--];
        }
    }
    // //队列第一个元素是出栈的最后一个元素
    int top=obj->stackOut[stackOutTop--];
    //出栈再导出入栈
    while(stackOutTop>=0){
        obj->stackIn[++stackInTop]=obj->stackOut[stackOutTop--];
    }
    //更新栈顶
    obj->stackInTop=stackInTop;
    obj->stackOutTop=stackOutTop;
    return top;
}

int myQueuePeek(MyQueue* obj) {
    return obj->stackIn[0];
}

bool myQueueEmpty(MyQueue* obj) {
    if(obj->stackInTop==-1&&obj->stackOutTop==-1){
        return true;
    }
    return false;
}

void myQueueFree(MyQueue* obj) {
    obj->stackInTop=-1;
    obj->stackOutTop=-1;
}

225.用队列实现栈

题目链接:力扣

题目描述:仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作。

对于这种题目,老是迷惑结构体定义的细节,需要在别人代码的基础上改动,逻辑是了解的。

// 使用两个队列实现栈
// 使用两个数组(队列)和四个指针定义栈,指针分别指向对应的队首和队尾
typedef struct {
    int queue1[100], queue2[100];
    int front1, front2;
    int rear1, rear2;
} MyStack;

// 开辟一个栈
MyStack* myStackCreate() {
    MyStack* stack=malloc(sizeof(MyStack));
    stack->front1=0;
    stack->front2=0;
    stack->rear1=0;
    stack->rear2=0;
    return stack;
}

// 将元素存入队列中,存入后队尾指针 +1
void myStackPush(MyStack* obj, int x) {
    obj->queue1[(obj->rear1)++] = x;
}

int myStackPop(MyStack* obj) {
    // 优化:复制指针,减少对内存的访问次数
    int front1 = obj->front1, front2 = obj->front2;
    int rear1 = obj->rear1, rear2 = obj->rear2;

    // 将 queue1 除最后面的元素以外的所有元素都备份到 queue2
    while (rear1 - front1 > 1) {
        obj->queue2[rear2++] = obj->queue1[front1++];
    }
    // 弹出 queue1 的最后一个元素并保存
    int top = obj->queue1[front1++];
    // 将其他元素从 queue2 导回 queue1
    while (front2 != rear2) {
        obj->queue1[rear1++] = obj->queue2[front2++];
    }

    // 更新队首队尾指针
    obj->front1 = front1, obj->front2 = front2;
    obj->rear1 = rear1, obj->rear2 = rear2;

    // 返回栈顶指针
    return top;
}

// 直接返回队尾元素
int myStackTop(MyStack* obj) {
    // 注意队列的队尾是 rear-1 而不是 rear
    return obj->queue1[(obj->rear1) - 1];
}

// 若队首队尾指针相等,则队列为空,即栈为空
bool myStackEmpty(MyStack* obj) {
    return obj->rear1 == obj->front1;
}

// 将队首队尾指针都归 0
void myStackFree(MyStack* obj) {
    obj->front1 = 0, obj->front2 = 0;
    obj->rear1 = 0, obj->rear2 = 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值