《算法导论》笔记 第10章 10.1 栈和队列

来源:互联网 发布:pot player for mac 编辑:程序博客网 时间:2024/06/04 19:58

【笔记】

栈:后进先出 LIFO

队列:先进先出 FIFO

template<typename ITEM>class stack {private:    ITEM S[MAXN];    int tp;public:    stack() {        tp = 0;    }    bool empty() {        return tp == 0;    }    void push(ITEM x) {        if (tp == MAXN) throw "stack overflow";        S[tp++] = x;    }    ITEM top() {        if (tp == 0) throw "stack empty";        return S[tp-1];    }    void pop() {        if (tp == 0) throw "stack underflow";        tp--;    }    int size() {        return tp;    }};template<typename ITEM>class queue {private:    ITEM Q[MAXN];    int head,tail;    int sz;public:    queue() {        head = tail = sz = 0;    }    bool empty() {        return sz == 0;    }    void push(ITEM x) {        if (sz == MAXN) throw "queue overflow";        Q[tail++] = x;        sz++;        if (tail == MAXN) tail = 0;    }    ITEM front() {        if (sz == 0) throw "queue empty";        return Q[head];    }    void pop() {        if (sz == 0) throw "queue underflow";        head++;        sz--;        if (head == MAXN) head = 0;    }    int size() {        return sz;    }};


【练习】

10.1-1 说明对一个储存在数组S[1..6]中的、初始为空的栈S,依次执行PUSH(S,4),PUSH(S,1),PUSH(S,3),POP(S),PUSH(S,8)以及POP(S)操作后的结果。

4 1 3

4 1

4 1 8

POP返回3


10.1-2 说明如何用一个数组A[1..n]来实现两个栈,使得两个栈中的元素总数不到n时,两者都不会发生上溢。注意PUSH和POP操作的时间应为O(1)。

两个栈分别用A[1]和A[n]做栈底,PUSH操作时,向中间插入元素,当两个栈元素总数为n时数组满,发生上溢。


10.1-3 说明对一个存储在数组Q[1..6]中的、初始为空的队列Q,依次执行ENQUEUE(Q,4),ENQUEUE(Q,1),ENQUEUE(Q,3),DEQUEUE(Q),ENQUEUE(Q,8)以及DEQUEUE(Q)操作后的结果。

4

4 1

4 1 3

1 3

1 3 8

DEQUEUE(Q)返回4


10.1-4 重写ENQUEUE和DEQUEUE,使之能处理队列的下溢和上溢。

见代码。


10.1-5 栈的插入和删除操作都是在一端进行的,而队列的插入和删除确是在两头进行的。另有一种双端队列,其两端都可以做插入和删除操作。对于一个用数组构造的双端队列,请写出四个在两端进行插入和删除操作的过程,要求运行时间都为O(1)。

template <typename ITEM>class deque {private:    ITEM D[MAXN];    int head,tail;    int sz;public:    deque() {        head = tail = 0;        sz = 0;    }    bool empty() {        return sz == 0;    }    ITEM front() {        if (sz == 0) throw "deque empty";        return D[head];    }    ITEM back() {        if (sz == 0) throw "deque empty";        return D[tail-1];    }    void push_front(ITEM x) {        if (sz == MAXN) throw "deque overflow";        if (head == 0) head = MAXN;        head--;        sz++;        D[head] = x;    }    void push_back(ITEM x) {        if (sz == MAXN) throw "deque overflow";        D[tail++] = x;        sz++;        if (tail == MAXN) tail = 0;    }    void pop_front() {        if (sz == 0) throw "deque underflow";        head++;        if (head == MAXN) head = 0;        sz--;    }    void pop_back() {        if (sz == 0) throw "deque underflow";        if (tail == 0) tail = MAXN;        tail--;        sz--;    }    int size() {        return sz;    }};


10.1-6 说明如何用两个栈来实现一个队列,并分析有关队列操作的运行时间。

template <typename ITEM>class queuebytwostack{private:    stack<ITEM> stkin;    stack<ITEM> stkout;    void readyToPop() {        while (!stkin.empty()) {            stkout.push(stkin.top());            stkin.pop();        }    }public:    bool empty() {        if (stkin.empty()&&stkout.empty()) return true;        return false;    }    void push(ITEM x){        try {            stkin.push(x);        }        catch (const char *e) {            throw e;        }    }    ITEM front() {        try {            if (stkout.empty()) readyToPop();            return stkout.top();        }        catch (const char *e) {            throw e;        }    }    void pop() {        try {            if (stkout.empty()) readyToPop();            stkout.pop();        }        catch (const char *e) {            throw e;        }    }    int size() {        return stkin.size()+stkout.size();    }};
PUSH O(1)

POP O(n)


10.1-7 说明如何用两个队列来实现一个栈,并分析有关栈操作的运行时间。

template <typename ITEM>class stackbytwoqueue {private:    queue<ITEM> que[2];    int p;public:    stackbytwoqueue() {        p = 0;    }    bool empty() {        if (que[0].empty()&&que[1].empty()) return true;        return false;    }    void push(ITEM x) {        try {            que[p].push(x);        }        catch (const char *e) {            throw e;        }    }    ITEM top() {        try {            int sz = que[p].size();            ITEM res;            for (int i=1;i<=sz;i++) {                if (i==sz) res = que[p].front();                que[p^1].push(que[p].front());                que[p].pop();            }            p^=1;            return res;        }        catch (const char *e) {            throw e;        }    }    void pop() {        try {            int sz = que[p].size();            for (int i=1;i<=sz-1;i++) {                que[p^1].push(que[p].front());                que[p].pop();            }            que[p].pop();            p^=1;        }        catch (const char *e) {            throw e;        }    }    int size() {        return que[p].size()+que[p^1].size();    }};
PUSH O(1)

POP O(n)



0 0