用一个数组实现三个stack
此题来自于Crack the Coding Interview,3.1题。
要求:
用1个数组实现3个stack,使得在数组没有满的情况之下,一直可以继续插入数,而且这3个stack的push和pop操作应该和普通stack用起来没有区别。
此题的思路是,在这个数组中的每一个元素中加入一个指针域,在code中,这就是pPre,就是指向更先入栈的元素。这样,整个数组除了靠数组本身的index组织起来,在已经用过的元素中,还有3条链。
此外,对于pop操作,如果该pop操作不是在数组有效元素的最末一个元素进行(这是可能的,例如stack 1占用位置124,stack 2占用位置356,那么stack 1进行pop操作则pop的是4,那么将出现“空”,对于这些“空”,用一个freeList串接起来记录free的cell。在程序一开始的时候,因为数组中所有的空间都是free的,所以freeList包含了整个数组。
#include <iostream> using namespace std; struct Item{ int value; //Real num Item *pPre; //pre num in the stack }; struct FreeListItem{ int freeIndex; //free index FreeListItem *pNext; //next free index's item pointer FreeListItem(int fI, FreeListItem *p) { freeIndex = fI; pNext = p; } }; class ThreeStacks{ public: ThreeStacks(int capacityOfEach); void push(int stackNum, int value); int pop(int stackNum); int top(int stackNum); private: int stackTop[3]; int m_capacity; Item *arr; // 用来实际存放数据 FreeListItem *freeList; // 用来存放free的cell的index }; ThreeStacks::ThreeStacks(int capacity) { stackTop[0] = -1; stackTop[1] = -1; stackTop[2] = -1; m_capacity = capacity; arr = new Item[m_capacity]; memset(arr, 0, sizeof(Item) * m_capacity); FreeListItem *pRight = new FreeListItem(m_capacity - 1, NULL); for (int i = m_capacity - 2; i >= 0; i--) { FreeListItem *pLeft = new FreeListItem(i, pRight); pRight = pLeft; } freeList = pRight; } void ThreeStacks::push(int stackNum, int value) { int currStackTop = 0; if (stackNum <= 2 && stackNum >= 0) currStackTop = stackTop[stackNum]; else { cout<<"Err input!"<<endl; return; } if (!freeList) { cout<<"Stack is Full!"<<endl; return; } int firstFreeIndex = freeList->freeIndex; arr[firstFreeIndex].value = value; arr[firstFreeIndex].pPre = &arr[currStackTop]; stackTop[stackNum] = firstFreeIndex; FreeListItem *pTmp = freeList; freeList = freeList->pNext; delete pTmp; pTmp = NULL; } int ThreeStacks::top(int stackNum) { int currStackTop = 0; if (stackNum <= 2 && stackNum >= 0) currStackTop = stackTop[stackNum]; else { cout<<"Err input!"<<endl; return; } return arr[currStackTop].value; } int ThreeStacks::pop(int stackNum) { int currStackTop = 0; if (stackNum <= 2 && stackNum >= 0) currStackTop = stackTop[stackNum]; else{ cout<<"Err Input!"<<endl; return -1; } if (currStackTop == -1) { cout<<"No Items in Stack!"<<endl; return -1; } int returnValue = arr[currStackTop].value; stackTop[stackNum] = (arr[currStackTop].pPre - arr); arr[currStackTop].pPre = NULL; arr[currStackTop].value = 0; FreeListItem *freeListItem = new FreeListItem(currStackTop, freeList); freeList = freeListItem; return returnValue; } int main() { ThreeStacks threeStacks(10000); for (int i = 0; i < 100; i++) { int stackNum = rand()%3; threeStacks.push(stackNum, i); } cout<<"Insert over!"<<endl; while (1) { cout<<"stack 0 : "<<endl; int value = threeStacks.pop(0); if (value == -1) break; cout<<value<<endl;; } return 0; }
EOF