用一个数组实现三个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

原文地址:https://www.cnblogs.com/lihaozy/p/2809806.html