栈与队列---用两个队列实现栈

使用两个队列实现先入后出的栈,并且支持栈的插入删除、获取栈顶元素、检查是否空栈的功能。

思路

两个队列实现栈的思路:所有数据插入在非空的队列队尾,另一个队列用于删除时的倒数据,将size-1个数据倒入到空队列2,最后一个数据即栈顶数据就在队列1的队头,进行保留并删除即可。

栈结构体创建

结构体包含两个队列q1、q2:

typedef struct {
    Queue q1;
    Queue q2;
} MyStack;

栈空间的创建以及栈结构体内两个队列成员的初始化

MyStack* myStackCreate() {
    MyStack* ms = (MyStack*)malloc(sizeof(MyStack));
    QueueInit(&ms->q1);
    QueueInit(&ms->q2);
    return ms;
}

两个队列实现栈的插入操作实现

在非空的队列中插入:

void myStackPush(MyStack* obj, int x) {
    if(!QueueEmpty(&obj->q1))
        QueuePush(&obj->q1,x);
    else
        QueuePush(&obj->q2,x);
}

两个队列实现栈的删除操作实现                                                                                                     

使用假设判断法,创建nonemptyq和emptyq两个队列指针,先使nonemptyq指向q1,再使用if判断,如果q1为空,将nonemptyq指向q2并将emptyq指向q1,后面操作nonemptyq与emptyq指针即可。

删除操作,将nonemptyq指向队列中的前size-1个数据倒入emptyq指向的队列中,再将nonemptyq中最后一个数据获取并删除。

int myStackPop(MyStack* obj) {
    Queue* nonemptyq = &obj->q1;
    Queue* emptyq = &obj->q2;
    if(QueueEmpty(&obj->q1))
    {
        nonemptyq = &obj->q2;
        emptyq = &obj->q1;
    }
    while(QueueSize(nonemptyq)>1)
    {
        QueuePush(emptyq,QueueFront(nonemptyq));
        QueuePop(nonemptyq);
    }
    int tmp = QueueFront(nonemptyq);
    QueuePop(nonemptyq);
    return tmp;
}

获取栈顶数据

即非空队列队尾数据的获取:

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;
}

整体代码如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
//队列---先进先出,FIFO
//队尾进,队头出

//队列的实现用什么?--->链表,单链表与双向链表都行
//不用数组,为什么?--->因为数组尾插虽然方便,但是头删很麻烦
//单链表也不好进行尾插,但是我们可以创建结构体Queue包含尾结点和头结点
#define QueueDataType int 
typedef struct QueueNode
{
	QueueDataType val;
	struct QueueNode* next;
}QNode;

typedef struct Queue
{
	QNode* phead;//头
	QNode* ptail;//尾
	int size;//记录队列数据个数
}Queue;

//初始化
void QueueInit(Queue* pq);
//销毁
void QueueDestroy(Queue* pq);
//插入
void QueuePush(Queue* pq, QueueDataType x);
//删除
void QueuePop(Queue* pq);
//获取队列头部元素
QueueDataType QueueFront(Queue* pq);
//获取队列尾部元素
QueueDataType QueueBack(Queue* pq);
//获取队列有效元素个数
int QueueSize(Queue* pq);
//检测队列是否为空
bool QueueEmpty(Queue* pq);

//初始化
void QueueInit(Queue* pq)
{
	assert(pq);
	pq->phead = NULL;
	pq->ptail = NULL;
	pq->size = 0;
}

//销毁
void QueueDestroy(Queue* pq)
{
	assert(pq);
	QNode* cur = pq->phead;
	while (cur)
	{
		QNode* next = cur->next;
		//pq->phead = pq->phead->next;//不直观
		free(cur);
		cur = next;
	}

	pq->phead = pq->ptail = NULL;
	pq->size = 0;
	pq = NULL;
}

//插入
void QueuePush(Queue* pq, QueueDataType x)
{
	assert(pq);
	//创建插入的结点newnode
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	newnode->next = NULL;
	newnode->val = x;

	//插入
	if (pq->phead == NULL)
	{
		pq->phead = pq->ptail = newnode;
	}
	else
	{
		pq->ptail->next = newnode;
		pq->ptail = newnode;
	}
	pq->size++;
}

//删除
void QueuePop(Queue* pq)
{
	assert(pq);
	assert(pq->phead);//无结点
	//写麻烦了
	//QNode* cur = pq->phead;
	//if (pq->ptail == pq->phead)//1个结点
	//{
	//	free(cur);
	//	pq->phead = pq->ptail = cur = NULL;
	//}
	//else
	//{
	//	//多个结点
	//	QNode* next = cur->next;
	//	free(cur);
	//	cur = NULL;
	//	pq->phead = next;
	//}

	QNode* cur = pq->phead;
	QNode* next = cur->next;
	free(cur);
	cur = NULL;
	pq->phead = next;
	if (pq->phead == NULL)
		pq->ptail = NULL;

	pq->size--;
}

//获取队列头部元素
QueueDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(pq->phead);

	return pq->phead->val;
}

//获取队列尾部元素
QueueDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(pq->phead);

	return pq->ptail->val;
}

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

	return pq->size;
}

//检测队列是否为空
bool QueueEmpty(Queue* pq)
{
	assert(pq);

	return pq->phead == NULL;
}


typedef struct {
    Queue q1;
    Queue q2;
} MyStack;


MyStack* myStackCreate() {
    MyStack* ms = (MyStack*)malloc(sizeof(MyStack));
    QueueInit(&ms->q1);
    QueueInit(&ms->q2);
    return ms;
}

void myStackPush(MyStack* obj, int x) {
    if(!QueueEmpty(&obj->q1))
        QueuePush(&obj->q1,x);
    else
        QueuePush(&obj->q2,x);
}

int myStackPop(MyStack* obj) {
    Queue* nonemptyq = &obj->q1;
    Queue* emptyq = &obj->q2;
    if(QueueEmpty(&obj->q1))
    {
        nonemptyq = &obj->q2;
        emptyq = &obj->q1;
    }
    while(QueueSize(nonemptyq)>1)
    {
        QueuePush(emptyq,QueueFront(nonemptyq));
        QueuePop(nonemptyq);
    }
    int tmp = QueueFront(nonemptyq);
    QueuePop(nonemptyq);
    return tmp;
}

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;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值