栈和队列面试题

栈和队列实现的代码在链接中的博客中https://blog.csdn.net/Damn_Yang/article/details/83928852

1.实现一个栈,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值)的时间复杂度为O(1)

思路:我们借助两个栈来进行操作(stack1和stack2)

           入栈时:stack1正常入栈,如果stack2为空或者stack2栈顶的元素大于等于入栈的元素,stack2也入栈

           出栈时:如果stack1栈顶的元素等于stack2栈顶的元素,则stack2出栈。不等于的话,stack1出栈

           返回最小值:返回stack2栈顶的元素

代码实现:

头文件:

#include "Stack.h"
typedef int MstDataType;

typedef struct MinStack
{
	Stack _st;
	Stack _minst;
}MinStack;


void MinStackInit(MinStack* pms);
void MinStackDestory(MinStack* pms);


void MinStackPush(MinStack* pms,MstDataType x);
void MinStackPop(MinStack* pms);

DataType MinStackMin(MinStack* pms);

函数实现

#include"Topic.h"


void MinStackInit(MinStack* pms)
{
	assert(pms);
	StackInit(&pms->_st);
	StackInit(&pms->_minst);

}
void MinStackDestory(MinStack* pms)
{
	assert(pms);
	StackDestory(&pms->_st);
	StackDestory(&pms->_minst);

}

void MinStackPush(MinStack* pms, MstDataType x)
{
	assert(pms);
	StackPush(&pms->_st, x);
	if (StackEmpty(&pms->_minst) == 0 || StackTop(&pms->_minst) >= x)
	{
		StackPush(&pms->_minst, x);
	}
}
void MinStackPop(MinStack* pms)
{
	assert(pms);
	if (StackTop(&pms->_st) == StackTop(&pms->_minst))
	{
		StackPop(&pms->_minst);
	}
	StackPop(&pms->_st);

}

DataType MinStackMin(MinStack* pms)
{
	assert(pms);
	return StackTop(&pms->_minst);
}


void TestMinStack()
{
	MinStack pms;
	MinStackInit(&pms);
	MinStackPush(&pms, 4);
	MinStackPush(&pms, 5);
	MinStackPush(&pms, 3);
	MinStackPush(&pms, 3);
	MinStackPush(&pms, 2);
	MinStackPush(&pms, 3);

	while (StackEmpty(&pms._st) != 0)
	{
		printf("最小值:%d\n", MinStackMin(&pms));
		MinStackPop(&pms);
	}
}

int main()
{
	TestMinStack();
	return 0;
}

2.使用两个栈实现一个队列

这道题在我写的另一篇博客中:https://blog.csdn.net/Damn_Yang/article/details/84103454

3.使用两个队列实现一个栈

这道题在我写的另一篇博客中:https://blog.csdn.net/Damn_Yang/article/details/84103454

4.元素出栈、入栈顺序的合法性。如入栈的序列(1,2,3,4,5),出栈序列为(4,5,3,2,1)

思路:定义一个栈st,入栈序列为in,出栈序列为out,长度分别为insize和outsize。如果两个序列为空或长度不等,则不合法,针对长度相等且不为空的两个序列进行判断。

先将in中第一个元素入栈,然后通过循环使后移。

1、如果当前栈为空且入栈序列不为空,则入栈序列in后移,st入栈。

2、如果栈顶元素不等于出栈序列且入栈序列不为空,则入栈序列in后移,st入栈。

3、如果栈顶元素等于出栈序列,st出栈,出栈序列out后移。

循环比较后,如果栈为空,则出栈序列是合法的,否则是不合法的


//元素出栈 入栈的合法性
int IsLegalStackOrder(int * in, int insize, int*out, int outsize)
{
	assert(in&&out&&insize == outsize);
	Stack st;
	StackInit(&st);
	int inindex = 0;
	int outindex = 0;
	while (inindex < insize)
	{
		StackPush(&st, in[inindex]);
		++inindex;
		while (StackEmpty(&st) && StackTop(&st) == out[outindex])
		{
			StackPop(&st);
			++outindex;
		}
	}
	if (StackEmpty(&st) == 0)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}
int main()
{
	int in[] = { 1,2,3,4,5 };
	int out[] = { 4,5,3,2,1 };
	if (IsLegalStackOrder(in, 5, out, 5) == 1)
	{
		printf("合法\n");
	}
	else
	{
		printf("不合法");
	}
	
	return 0;
}

5.一个数组实现两个栈(共享栈)

思路:将数组的下标为0的位置当做第一个栈的栈底,下标为1的位置当做第二个栈的栈底,将数组的偶数位置看做第一个栈的存储空间,奇数位置看做第二个栈的存储空间。

代码实现:

ShareStack.h

#include<stdio.h>
#include<assert.h>

#define N 100

typedef int DataType;
typedef struct ShareStack
{
	DataType _a[N];
	int _top1;
	int _top2;

}ShareStack;


void ShareStackInit(ShareStack*pss);
void ShareStackPush(ShareStack*pss,DataType x,int which);
void ShareStackPop(ShareStack*pss);
DataType ShareStackTop(ShareStack*pss, int which);


int ShareStackEmpty(ShareStack*pss,int which);


ShareStack.c

#include"ShareStack.h"


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

}
void ShareStackPush(ShareStack*pss, DataType x, int which)
{
	assert(pss);
	if (which == 1)
	{
		pss->_a[pss->_top1] = x;
		pss->_top1 += 2;
	}
	else if (which == 2)
	{
		pss->_a[pss->_top2] = x;
		pss->_top2 += 2;
	}

}

void ShareStackPop(ShareStack*pss,int which)
{
	assert(pss);
	assert(which == 1 || which == 2);
	if (which == 1)
	{
		pss->_top1 -= 2;
	}
	else
	{
		pss->_top2 -= 2;
	}
}
DataType ShareStackTop(ShareStack*pss, int which)
{
	assert(pss);
	assert(which == 1 || which == 2);
	if (which == 1)
	{
		return pss->_a[pss->_top1 - 2];
	}
	else
	{
		return pss->_a[pss->_top2 - 2];

	}
}

int ShareStackEmpty(ShareStack*pss, int which)
{
	assert(pss);
	assert(which == 1 || which == 2);
	if ((pss->_top1 == 0 && which == 1) || (pss->_top2 == 1 && which == 2))
	{
		return 0;
	}
	else
	{
		return 1;
	}
}

TestShareStack()
{
	ShareStack pss;
	ShareStackInit(&pss);
	ShareStackPush(&pss, 1 ,1);
	ShareStackPush(&pss, 2, 1);
	ShareStackPush(&pss, 3, 1);
	ShareStackPush(&pss, 1, 2);
	ShareStackPush(&pss, 2, 2);
	ShareStackPush(&pss, 3, 2);

	while (ShareStackEmpty(&pss, 1))
	{
		printf("%d ", ShareStackTop(&pss, 1));
		ShareStackPop(&pss, 1);
	}
	printf("\n");
	while (ShareStackEmpty(&pss, 2))
	{
		printf("%d ", ShareStackTop(&pss, 2));
		ShareStackPop(&pss, 2);
	}
}

int main()
{
	TestShareStack();
	return 0;
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值