您的位置:首页 > 职场人生

栈和队列相关面试题(1)

2016-06-14 13:35 316 查看
1、实现一个栈,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值的操作)的时间复杂度为O(1)

思路:

1、用两个栈实现,一个栈保存所有的入栈元素,另一个栈专门用来保存要返回的最小值

2、用一个栈实现,每次当插入的值大于要返回的最小值时,先把要入栈的元素入栈,再把要返回的最小值入栈,但是感觉这样会

破坏栈的结构


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

思路:当两个栈都为空时,只能做入队操作,当两个栈不都为空时,入队、出队操作都可以实现。

inSta只用于入栈,outSta只用于出栈

过程:

入队:不管outSta是否为空,都直接把元素入栈到inSta

出队:1、当inSta、outSta都为空时,队列里面无元素,无法实现出栈

2、当outSta为空时,把inSta除栈底元素外的所有元素出栈,并按照出栈顺序入栈到outSta,把inSta的栈底元素出栈

3、当outSta不为空时,说明上一操作为出栈,此时把outSta的栈顶元素出栈即可


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

思路:在操作完成后,元素始终只存在于一个队列中,不会存在两个队列中都有元素的情况

过程:

1、入栈:

1、两个队都为空,默认入队到que1

2、把元素入队到不为空的那个队列中

2、出栈:

1、两个对都为空,栈中无元素,无法出栈

2、把不为空的那个队列的除队尾元素全部出队,并按照出队顺序入队到另一个队列,最后再把队尾元素出队即可完成


StackAndQueue.h

<strong><span style="font-size:18px;">#pragma once

#include <iostream>
#include <assert.h>
using namespace std;

#include <stack>
#include <queue>

template<class T>
class TwoStack
{
public:
void Push(const T& data)
{
if (MinDataStack.empty()==true || MinDataStack.top() > data)
{
MinDataStack.push(data);
DataStack.push(data);
}
else
{
DataStack.push(data);
}
}

void Pop()
{
assert(!DataStack.empty());
if (MinDataStack.top() == DataStack.top())
{
MinDataStack.pop();
DataStack.pop();
}
else
{
DataStack.pop();
}
}

T& MinData()
{
assert(!DataStack.empty());
return MinDataStack.top();
}

T& Top()
{
assert(!DataStack.empty());
return DataStack.top();
}

bool Empty()
{
return DataStack.empty();
}

size_t Size()
{
return DataStack.size();
}

private:
stack<T> DataStack;
stack<T> MinDataStack;
};

template<class T>
class TwoStackForQueue
{
public:
void Push(const T& data)
{
InStack.push(data);
}

void Pop()
{
assert(InStack.empty() == false || OutStack.empty() == false);//如果全为空,那么则是空队列,不进行操作
while (InStack.empty() == false)
{
OutStack.push(InStack.top());
InStack.pop();
}
OutStack.pop();
}

T& Front()
{
assert(InStack.empty() == false || OutStack.empty() == false);//如果全为空,那么则是空队列,不进行操作
while (InStack.empty() == false)
{
OutStack.push(InStack.top());
InStack.pop();
}
return OutStack.top();
}

T& Back()
{
assert(InStack.empty() == false || OutStack.empty() == false);//如果全为空,那么则是空队列,不进行操作
while(OutStack.empty() == false)
{
InStack.push(OutStack.top());
OutStack.pop();
}
return InStack.top();
}

bool Empty()
{
return (InStack.empty() == true && OutStack.empty() == true);
}

size_t Size()
{
return InStack.size()+OutStack.size();
}
//友元函数
template<typename T>
friend ostream& operator<<(ostream& os, const TwoStackForQueue<T>& queue);
private:
stack<T> InStack;
stack<T> OutStack;
};

//输出运算符重载
template<class T>
ostream& operator<<(ostream& os,const TwoStackForQueue<T>& queue)
{
TwoStackForQueue<T> coutqueue(queue);

while(coutqueue.OutStack.size() > 0)
{
os<<coutqueue.OutStack.top()<<" ";
coutqueue.OutStack.pop();
}
while (coutqueue.InStack.size() > 0)
{
coutqueue.OutStack.push(coutqueue.InStack.top());
coutqueue.InStack.pop();
}
while(coutqueue.OutStack.size() > 0)
{
os<<coutqueue.OutStack.top()<<" ";
coutqueue.OutStack.pop();
}
return os;
}

