zoukankan      html  css  js  c++  java
  • 《算法导论》笔记 第10章 10.1 栈和队列

    【笔记】

    栈:后进先出 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)



  • 相关阅读:
    Qt消息机制和事件、事件过滤
    QTableview 获取鼠标坐标的item(QModelIndex)
    qt 拖放dropEvent
    Qt获取控件位置,坐标总结
    Quick Easy FTP Server FTP工具文件传输使用
    Qt QDialog将窗体变为顶层窗体(activateWindow(); 和 raise() )
    makefile 通配符了解% $@ $^ $<
    QLocalServer和QLocalSocket单进程和进程通信
    RC4 加解密
    qt 拷贝文件设置进度条
  • 原文地址:https://www.cnblogs.com/cyendra/p/3681505.html
Copyright © 2011-2022 走看看