您的位置:首页 > 其它

Cracking the coding interview--Q3.1

2014-10-31 11:44 267 查看
原文:

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

译文:

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

如果实现使用一个数组表示一个栈就简单很多,一个指针指向当前栈顶元素位置,初始top=-1,表示栈为空

如果入栈则top++,并元素入栈即可,出栈也只需要top--,top指向栈顶元素。

方法一:

如果用一个数组代表三个栈的操作,假设前天不知道每个栈所需要的空间大小,则可以使用数组等分,每个栈使用

三分之一空间,各个栈都有自己的栈顶指针来操作自己的空间。

package chapter_3_StacksandQueues;

class Stack_1 {
private int stack[];
private int size;

// 分别记录三个栈顶指针位置,栈顶指针指向当前栈最高元素
private int top[] = new int[3];
private int bottom[] = new int[3];

public Stack_1(int size) {
stack = new int[size * 3];
this.size = size;
top[0] = bottom[0] = -1;
top[1] = bottom[1] = size * 1 -1;
top[2] = bottom[2] = size * 2 -1;
}

public boolean isEmpty(int stackNum) {
return top[stackNum] == (stackNum * size -1);
}

public boolean isFull(int stackNum) {
return top[stackNum] == ((stackNum+1) *size - 1);
}

public void push(int stackNum, int value) {
if(isFull(stackNum)) {
System.out.println("Stack num :" + stackNum + " is full!");
return;
}
stack[++ top[stackNum]] = value;
}

public int top(int stackNum) {
if(isEmpty(stackNum)) {
System.out.println("Stack num :" + stackNum + " is empty!");
return -1;
}
return stack[top[stackNum]];
}

public void pop(int stackNum) {
if(isEmpty(stackNum)) {
System.out.println("Stack num :" + stackNum + " is empty!");
return;
}

top[stackNum]--;
}
// 清空并输出
public String getSatckandClear(int stackNum) {
StringBuilder result = new StringBuilder();
// 当前不空
while(!isEmpty(stackNum)) {
result.append(" " + top(stackNum));
pop(stackNum);
}
return result.toString();
}
}

/**
*
* 你如何只用一个数组实现三个栈?
*
*/
public class Question_3_1 {
public static void main(String args[]) {
Stack_1 stack = new Stack_1(5);
int stackNum = 0;
System.out.println("stackNum " + stackNum + " is Empty :" + stack.isEmpty(stackNum));

for(int i=0; i<3; i++) {
for(int j=i*10, k=1; k<=10; k++,j++) {
stack.push(i, j);
}
}

for(int i=0; i<3; i++) {
String result = stack.getSatckandClear(i);
System.out.format("stack %d : %s\n", i, result);
}
}
}


方法二:

如果考虑三个栈直接使用同一个数组,这个可以灵活各个栈空间大小,不约束于三分之一。这样连续使用则每个栈都有自己的栈顶指针

但是同时由于站内数据混在一起,则需要每个栈当前栈顶元素,如果出栈,则需要找到其前一个元素,此时需要记录每个元素的前继元

素在数组中的下标,所以数组元素就不能单纯使用基本类型了,可以使用c++的结构体,java中则使用类

class Node {
public int data;
public int pre;
}

此时对于操作流程中则需要注意每个栈的出栈和入栈,如果只是单纯各管自己的,每次出栈去数组最高位,则考虑如果栈1一直出栈,最终为空

而此时栈2入栈则单纯只考虑数组最高位则浪费了栈1出栈的位置空间,所以每次都需要有一个全部栈空间指针stack_top,随时指针当前最低位空闲位置

每次有元素需要出栈的时候,元素出栈,如果元素位置比全部stack_top要低位,则更新stack_top为当前出栈位置,如果要高则无需变动,这样实时保证

下次入栈时候能利用最低位空闲位置。

每次有元素需要入栈,则stack_top记录最低位入栈,但是stack_top的下一个高位比一定是空闲位置,所以需要往高位扫描直到找到下一个空闲位置,此时

也是整个数组最低位空闲位置。

package chapter_3_StacksandQueues;

class Node {
public int data;
public int pre;
}

class Stack_1_2 {
private Node[] stack;
// 整个栈的大小
private int size;
private int top[] = new int[3];
// 记录当前全局栈顶可存放位置
private int stack_top;

public Stack_1_2(int size) {
stack = new Node[size];
this.size = size;
top[0] = top[1] = top[2] = -1;
stack_top = 0;

for(int i=0; i<size; i++) {
stack[i] = new Node();
stack[i].pre = -2;
}
}

public boolean isEmpty(int stackNum) {
return top[stackNum] == -1;
}

public boolean isFull() {
return stack_top == (size -1);
}
// 入栈
public void push(int stackNum, int data) {
if(isFull()) {
System.out.println("Stack :" + " is full!");
return;
}
int pre = top[stackNum];
stack[stack_top].pre = pre;
stack[stack_top].data = data;
top[stackNum]
c870
= stack_top;
// 寻找下一个空闲栈位置
for(int i=stack_top;i<size; i++) {
if(stack[i].pre == -2) {
stack_top = i;
break;
}
}
// 如果没有空闲栈位置,则指向栈顶下一个位置
}

public int top(int stackNum) {
if(isEmpty(stackNum)) {
System.out.println("Stack num :" + stackNum + " is empty!");
return -1;
}
return stack[top[stackNum]].data;
}
// 出栈
public void pop(int stackNum) {
if(isEmpty(stackNum)) {
System.out.println("Stack num :" + stackNum + " is empty!");
return;
}
int now = top[stackNum];
Node node = stack[now];
if(now < stack_top) {
stack_top = now;
}

int pre = node.pre;
top[stackNum] = pre;
node.pre = -2; // 标记为空闲位置
}

public String getSatckData(int stackNum) {
StringBuilder result = new StringBuilder();

int cur = top[stackNum];
while(cur != -1) {
result.append(" " + stack[cur].data);
cur = stack[cur].pre;
}
return result.toString();
}
}
/**
*
* 你如何只用一个数组实现三个栈?
*
*/
public class Question_3_1_2 {
public static void main(String args[]) {
Stack_1_2 stack = new Stack_1_2(20);
int stackNum = 0;
System.out.println("stackNum " + stackNum + " is Empty :" + stack.isEmpty(stackNum));

int stackStart[] = {0, 100, 1000};

// 3 * 3
for(int i=0; i<3; i++) {
for(int k=1; k<=3; k++) {
stack.push(i, stackStart[i] ++);
}
}
// 3 * 3
for(int i=2; i>=0; i--) {
for(int k=1; k<=3; k++) {
stack.push(i, stackStart[i] ++);
}
}
// 3 * 1
for(int i=0; i<3; i++) {
for(int k=1; k<=1; k++) {
stack.push(i, stackStart[i] ++);
}
}
// 输出各个栈的内容
for(int i=0; i<3; i++) {
String result = stack.getSatckData(i);
System.out.format("stack %d : %s\n", i, result);
}

// 栈1出栈5个元素
for(int i=0; i<5;i++) {
System.out.format("stack 0 出栈 top pop : %d\n", i, stack.top(0));
stack.pop(0);
}

// 栈2、3入栈元素
for(int i=1; i<3; i++) {
for(int k=1; k<=3; k++) {
stack.push(i, stackStart[i] ++);
}
}

// 输出各个栈的内容
for(int i=0; i<3; i++) {
String result = stack.getSatckData(i);
System.out.format("stack %d : %s\n", i, result);
}
}
}


参考自:http://hawstein.com/posts/3.1.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法