template<class T>
class TwoQueueForStack
{
public:
void Push(const T& data)
{
//每次push数据,总能保证一个队列为空
if (_Queue2.empty() == true)
{
_Queue1.push(data);
}
else//_Queue1.empty() == true
{
_Queue2.push(data);
}
}

void pop()
{
assert(_Queue1.empty() == false || _Queue2.empty() == false);
if (_Queue1.empty() == false)
{
while (_Queue1.front() != _Queue1.back())
{
_Queue2.push(_Queue1.front());
_Queue1.pop();
}
_Queue1.pop();
}
else//_Queue2.empty() == false
{
while (_Queue2.front() != _Queue2.back())
{
_Queue1.push(_Queue2.front());
_Queue2.pop();
}
_Queue2.pop();
}
}

T& Top()
{
assert(_Queue1.empty() == false || _Queue2.empty() == false);
if (_Queue1.empty() == false)
{
return _Queue1.back();
}
else
{
return _Queue2.back();
}
}

bool Empty()
{
return _Queue1.empty() == true && _Queue2.empty() == true;
}

size_t Size()
{
return _Queue1.size()+_Queue2.size();
}

//template<typename T>
//friend ostream& operator<<(ostream& os,const TwoQueueForStack<T>& stack);
private:
queue<T> _Queue1;
queue<T> _Queue2;
};

//template<class T>
//ostream& operator<<(ostream& os,const TwoQueueForStack<T>& stack)
//{
//	TwoQueueForStack<T> countstack(stack);
//
//	while (countstack._Queue1.size() > 0)
//	{
//		cout<<countstack._Queue1.front()<<" ";
//		countstack._Queue1.pop();
//	}
//
//	while (countstack._Queue2.size() > 0)
//	{
//		count<<countstack._Queue2.front()<<" ";
//		countstack._Queue2.pop();
//	}
//
//	while (countstack._Queue1.size() > 0)
//	{
//		cout<<countstack._Queue1.front()<<" ";
//		countstack._Queue1.pop();
//	}
//	return os;
//}

</span></strong>


test.cpp

<strong><span style="font-size:18px;">#define _CRT_SECURE_NO_WARNINGS 1
#include "StackAndQueue.h"

void Test1()
{
//实现一个栈,要求实现Push(出栈)、Pop(入栈)、
//Min(返回最小值的操作)的时间复杂度为O(1)
//思路:有两个栈,每次压栈进入DataStack之前,先与MinDataStack的栈顶元素进行
//比较,如果比MinDataStack的栈顶元素小,那么数据即进入DataStack栈中也进入MinDataStack中
TwoStack<int> twostack;
twostack.Push(1);
twostack.Push(5);
twostack.Push(9);
twostack.Push(3);
twostack.Push(2);
twostack.Push(0);
twostack.Push(6);
cout<<twostack.MinData()<<endl;
cout<<twostack.Top()<<endl;
cout<<twostack.Size()<<endl;
cout<<twostack.Empty()<<endl;

twostack.Pop();
twostack.Pop();
twostack.Pop();
cout<<twostack.MinData()<<endl;
cout<<twostack.Top()<<endl;
cout<<twostack.Size()<<endl;
cout<<twostack.Empty()<<endl;
}

void Test2()
{
//使用两个栈实现一个队列
//思路:有两个栈,一个在InStack栈上只操作入栈,一个OutStack栈上只操作出栈
TwoStackForQueue<int> queue;
queue.Push(1);
queue.Push(2);
queue.Push(3);
queue.Push(4);
queue.Push(5);
queue.Push(6);
cout<<queue<<endl;

queue.Pop();
queue.Pop();
cout<<queue<<endl;

cout<<queue.Front()<<endl;
cout<<queue.Back()<<endl;
cout<<queue.Empty()<<endl;
cout<<queue.Size()<<endl;
}

void Test3()
{
//使用两个队列实现一个栈
TwoQueueForStack<int> stack;
stack.Push(6);
stack.Push(8);
stack.Push(0);
stack.Push(5);
stack.Push(9);
stack.Push(1);

stack.pop();
stack.pop();
stack.pop();
stack.pop();
stack.pop();

cout<<stack.Top()<<endl;
cout<<stack.Size()<<endl;
cout<<stack.Empty()<<endl;
}

int main()
{
//Test1();
//Test2();
//Test3();
system("pause");
return 0;
}

</span></strong>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: