题目

原文:

Describe how you could use a single array to implement three stacks.

译文:

你如何只用一个数组实现三个栈?

解答

我们可以很容易地用一个数组来实现一个栈,压栈就往数组里插入值,栈顶指针加1; 出栈就直接将栈顶指针减1;取栈顶值就把栈顶指针指向的单元的值返回; 判断是否为空就直接看栈顶指针是否为-1。

如果要在一个数组里实现3个栈,可以将该数组分为3个部分。如果我们并不知道哪个栈将装 入更多的数据,就直接将这个数组平均分为3个部分,每个部分维护一个栈顶指针, 根据具体是对哪个栈进行操作,用栈顶指针去加上相应的偏移量即可。

代码如下:

class stack3{
public:
stack3(int size = ){
buf = new int[size*];
ptop[]=ptop[]=ptop[]=-;
this->size = size;
}
~stack3(){
delete[] buf;
}
void push(int stackNum, int val){
int idx = stackNum*size + ptop[stackNum] + ;
buf[idx] = val;
++ptop[stackNum];
}
void pop(int stackNum){
--ptop[stackNum];
}
int top(int stackNum){
int idx = stackNum*size + ptop[stackNum];
return buf[idx];
}
bool empty(int stackNum){
return ptop[stackNum]==-;
} private:
int *buf;
int ptop[];
int size;
};

当然,我们也可以有第二种方案。数组不分段,无论是哪个栈入栈,都依次地往这个数组里 存放。这样一来,我们除了维护每个栈的栈顶指针外,我们还需要维护每个栈中, 每个元素指向前一个元素的指针。这样一来,某个栈栈顶元素出栈后,它就能正确地找到下 一个栈顶元素。

所以,数组里存放的不再是基本数据类型的数据,我们需要先定义一个结点结构:

typedef struct node{
int val,preIdx;
}node;

数组中的每个元素将是这样一个结点,它保存当前位置的值,和指向上一个结点的索引。

具体代码如下:

class stack3_1{
public:
stack3_1(int totalSize = ){
buf = new node[totalSize];
ptop[]=ptop[]=ptop[]=-;
this->totalSize = totalSize;
cur = ;
}
~stack3_1(){
delete[] buf;
}
void push(int stackNum, int val){
buf[cur].val = val;
buf[cur].preIdx = ptop[stackNum];
ptop[stackNum] = cur;
++cur;
}
void pop(int stackNum){
ptop[stackNum] = buf[ptop[stackNum]].preIdx;
}
int top(int stackNum){
return buf[ptop[stackNum]].val;
}
bool empty(int stackNum){
return ptop[stackNum]==-;
} private:
node *buf;
int ptop[];
int totalSize;
int cur;
};

这种实现有一个缺点,在频繁地入栈出栈后,会造成数组空间的大量浪费。 因为当前指针cur是一直递增的,而堆栈在出栈后相应位置的空间将不会再被利用到。 代码中pop函数,只是修改了栈顶指针。如果我们对一个栈先执行出栈,再入栈, 那么再次入栈的位置是在cur,而不是原来栈顶的位置。

有没有避免这种空间浪费的方法呢?当然是有的。不过这样一来,对cur的操作就变得复杂 了。第一,每次执行pop操作,检查该元素对应索引是否小于cur,如果是, 将cur更新到该元素索引;否则cur不变。第二,每次执行完push操作, cur要沿着数组依次向后查找,直到找到第一个空的空间,用它的索引更新cur。 这部分代码实现起来也是没什么难度的,这里不再贴出。

以下是完整代码:

#include <iostream>
using namespace std; class stack3{
public:
stack3(int size = ){
buf = new int[size*];
ptop[]=ptop[]=ptop[]=-;
this->size = size;
}
~stack3(){
delete[] buf;
}
void push(int stackNum, int val){
int idx = stackNum*size + ptop[stackNum] + ;
buf[idx] = val;
++ptop[stackNum];
}
void pop(int stackNum){
--ptop[stackNum];
}
int top(int stackNum){
int idx = stackNum*size + ptop[stackNum];
return buf[idx];
}
bool empty(int stackNum){
return ptop[stackNum]==-;
} private:
int *buf;
int ptop[];
int size;
}; typedef struct node{
int val,preIdx;
}node; class stack3_1{
public:
stack3_1(int totalSize = ){
buf = new node[totalSize];
ptop[]=ptop[]=ptop[]=-;
this->totalSize = totalSize;
cur = ;
}
~stack3_1(){
delete[] buf;
}
void push(int stackNum, int val){
buf[cur].val = val;
buf[cur].preIdx = ptop[stackNum];
ptop[stackNum] = cur;
++cur;
}
void pop(int stackNum){
ptop[stackNum] = buf[ptop[stackNum]].preIdx;
}
int top(int stackNum){
return buf[ptop[stackNum]].val;
}
bool empty(int stackNum){
return ptop[stackNum]==-;
} private:
node *buf;
int ptop[];
int totalSize;
int cur;
}; int main(){
stack3_1 mystack;//stack3 mystack;
for(int i=; i<; ++i)
mystack.push(, i);
for(int i=; i<; ++i)
mystack.push(, i);
for(int i=; i<; ++i)
mystack.push(, i);
for(int i=; i<; ++i)
cout<<mystack.top(i)<<" "; cout<<endl;
for(int i=; i<; ++i){
mystack.pop(i);
cout<<mystack.top(i)<<" ";
}
mystack.push(, );
mystack.push(, );
mystack.push(, );
for(int i=; i<; ++i)
cout<<mystack.top(i)<<" ";
return ;
}

