Google面试题之栈的设计

作者:云梦泽

日期:2013.11.17

地点:湖南大学软件大楼211

一、题目

题目:定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。要求函数minpush以及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;
}



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值