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

面试题——栈与队列的应用(下)

2016-04-18 20:10 393 查看
栈与队列的应用 在“栈与队列的应用(上)”中,通过讨论两个队列实现一个栈和两个栈实现一个队列这两个问题,我们对栈和队列也有了更深的了解,下面我们主要来讨论以下两个面试中常常会遇到的问题:
1)一个数组实现两个栈
2)实现一个栈,能够push、pop、min(求栈中最小的数据)

问题一:
对于一个数组,我们如何能够使其成为两个栈?根据数组和栈的特点,我们不难发现可以将数组的两端作为栈的栈底,使用两个指针分别指向数组的开始位置和末尾位置,假设将数组的左边作为栈s1,数组的右边作为栈s2,若s1中的栈顶指针向后在偏移一个位置与另一个指针同时指向一块空间,此时就称为“栈满”,不能进行插入操作。如果想要对栈进行操作,就必须要指定对哪个栈操作。这里使用了两个整形变量用来记录栈s1和栈s2的栈顶的位置下标,对其进行操作。

下面为简单的图示:




下面是具体的程序代码:

//一个数组实现两个栈
//方法一:(静态数组)
#include <iostream>
using namespace std;
#include <stdlib.h>
#define MAX 100

template <class T>
class TwoStack
{
public:
TwoStack()     //构造函数
:_array(new T[MAX])
, lefttop0(-1)
, righttop1(MAX)
{ }

public:
void Push(T x, int i)     //压栈,将数据压入i号栈中
{
if (lefttop0 + 1 == righttop1)
{
cout << "栈已满,不能压栈!";
return;
}
else
{
switch (i)
{
case 0:                       //压入0号栈中
lefttop0++;
_array[lefttop0] = x;
break;
case 1:               //压入1号栈中
righttop1--;
_array[righttop1] = x;
break;
default:
break;
}
}
}

void Pop(int i)     //i号栈、元素出栈
{
switch (i)
{
case 0:
if (lefttop0 == -1)
{
cout << "The Stack is Empty!" << endl;
}
lefttop0--;
break;
case 1:
if (righttop1 == MAX)
{
cout << "The Stack is Empty!" << endl;
}
righttop1++;
break;
default:
break;
}
}

T& top(int i)          //读取i号栈中元素
{
if (i == 0)
{
return _array[lefttop0];
}
else
{
return _array[righttop1];
}
}

void Display(int i)      //打印i号栈的元素
{
if (i == 0)
{
cout << "打印0号栈中的元素:" << endl;
while (lefttop0 != -1)
{
cout << _array[lefttop0] << " ";
lefttop0--;
}
cout << endl;
}
else if (i == 1)
{
cout << "打印1号栈中的元素:" << endl;
while (righttop1 != MAX)
{
cout << _array[righttop1] << " ";
righttop1++;
}
cout << endl;
}
}

private:
T* _array;
int lefttop0;
int righttop1;
};


问题二:
这个问题主要是要实现求栈中最小数据,完成这个功能,就需要借助另一个栈对最小数据进行保存,假设现有栈s1和栈s2,当向s1中插入第一个数据时,同时也向s2中插入相同的数据,下来在向s1中插入第二个数据,此时若第二个数据小于s2的栈顶数据,此时也将与之相同的数据插入s2中,若第二个数据小于s2的栈顶数据,则不用向s2中插入数据,按照这样的方式插入数据。现在就能够显而易见的知道s2中的栈顶数据就是栈s1中的最小数据。
如果需要对s1中数据进行删除,如若s1中要删除的数据与s2中要删除的数据相同,则栈s2中同样删除栈顶元素,若不等,则将s1中栈顶元素删除就行,不需要删除s2中的数据。这样就能够始终保持s2中栈顶数据为栈s1中的最小数据。

下面是简单的图示:


下面为具体的程序代码:

//判断出对序列中的最小数据
//实现一个栈,要求实现Push、pop、min(返回栈中最小值)的时间复杂度为o(1)。
#include <iostream>
using namespace std;
#include <stdlib.h>
#include <stack>

template <class T>
class Stack
{
public:
void Push(const T& x)
{
if (s1.empty() && s2.empty())
{
s1.push(x);
s2.push(x);
}
else if (!s1.empty())
{
if (x < s2.top())
{
s1.push(x);
s2.push(x);
}
else
{
s1.push(x);
}
}
}

void Pop()
{
if (!s1.empty() && !s2.empty())
{
if (s1.top() == s2.top())
{
s1.pop();
s2.pop();
}
else
{
s1.pop();
}
}
}

T minNumber()
{
return s2.top();
}
private:
stack<T> s1;
stack<T> s2;
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  面试题 队列