栈和队列相关题目

题目一:实现一个栈,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值)的时间复杂度为O(1)
本题目的GitHub地址

  • 本题目的实现思路比较简单,使用两个栈,一个栈是用来存储数字,就是普通的数据,在代码中这个栈为Stack

  • 结构体的设计:数字+出现次数,另一个栈便用来存储结构体,在代码中这个栈为NumStack,这个栈的栈顶永远存的是Stack栈中的最小值和最小值个数构成的结构体

  • 所以我们将要设计的这个栈命名为DoubleStack,提供入栈,出栈,返回最小值得接口和其它基本接口

  • 入栈:首先我们先考虑入栈,入栈的时候呢,对于Stack肯定是必须要入栈的,对于NumStack的话就需要考虑了,如果NumStack是空栈,那么肯定是第一次进入元素,所以两个栈都要存东西,而且对于第一次存入的应该将最小值对应的结构体设置为1

  • 如果NumStack 栈不为空的话,那么在压栈之前就需要比较大小,如果比NumStack 栈栈顶元素还小的话就需要将这个较小值压栈,如果相等的话就对栈顶元素的结构体的num+1即可!

  • 出栈:首先还是先要获取栈顶元素,因为不是每一次入Stack 栈的元素都能存入到NumStack 中,所以要出栈的元素和NumStack 的栈顶相等的话就将对应的结构体的count属性-1,要是count原本就是1,那么直接将此元素在NumSatck 中出栈即可!

  • 上一步只是判断NumStack 中的元素是否需要出栈,但是将Stack 中的元素出栈是必要的,所以最后将Stack 中的元素弹栈!

GIF演示过程——入栈
这里写图片描述
GIF演示过程——出栈
这里写图片描述

void DoubleStackPush(DoubleStack* ds, IDataType x)
{
   
	SDataType s;
	SDataType ret;
	assert(ds);

	//如果结构体栈为空
	if(NStackEmpty(&ds->nst) == 0)
	{
   
		s.count = 1;
		s.num = x;
		StackPush(&ds->st,x);
		NStackPush(&ds->nst, s);
	}
	else
	{
   	
		StackPush(&ds->st, x);
		//如果入栈的元素小于最小值记录栈的栈顶
		if(x < NStackTop(&ds->nst).num)
		{
   
			s.num = x;
			s.count = 1;
			//将此元素的对应结构体入栈
			NStackPush(&ds->nst, s);
		}
		else if (x == NStackTop(&ds->nst).num) 
		{
   
			//相等的情况
			ret = NStackTop(&ds->nst);
			NStackPop(&ds->nst);
			ret.count += 1;
			NStackPush(&ds->nst, ret);
		}
	}
}
void DoubleStackPop(DoubleStack* ds)
{
   
	SDataType ret;
	assert(ds);
	//先获取结构体栈的栈顶元素
	ret = NStackTop(&ds->nst);

	//如果像个相等就做结构体计数-1或者出栈操作
	if(ret.num == StackTop(&ds->st))
	{
   
		if(ret.count == 1)
		{
   
			NStackPop(&ds->nst);
		}
		else 
		{
   
			ret.count--;
			NStackPop(&ds->nst);
			NStackPush(&ds->nst, ret);
		}
	}
	//将原本存数字出栈
	StackPop(&ds->st);
}

题目二:一个数组实现两个栈(共享栈)

本题需要使用一个数组来完成两个栈,于是最容易实现这两个栈的方法就是奇偶栈!
数组中的奇数位用来存储一个栈的数据,偶数位用来存储另一个栈的数据!
这里写图片描述

#include "ShareStack.h"

void ShareStackInit(ShareStack* pss)
{
   
	assert(pss);
	pss->_top1 = 0;
	pss->_top2 = 1;
}

//which 1/2
void ShareStackPush(ShareStack* pss, SSDataType x, int which)
{
   
	assert(pss && (which == 1 || which == 2));
	if (pss->_top1 < N && pss->_top2 < N)
	{
   
		if (which == 1)
		{
   
			pss->_a[pss->_top1] = x;
			pss
  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值