Cracking the coding interview--Q3.1的更多相关文章

  1. Cracking the coding interview

    写在开头 最近忙于论文的开题等工作,还有阿里的实习笔试,被虐的还行,说还行是因为自己的水平或者说是自己准备的还没有达到他们所需要人才的水平,所以就想找一本面试的书<Cracking the co ...

  2. Cracking the coding interview 第一章问题及解答

    Cracking the coding interview 第一章问题及解答 不管是不是要挪地方,面试题具有很好的联系代码总用,参加新工作的半年里,做的大多是探索性的工作,反而代码写得少了,不高兴,最 ...

  3. Cracking the Coding Interview(Trees and Graphs)

    Cracking the Coding Interview(Trees and Graphs) 树和图的训练平时相对很少,还是要加强训练一些树和图的基础算法.自己对树节点的设计应该不是很合理,多多少少 ...

  4. Cracking the Coding Interview(Stacks and Queues)

    Cracking the Coding Interview(Stacks and Queues) 1.Describe how you could use a single array to impl ...

  5. 《Cracking the Coding Interview》读书笔记

    <Cracking the Coding Interview>是适合硅谷技术面试的一本面试指南,因为题目分类清晰,风格比较靠谱,所以广受推崇. 以下是我的读书笔记,基本都是每章的课后习题解 ...

  6. Cracking the coding interview目录及资料收集

    前言 <Cracking the coding interview>是一本被许多人极力推荐的程序员面试书籍, 详情可见:http://www.careercup.com/book. 第六版 ...

  7. 《Cracking the Coding Interview》——第13章:C和C++——题目6

    2014-04-25 20:07 题目:为什么基类的析构函数必须声明为虚函数? 解法:不是必须,而是应该,这是种规范.对于基类中执行的一些动态资源分配,如果基类的析构函数不是虚函数,那么 派生类的析构 ...

  8. 《Cracking the Coding Interview》——第5章:位操作——题目7

    2014-03-19 06:27 题目:有一个数组里包含了0~n中除了某个整数m之外的所有整数,你要设法找出这个m.限制条件为每次你只能用O(1)的时间访问第i个元素的第j位二进制位. 解法:0~n的 ...

  9. Cracking the Coding Interview 10.7

    Design an algorithm to find the kth number such that the only prime factors are 3,5 and 7 方法一: a[i]= ...

  10. 二刷Cracking the Coding Interview(CC150第五版)

    第18章---高度难题 1,-------另类加法.实现加法. 另类加法 参与人数:327时间限制:3秒空间限制:32768K 算法知识视频讲解 题目描述 请编写一个函数,将两个数字相加.不得使用+或 ...

随机推荐

  1. MySQL 获取子分类ID的所有父分类ID和Name的集合

    CREATE DEFINER=`sa`@`%` PROCEDURE `proc_Product_leimu_ParentIds`( IN pID INT ) BEGIN ) vars, product ...

  2. if you are not making someone else's life better, then you are wasting your time.– Will Smith如果你不能给别人的生活带来改善,那么你就是在浪费你的宝贵时间。 --威尔 史密斯(程序员,你做的东西...)

    if you are not making someone else's life better, then you are wasting your time. – Will Smith 如果你不能 ...

  3. C语言笔记本

    在此记录一些常见的C语言错误,可以当作学习C语言的笔记,需要的时候可以回过头看看. 1.关于“++” #include int main() { int a,b,cd; a=10; b=a++; c= ...

  4. php_memcache 缓存 下载-安装-配置-学习

    一.安装php_memcache.dll 打开phpinfo() 查看PHP Extension Build,如TS,VC11 查看Architecture,如X86.X64 查看PHP版本,如5.6 ...

  5. 在 ASP.NET Web API 中,使用 命名空间(namespace) 来作为路由的参数

    这个问题来源于我想在 Web API 中使用相同的控制器名称(Controller)在不同的命名空间下,但是 Web API 的默认 路由(Route) 机制是会忽略命名空间的不同的,如果这样做,会看 ...

  6. HDU 2444 The Accomodation of Students二分图判定和匈牙利算法

    本题就是先推断能否够组成二分图,然后用匈牙利算法求出最大匹配. 究竟怎样学习一种新算法呢? 我也不知道什么方法是最佳的了,由于看书本和大牛们写的匈牙利算法具体分析,看了几乎相同两个小时没看懂,最后自己 ...

  7. git将远程仓库最新版本拉到本地仓库

    一.正规做法有两种.git fetch和git pull. 注意不管用fetch还是pull,做之前都要在本地仓库做一次git commit,确保,本地仓库和工作目录及缓存一致.1.git fetch ...

  8. modelsim 保存波形文件

    1. do文件记录了仿真的过程和加载的各种库. do文件的保存过程: file——>save format——>D:/modeltech_6.5b/examples/run_wave.do ...

  9. 递归查询SQL语句

    USE [DB] GO /****** Object: View [dbo].[v_menus] Script Date: 02/24/2014 15:55:45 ******/ SET ANSI_N ...

  10. fis速查(不断更新)

    模块化开发-pure: http://hefangshi.github.io/fis-site/docs/advance/modjs-solution.html 三种语言能力(资源定位,内容嵌入,依赖 ...