原文:
Describe how you could use a single array to implement three stacks.
译文:
你如何只用一个数组实现三个栈?
分两种情况:1)固定的栈,即栈和栈之间无法共享空间,每个栈都只有固定的空间。用n个栈顶指针来记录栈顶位置即可。
2)非固定的栈:有必要构造一个StackData的类来存放关于某个栈的信息,包括栈的开始位置,指向当前栈顶元素的位置,实际装有元素个数,可装元素的容量
还要一个关键的shift函数,用于把某个栈整体往后挪一位,以便为前一个栈腾出空间。
package Stack_Queue;
public class S3_1_Fixed {
// ================ Version 1 Fixed Division Stack
static int stackSize = 100;
static int[] buffer = new int[stackSize * 3];
static int[] stackPointer = {-1, -1, -1}; // 存放用于记录栈顶元素的index
// 把value压入第stackNum个栈
public static void push(int stackNum, int value) throws Exception{
if(stackPointer[stackNum] + 1 >= stackSize) {
throw new Exception("Out of space.");
}
stackPointer[stackNum]++;
buffer[absTopOfStack(stackNum)] = value;
}
// 取出第stackNum个栈的栈顶元素
public static int pop(int stackNum) throws Exception {
if(stackPointer[stackNum] == -1) {
throw new Exception("Trying to pop an empty stack");
}
int value = buffer[absTopOfStack(stackNum)];
buffer[absTopOfStack(stackNum)] = 0; // 栈顶元素置零
stackPointer[stackNum]--; // 把栈顶元素index减一
return value;
}
// 查看第stackNum个栈的栈顶元素
public static int peek(int stackNum) throws Exception {
int index = absTopOfStack(stackNum);
if(stackPointer[stackNum] == -1) {
throw new Exception("Trying to peek an empty stack");
}
return buffer[index];
}
// 判断第stackNum个栈是否为空
public static boolean isEmpty(int stackNum) {
return stackPointer[stackNum] == -1;
}
// 返回第stackNum个栈的栈顶元素的index
public static int absTopOfStack(int stackNum) {
return stackNum * stackSize + stackPointer[stackNum];
}
public static void main(String [] args) throws Exception {
push(2, 4);
System.out.println("Peek 2: " + peek(2));
push(0, 3);
push(0, 7);
push(0, 5);
System.out.println("Peek 0: " + peek(0));
pop(0);
System.out.println("Peek 0: " + peek(0));
pop(0);
System.out.println("Peek 0: " + peek(0));
}
}
package Stack_Queue;
import CtCILibrary.AssortedMethods;
public class S3_1_Flexible {
//================ Version 2 Flexible Division Stack
static int number_of_stacks = 3;
static int default_size = 4;
static int total_size = default_size * number_of_stacks;
static StackData[] stacks = { new StackData(0, default_size),
new StackData(default_size, default_size),
new StackData(default_size * 2, default_size) };
static int[] buffer = new int[total_size];
public static void main(String[] args) throws Exception {
push(0, 10);
push(1, 20);
push(2, 30);
push(1, 21);
push(0, 11);
push(0, 12);
pop(0);
push(2, 31);
push(0, 13);
push(1, 22);
push(2, 31);
push(2, 32);
push(2, 33);
push(2, 34);
System.out.println("Final Stack: " + AssortedMethods.arrayToString(buffer));
pop(1);
push(2, 35);
System.out.println("Final Stack: " + AssortedMethods.arrayToString(buffer));
}
// 3个栈总共的element数量
public static int numberOfElements() {
return stacks[0].size + stacks[1].size + stacks[2].size;
}
// 得到index的下一个位置,关键是处理wrap
public static int nextElement(int index) {
if (index + 1 == total_size) { // wrap
return 0;
} else {
return index + 1;
}
}
// 得到index的前一个位置,关键是处理wrap
public static int previousElement(int index) {
if (index == 0) { // wrap
return total_size - 1;
} else {
return index - 1;
}
}
// 把第stackNum栈的所有元素往后移1位
public static void shift(int stackNum) {
StackData stack = stacks[stackNum];
if (stack.size >= stack.capacity) {
int nextStack = (stackNum + 1) % number_of_stacks;
shift(nextStack); // make some room
stack.capacity++;
}
// end of array
for (int i = (stack.start + stack.capacity - 1) % total_size; stack.isWithinStack(i, total_size); i = previousElement(i)) {
buffer[i] = buffer[previousElement(i)];
}
buffer[stack.start] = 0;
stack.start = nextElement(stack.start); // move start start
stack.pointer = nextElement(stack.pointer); // move stack pointer
stack.capacity--; // return capacity to original
}
/* Expand stack by shifting over other stacks */
public static void expand(int stackNum) {
shift((stackNum + 1) % number_of_stacks); // 把第stackNum + 1栈的所有元素往后移1位,使得第stackNum栈多一个元素的空间
stacks[stackNum].capacity++;
}
// 在第stackNum栈内压入value
static void push(int stackNum, int value) throws Exception {
StackData stack = stacks[stackNum];
/* Check that we have space */
if (stack.size >= stack.capacity) {
if (numberOfElements() >= total_size) { // Totally full
throw new Exception("Out of space.");
} else { // just need to shift things around
expand(stackNum);
}
}
/*
* Find the index of the top element in the array + 1, and increment the
* stack pointer
*/
stack.size++;
stack.pointer = nextElement(stack.pointer);
buffer[stack.pointer] = value;
}
// 从第stackNum栈内弹出栈顶元素
static int pop(int stackNum) throws Exception {
StackData stack = stacks[stackNum];
if (stack.size == 0) {
throw new Exception("Trying to pop an empty stack.");
}
int value = buffer[stack.pointer];
buffer[stack.pointer] = 0;
stack.pointer = previousElement(stack.pointer);
stack.size--;
return value;
}
// 访问第stackNum个栈的栈顶元素
static int peek(int stackNum) {
StackData stack = stacks[stackNum];
return buffer[stack.pointer];
}
// 判断第stackNum个栈是否为空
static boolean isEmpty(int stackNum) {
StackData stack = stacks[stackNum];
return stack.size == 0;
}
static class StackData {
public int start; // 开始位置
public int pointer; // 指向当前栈顶元素
public int size = 0; // 实际装有元素个数
public int capacity; // 可装元素容量
public StackData(int _start, int _capacity) {
start = _start;
pointer = _start - 1;
capacity = _capacity;
}
public boolean isWithinStack(int index, int total_size) {
// Note: if stack wraps, the head (right side) wraps around to the left.
if (start <= index && index < start + capacity) {
// non-wrapping, or "head" (right side) of wrapping case
return true;
} else if (start + capacity > total_size && index < (start + capacity) % total_size) {
// tail (left side) of wrapping case
return true;
}
return false;
}
}
}
分享到:
相关推荐
Stack_Queue_Stack_源码
c++stack_和_queue用法,很好的介绍了STL中stack和queue的用法,及其使用方法
前端大厂最新面试题-stack_queue
Data structure: Stack->Queue Example
本源码实现了两个类,一个是带有最大值的栈和一个是带有最大值的队列。栈利用了两个C++的stack,队列利用了C++的queue。
实现栈,队列,链表的简单操作,其中链表包括单链表,双链表,循环链表。
定义一个数组,int型的top表示栈顶(表示当前可以插入元素的位置),usesize表示使用的栈的大小 栈的push和pop要注意top的移动,usesize的增加减小 3、栈的练习题之括号匹配 可以在leetcode上找到 明确,括号的几种...
Java_Stack_Queue Java中使用链表的堆栈和队列实现
常用的C++数据结构算法,包括队列、堆栈、链表...等.以模板类型式实现
NXP 的 LIN 协议栈,之前一直用的 4.5.7 的版本,使用过程中有好几个问题都是手动修复的。最近在官网上看见了 4.6.6 的版本,下载测试了一遍,发现之前手动修复的几个问题都已经 OK 了。
一个完整的LIN代码程序,使用NXP提供的驱动开发
Pro_MERN_Stack_Full_Stack_Web_App_Development_with_Mongo,_Express,_React,_and_Node
Lists_Stack_Queue_PriorityQueue.java
TI公司提供2015年11月最新基于ZigBee无线智能家居开发协议(Z_Stack_Home_1.2.2a.exe) 由于只能上传小于60MB文件,将150MB原文件分割3个部分上传,分别为: Z_Stack_Home_1.2.2a.exe.part1.rar Z_Stack_Home_1.2.2a....
用数组实现对栈的操作,如入栈,退栈,清空,输出等
stack_queue_p2pchat_practice:只是使用Stack和Queue技术的Java实践聊天应用程序
tcpip_stack_v1_2_TCP,IP_TCP_IP_udpmac_UDP_tcp.zip
用数组设计堆栈,主要实现push,pop操作, 并判断是否上衣下一
飞思卡尔官方最新LIN栈源码,可用于LIN应用开发参考和LIN的学习