程序员面试金典: 9.3栈与队列 3.1描述如何只用一个数组来实现三个栈

#include <iostream>
#include <stdio.h>
#include <string>
#include <stack>

using namespace std;

/*
问题:描述如何只用一个数组实现三个栈
分析:栈是后进先出,先把问题简化为如何用一个数组实现一个栈
      数组每次插入时插入在最后,取出时取出最后一个元素即可
	  暂未想到。难道对数组三等分,每个生成一个栈?
书上解法:
1 将栈三等分,维持一个数组,数组中每个元素用于记录栈顶的下标,
  根据用户传入的栈号,获取该栈对应于数组中的实际元素
2 当push时,就令选择的栈对应的栈顶下标累加,并设置数组中对应该元素的值(压入时判满)
  当pop时,先获取栈顶元素,令栈顶下标累减,并对数组中该元素的值清零(弹出时判空)

输入:
3(需要赋值的栈的个数)
0(某个栈的下标) 3(栈中存放的元素)
1 2 3
1 2
4 5
2 1
6
3(指令个数)
0(栈号)pop(指令弹出) 2(弹出次数)
1 (栈号) push(指令压入) 5(压入元素)
2 (栈号) pop(指令弹出) 2(弹出次数)
输出:输出从0号栈到2号栈的元素
1
4 5 5
栈空

关键:
1 将栈三等分,维持一个数组,数组中每个元素用于记录栈顶的下标,
  根据用户传入的栈号,获取该栈对应于数组中的实际元素
2 当push时,就令选择的栈对应的栈顶下标累加,并设置数组中对应该元素的值(压入时判满)
  当pop时,先获取栈顶元素,令栈顶下标累减,并对数组中该元素的值清零(弹出时判空)
3 		//栈非空,则令栈顶下标累加,并设置栈顶元素
		stackPointer[stackIndex]++;
		int pos = getPosition(stackIndex);
		buffer[pos] = value;
*/



class ThreeStack
{
public:
	ThreeStack()
	{
		stackNum = 3;
		//初始化每个栈栈顶下标为-1;
		for(int i = 0 ; i < stackNum ; i++)
		{
			stackPointer[i] = -1;
		}
	}
	//压入栈中,需要提供栈号,先判断加入一个元素是否超过栈的长度
	void push(int stackIndex, int value)
	{
		if( stackPointer[stackIndex] + 1 >= STACK_SIZE )
		{
			//cout << "stack:" << stackIndex << " is full!" << endl;
			return;
		}
		//栈非空,则令栈顶下标累加,并设置栈顶元素
		stackPointer[stackIndex]++;
		int pos = getPosition(stackIndex);
		buffer[pos] = value;
	}

	//从栈中弹出,先判断栈非空,再令元素为0,累减栈顶下标
	void pop(int stackIndex)
	{
		if( isEmpty(stackIndex) )
		{
			//cout << "stack:" << stackIndex << " is empty!" << endl;
			return;
		}
		int pos = getPosition(stackIndex);
		buffer[pos] = 0;
		stackPointer[stackIndex]--;
	}

	//获取栈顶元素
	int top(int stackIndex)
	{
		if( isEmpty(stackIndex) )
		{
			//cout << "stack:" << stackIndex << " is empty!" << endl;
			return -1;
		}
		int pos = getPosition(stackIndex);
		return buffer[pos];
	}

	bool isEmpty(int stackIndex)
	{
		return stackPointer[stackIndex] == -1;
	}

	//获取栈的实际位置=栈的大小*栈的下标 + 该栈对应的栈顶下标
	int getPosition(int stackIndex)
	{
		int position = stackIndex * STACK_SIZE + stackPointer[stackIndex];
		return position;
	}

	//打印某栈中所有元素,从栈最里面一直到最外面顺序(先递归,后打印), 最好拷贝一份
	void print(int stackIndex)
	{
		if(isEmpty(stackIndex))
		{
			return;
		}
		stack<int> stackData;
		while(!isEmpty(stackIndex))
		{
			stackData.push( top(stackIndex) ) ;
			pop(stackIndex);
		}
		while(!stackData.empty())
		{
			cout << stackData.top() << " ";
			stackData.pop();
		}
		cout << endl;
	}
private:
	const static int STACK_SIZE = 1000;
	int buffer[3 * STACK_SIZE]; //用于栈的数组
	int stackPointer[3];        //记录栈顶位置的数组
	int stackNum;               //栈的个数
};

int main(int argc, char* argv[])
{
	int stackNum;
	while(cin >> stackNum)
	{
		//初始化栈
		ThreeStack threeStack;
		for(int i = 0 ; i < stackNum ; i++)
		{
			int stackIndex;
			int num;
			cin >> stackIndex >> num;
			for(int j = 0; j < num ; j++)
			{
				int value;
				cin >> value;
				threeStack.push(stackIndex , value);
			}
		}

		//接受指令操作
		int commandNum;
		cin >> commandNum;
		for(int k = 0 ; k < commandNum ; k++)
		{
			int stackIndex;
			string command;
			int value;
			cin >> stackIndex >> command >> value;
			//如果是压入,则压入到指定栈号
			if(command == "push")
			{
				threeStack.push(stackIndex , value);
			}
			else if(command == "pop")
			{
				for(int p = 0 ; p < value ; p++)
				{
					threeStack.pop(stackIndex);
				}
			}
		}

		//输出栈中元素,如果栈空,就输出空栈
		for(int i = 0 ; i < 3; i++)
		{
			if(threeStack.isEmpty(i))
			{
				cout << "栈空" << endl;
			}
			else
			{
				threeStack.print(i);
			}
		}
	}
	getchar();
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值