`
xitonga
  • 浏览: 589446 次
文章分类
社区版块
存档分类
最新评论

Stack_Queue 一个数组实现三个栈 @CareerCup

 
阅读更多

原文:

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;
		}
	}
}





分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics