题目

原文:

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. Linux命令-防火墙命令:iptables

    iptables详解--转 查看防火墙设置: 第一种方式: cat /etc/sysconfig/iptables 第二种方式: iptables -L -n -v 设置防火墙: 第一种方式: ipt ...

  2. 基于HTTP在互联网传输敏感数据的消息摘要、签名与加密方案

    基于HTTP在互联网传输敏感数据的消息摘要.签名与加密方案 博客分类: 信息安全 Java 签名加密AESMD5HTTPS  一.关键词 HTTP,HTTPS,AES,SHA-1,MD5,消息摘要,数 ...

  3. DBA_实践指南系列7_Oracle Erp R12监控OAM(案例)

    2013-12-07 Created By BaoXinjian

  4. 关于Andorid的RecyclerView在V7包下找不到的解决办法

      关于Andorid的RecyclerView在V7包下找不到的解决办法 最近在学习使用RecyclerView替换现有的ListView,看了几篇文章.当准备自己动手实现的时候发现,V7包下找不到 ...

  5. 关于c语言内存分配,malloc,free,和段错误,内存泄露

    1.   C语言的函数malloc和free (1) 函数malloc和free在头文件<stdlib.h>中的原型及参数        void * malloc(size_t size ...

  6. mysql 表锁——读锁和写锁

    注意, 0.表的索引类型必须是InnoDB.相关链接:http://www.cnblogs.com/CyLee/p/5579672.html 1.如果你使用Navicat Premium,有可能会出现 ...

  7. win7上安装theano keras深度学习框架

    近期在学习深度学习,需要在本机上安装keras框架,好上手.上网查了一些资料,弄了几天今天终于完全搞好了.本次是使用GPU进行加速,使用cpu处理的请查看之前的随笔keras在win7下环境搭建 本机 ...

  8. Spring Cloud构建微服务架构(四)分布式配置中心

    Spring Cloud Config为服务端和客户端提供了分布式系统的外部化配置支持.配置服务器为各应用的所有环境提供了一个中心化的外部配置.它实现了对服务端和客户端对Spring Environm ...

  9. 微信公众号支付安卓和WP支付成功,苹果不能支付!

    花了几天时间,终于搞好了,代码是从官网上下的.NET DEMO的代码改的,测试的时候发现安卓和WP手机都能进行支付,但是苹果的怎么支付都支付不了,主要是在下面这个界面 点支付按钮就是苹果支付不了,其他 ...

  10. 教你如何写thinkphp多表查询语句

    1.table()函数 thinkphp中提供了一个table()函数,具体用法参考以下语句: $list=$Demo->table('think_blog blog,think_type ty ...