作者:云梦泽
日期:2013.11.17
地点:湖南大学软件大楼211
一、题目
题目:定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。要求函数min、push以及pop的时间复杂度都是O(1)。
二、基础知识
栈(stack) 是限定在表尾(栈顶)进行插入或删除操作一种线性结构,该结构数据元素有FILO的特点,基本操作包括插入,删除,判断为空等。
三、思路
按照栈的定义,push和pop操作理所当然时间复杂度为O(1),但min只借助于栈是无法达到要求的,因为我们还建设一个辅助栈,辅助栈和主栈平行操作,主栈正常存储数据,辅助栈则平行存储主栈中数值最小的索引。由此我们可通过辅助栈以时间复杂度O(1)顺利找到主栈中得最小值。
四、解决方案
采用C++的模板编程实现。
1.头文件保护符设定,防止多重文件包含
//作者:云梦泽
//日期:2013.11.10
//地点:软件大楼
//描述:Google面试之自定义栈
#ifndef STACK_DESIGN_H //头文件保护符
#define STACK_DESIGN_H
#include <vector>
using namespace std;
2.栈的定义,包括友元,在类模板函数中直接定义友元可恨大程度上避免错误,这是经验法则。
class MyStack
{
public:
MyStack() = default;
virtual ~MyStack() = default;
void push(const T &value);
void pop();
bool empty() const;
const T &top() const;
const T &min() const;
private:
vector<T> myData; //主栈,存放数据
vector<T> minIndex; //辅助栈,存放主栈中最小值的索引
friend void GetInfor(const MyStack &mystack)//友元的定义最好就在模板类直接实现,其实这里并非必要,因为没去访问类的私有变量,我们假如扩展时会有
{
if (!mystack.empty())
{
cout << "当前栈顶元素为: " << mystack.top() << endl;
cout << "当前栈最小元素为:" << mystack.min() << endl;
cout << "当前栈的状态:非空" << endl;
}
else
{
cout << "当前栈的状态:空" << endl;
}
}
};
3.类的实现,模板类函数成员的实现和模板类的定义都放在同一个头文件夹下也是经验法则
template<typename T>
void MyStack<T>::push(const T &value)
{
myData.push_back(value);
if (minIndex.size() == 0)
minIndex.push_back(0);
else
{
if (value < myData[minIndex.back()])
minIndex.push_back(myData.size() - 1);
else
minIndex.push_back(minIndex.back());
}
}
template<typename T>
void MyStack<T>::pop()
{
if (!empty())
{
myData.pop_back();
minIndex.pop_back();
}
else
{
cout << "栈已经为空:" << endl;
}
}
template <typename T>
bool MyStack<T>::empty()const
{
return myData.empty();
}
template<typename T>
const T &MyStack<T>::top() const
{
return myData.back();
}
template<typename T>
const T &MyStack<T>::min()const
{
return myData[minIndex.back()];
}
4.测试函数,通过在原文件中建立main()函数对我们刚刚建立的模板进行测试验证
//作者:云梦泽
//日期:2013.11.10
//地点:软件大楼
#include <iostream>
#include "stacKDesign.h"
using namespace std;
int main(void)
{
MyStack<int> mystack;
mystack.push(3);
GetInfor(mystack);
mystack.push(4);
GetInfor(mystack);
mystack.push(2);
GetInfor(mystack);
mystack.push(1);
GetInfor(mystack);
mystack.pop();
GetInfor(mystack);
mystack.pop();
GetInfor(mystack);
mystack.push(0);
GetInfor(mystack);
mystack.pop();
GetInfor(mystack);
mystatc.pop();
GetInfor(mystack);
mystack.pop();
GetInfor(mystack);
mystack.pop();
GetInfor(mystack);
return 0;
}