用两个队列实现栈的功能

用两个队列实现栈的功能

Test.c

#include "Queue.h"

////T1 用队列实现栈
// 请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push\top\pop\empty)
// 实现 MyStack 类:
// void push(int x) 将元素x压入栈顶。
// int pop() 移除并返回栈顶元素
// int top() 返回栈顶元素
// boolean empty() 如果栈是空的,返回 true;否则,返回false.

//解题思路:调用之前写好的队列 

typedef struct MyStack //定义栈(结构体)
{
	Queue q1;
	Queue q2; //栈里面包含了两个队列,用来模拟实现栈后入先出的功能
}MyStack;

//栈的初始化
void myStackCreate()
{
	MyStack* obj=(MyStack*)malloc(sizeof(MyStack)); //为栈开辟空间
	if (NULL==obj)
	{
		printf("malloc fail\n");
		exit(-1);
	}
	QueueInit(&obj->q1);
	QueueInit(&obj->q2); //将栈内的两个队列初始化
	return obj;
}



//栈插入数据 (插入数据时,要保障一个栈内队列为空,一个不为空)
void myStackPush(MyStack* obj,QDataType x)
{
	if (!QueueEmpty(&obj->q1))
	{
		QueuePush(&obj->q1,x); //q1队列不为空时,往q1里面插数据
	}
	else
	{
		QueuePush(&obj->q2,x);//q1队列为空时,往q2里面插数据
	}
}

//删除并返回栈顶元素
QDataType myStackPop(MyStack* obj)
{
	//定义 emptyQ为空队列、nonEmptyQ为非空队列
	Queue emptyQ = obj->q1;
	Queue nonEmptyQ = obj->q2;
	if (!QueueEmpty(&obj->q1))
	{
		emptyQ = obj->q2;
		nonEmptyQ = obj->q1;
	}

    //将非空队列里的元素都(剩余最后一个元素)倒入空队列中
	while (QueueSize(&nonEmptyQ)>1)
	{
		QueuePush(&emptyQ, QueueFront(&nonEmptyQ));
		QueuePop(&nonEmptyQ);
	}
	//将非空对列中最后一个元素直接pop出
	int top = QueueFront(&nonEmptyQ);
	QueuePop(&nonEmptyQ); // 这一步就是真正的删除MyStack的栈顶元素
	return top; //并返回栈顶元素

}

//取栈顶的元素
QDataType myStackTop(MyStack* obj)
{
	if (!QueueEmpty(&obj->q1))
	{
		return QueueBack(&obj->q1); //当q1不为空时,就取q1队尾的元素返回
     }
	else
	{
		return QueueBack(&obj->q2); //当q1为空时,就取q2队尾的元素返回
	}
}

//打印栈顶的元素
void myStackPrint(MyStack* obj)
{
	if (!QueueEmpty(&obj->q1))
	{
		while (!QueueEmpty(&obj->q1))
		{
			printf("%d ",QueueFront(&obj->q1));
			QueuePop(&obj->q1);
		}
		printf("\n");
	}
	else
	{
		while (!QueueEmpty(&obj->q2))
		{
			printf("%d ", QueueFront(&obj->q2));
			QueuePop(&obj->q2);
		}
		printf("\n");
	}

}


//判断栈是否为空
bool myStackEmpty(MyStack* obj)
{
	return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2); //两个对列均为空,才返回true(空)
}

//释放栈开辟的空间
void myStackFree(MyStack* obj)
{
	QueueDestroy(&obj->q1);
	QueueDestroy(&obj->q2);

	free(obj);
	obj = NULL;
}

Queue.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>

//数据类型的申明

typedef int QDataType;
typedef struct QueueNode //定义队列结点
{
	struct QueueNode* next;
	QDataType data;
}QNode;

typedef struct Queue  //定义队列
{
	int size;
	QNode* head;
	QNode* tail;
}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);//取队尾的数据
bool QueueEmpty(Queue* pq); //判断队列是否为空
int QueueSize(Queue* pq); //计算队列结点的个数

Queue.c

#include "Queue.h"

void QueueInit(Queue* pq) //初始化队列
{
	assert(pq);
	pq->size = 0;
	pq->head = pq->tail = NULL;
}

void QueueDestroy(Queue* pq) //销毁队列开辟的空间
{
	assert(pq);
	QNode* cur = pq->head; //定义结点cur,便于遍历队列
	while (cur)
	{
		QNode* next = cur->next; // 先保存cur的下一个结点
		free(cur); //再释放掉
		cur = next; //最后,cur后移一个结点
	}
	pq->head = pq->tail = NULL;
}


void QueuePush(Queue* pq, QDataType x) //队尾插数据
{
	assert(pq);
	//1、构建新的队列节点
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (NULL==newnode)
	{
		printf("malloc fail\n");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;
	
	//2、链接新节点并后移tail
	if (NULL == pq->tail) //(1)队列为空时
	{
		pq->head = pq->tail = newnode;
	}
	else //(2)队列不为空时
	{
		pq->tail->next = newnode; //将新节点链接在tail后面
		pq->tail = newnode; //tail后移一个
	}
	pq->size++;
}

void QueuePop(Queue* pq)  //对头删数据
{
	assert(pq);
	assert(!QueueEmpty(pq));  //当队列中没有结点时
	if (pq->head->next==NULL) //当队列中仅有一个结点时
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else //当队列中有多个节点时
	{
		QNode* next = pq->head->next; //先保存head的下一个结点
		free(pq->head);
		pq->head = next;// head后移一个
	}
	pq->size--;
}

QDataType QueueFront(Queue* pq) //取对头的数据
{
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->head->data;
}

QDataType QueueBack(Queue* pq) //取队尾的数据
{
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->tail->data;
}

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

int QueueSize(Queue* pq) //计算队列结点的个数
{
	assert(pq);
	return pq->size;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值