leetcode 225. 用队列实现栈

请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。

思路:队列是先进先出,栈是后进先出

实现入栈:
向不为空的队列中入队,保持另一个队列为空

在这里插入图片描述

实现出栈:
非空队列依次出队,将数据转移到空队列中保存,只剩最后一个数据出队列

在这里插入图片描述
在这里插入图片描述

代码实现

//队列数据类型
typedef int QDataType;

//队列中数据结构体
typedef struct QueueNode
{
	struct QueueNode* next;
	QDataType data;
}QueueNode;


typedef struct Queue
{
	QueueNode* head;//队头指针
	QueueNode* tail;//队尾指针
	//size_t size;
}Queue;

//队列初始化
void QueueInit(Queue* pq);

//销毁队列
void QueueDestroy(Queue* pq);

//入队
void QueuePush(Queue* pq,QDataType x);

//出队
void QueuePop(Queue* pq);

//获取队头元素
QDataType QueueFront(Queue* pq);

//获取队尾元素
QDataType QueueBack(Queue* pq);

//获取队列中有效元素个数
int QueueSize(Queue* pq);

//检测队列是否为空,如果为空返回非零结果,如果非空返回0
bool QueueEmpty(Queue* pq);

void QueueInit(Queue* pq)
{
	//我们需要改变结构体的内容(需要改变结构成员head,tail),所以传入结构体指针
	//对于结构的指针成员,要初始化
	assert(pq);
	pq->head = NULL;
	pq->tail = NULL;
}


void QueueDestroy(Queue* pq)
{
	assert(pq);
	QueueNode* cur = pq->head;

	while (cur != NULL)
	{
		QueueNode* next = cur->next;
		free(cur);
		cur = NULL;
	}
	pq->head = pq->tail = NULL;
}

void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);

	QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
	newnode->data = x;
	newnode->next = NULL;

	if (pq->head == NULL)
	{
		//1.队列为空
		pq->head = pq->tail = newnode;
	}
	else
	{
		//2.队列不为空,尾部直接插入
		pq->tail->next = newnode;
		pq->tail = newnode;
	}

}

bool QueueEmpty(Queue* pq)
{
	//队列为空时 head == NULL
    assert(pq);
	return pq->head == NULL;
}


void QueuePop(Queue* pq)
{
	assert(pq);//结构体指针是不可能为空的,结构体成员指针指向NULL,与
	//结构体指针为空没有任何关系
	
	//1.队列空
	//assert(pq->head!=NULL);
	assert(!QueueEmpty(pq));

	
	QueueNode* next = pq->head->next;
	free(pq->head);
	pq->head = next;

	if (pq->head == NULL)
	{
		//2.只有一个元素 head = tail 注意处理tail变成野指针的情况
		//链表已经删完了
		pq->tail = NULL;
	}	
}


QDataType QueueBack(Queue* pq)
{
	assert(pq);
	//assert(pq->tail!=NULL);
	assert(!QueueEmpty(pq));
	return pq->tail->data;
}

QDataType QueueFront(Queue* pq)
{
	assert(pq);
	//assert(pq->head!=NULL);
	assert(!QueueEmpty(pq));
	return pq->head->data;
}

int QueueSize(Queue* pq)
{
	assert(pq);
	QueueNode* cur = pq->head;
	int sz = 0;
	
	//遍历队列
	while (cur!= NULL)
	{
		sz++;
		cur = cur->next;
	}
	return sz;
}

//对匿名结构体重命名
//定义栈结构体类型
typedef struct {
    Queue q1;
    Queue q2;
} MyStack;

MyStack* myStackCreate() {
    //st是野指针,这样错误
    // MyStack s;
    // MyStack* st = &s;
    // return st;

	//为了保证除了函数作用域,结构体指针还存在,这里选择在堆上开辟空间
	//不建议使用全局变量
    MyStack* st = (MyStack*)malloc(sizeof(MyStack));
    
    // if(st == NULL)
    // {
    //     exit(-1);
    // }
    //初始化
    //(st->q1).head = NULL
    
    //使用接口进行初始化
    QueueInit(&(st->q1));
    QueueInit(&(st->q2));
    return st;

}

void myStackPush(MyStack* obj, int x) 
{
	//非空队列入队
    if(!QueueEmpty(&obj->q1))
    {
        QueuePush(&obj->q1,x);
    }
    else
    {
        QueuePush(&obj->q2,x);
    }
}

int myStackPop(MyStack* obj) {
    //将非空队列的数据转移到另一个队列
    Queue* emptyQ = &obj->q1;
    Queue* nonEmptyQ = &obj->q2;
	
	//
    if(!QueueEmpty(&obj->q1))
    {
        //q1不为空
        emptyQ = &obj->q2;
        nonEmptyQ = &obj->q1;
    }

    while(QueueSize(nonEmptyQ)>1)
    {
 	   	//非空队列依次出队,空队列依次入队
        QueuePush(emptyQ,QueueFront(nonEmptyQ));
        QueuePop(nonEmptyQ);
    }
	//非空队列最后一个元素出队
    int top = QueueFront(nonEmptyQ);
    QueuePop(nonEmptyQ);

    return top;
}

//返回栈顶元素
int myStackTop(MyStack* obj) 
{
	//返回非空队列队尾元素
    if(!QueueEmpty(&obj->q1))
    {
        return QueueBack(&obj->q1);
    }
    else{
        return QueueBack(&obj->q2);
    }
}

bool myStackEmpty(MyStack* obj)
{
	//两个队列都不为空,则栈不为空
    return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2);
}

void myStackFree(MyStack* obj)
 {
 	//先销毁两个队列
    QueueDestroy(&obj->q1);
    QueueDestroy(&obj->q2);

    free(obj);
    //obj = NULL;
}
 

测试代码:

int main()
{
	MyStack* obj = myStackCreate();
	myStackPush(obj, 1);
	myStackPush(obj, 2);
	myStackPush(obj, 3);
	 
	int param_2 = myStackPop(obj); 
	int param_3 = myStackTop(obj); 
	 
	bool param_4 = myStackEmpty(obj); 
	myStackFree(obj);
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值