代码之家  ›  专栏  ›  技术社区  ›  Jorge Zazueta

汉诺塔C++的堆栈实现

  •  -1
  • Jorge Zazueta  · 技术社区  · 6 年前

    我已经为一个带有堆栈的递归ToH算法编写了以下代码,但我不知道为什么它会失败。没有编译错误,但一旦程序真正开始运行,它会稍微“思考”,然后崩溃。有什么想法吗?

    相关代码:

    void algoritmoDeTorres(int numDiscos, pila &origen, pila &aux, pila &meta)
    {
        GotoXY(0,0);
        if(numDiscos==1)
        {
            int item;
            item = origen.pop(); //crashes in this function
            lista laux;
            laux.insertaInicio(item);
            meta.push(item);
            return;
        }
        algoritmoDeTorres(numDiscos - 1, origen, aux, meta);
        origen.imprimePila();
        cout << endl;
        aux.imprimePila();
        cout << endl;
        meta.imprimePila();
        algoritmoDeTorres(numDiscos -1, aux, meta, origen);
    }
    
    
    class pila
    {
        private:
            lista lisst;
        public:
            int pop()
            {
                int tam;
                tam = lisst.regresaItem();
                lisst.borraInicio();
                return tam;
            }        
        };
    
    class lista
    {
    private:
        nodo *cabeza;
    public:
        lista()
        {
            cabeza = NULL;
        }
        void borraInicio()
        {
            nodo * aux;
            aux = cabeza->next; 
            delete cabeza;
            cabeza = aux;
        }
        int regresaItem()
        {
            return cabeza->item; //crashes here specifically
        }
    };
    
    class nodo
    {
    public:
        int item;
        nodo* next;
    
        nodo(int a,nodo * siguiente)
        {
            item = a;
            next = siguiente;
        }
    };
    
    int main()
    {
        pila ORIGEN,AUX,META;
        ORIGEN.push(3);
        ORIGEN.push(2);
        ORIGEN.push(1);
    
        algoritmoDeTorres(ORIGEN.Size(),ORIGEN,AUX,META);
    
        ORIGEN.destruirPila();
        AUX.destruirPila();
        META.destruirPila();
        return 0;
    }
    

    PS:对不起,我的课是西班牙语的,但很多想法仍然是用英语表达的,因此是时髦的语言。

    必要的重要翻译:

    aloritmoDeTorres-Towers算法

    迪斯科-磁盘

    pila-堆叠

    Origen-原点

    元-目的地/目标

    不确定-插入(在)开头

    Imprime-打印

    Regresa-返回

    Borra-擦除/删除

    Nodo-节点

    卡贝扎-头部

    Siguiente-下一个

    1 回复  |  直到 6 年前
        1
  •  0
  •   jackw11111    6 年前

    主要是重新安排课程,填补空白:

    #include <iostream>
    
    using namespace std;
    
    class nodo
    {
    public:
        int item;
        nodo* next;
    
        nodo(int a,nodo * siguiente)
        {
            item = a;
            next = siguiente;
        }
    };
    
    class lista
    {
    private:
        nodo* cabeza;
        nodo* p;
    public:
        lista()
        {
            cabeza = NULL;
            p = NULL;
        }
        void insertaInicio(int n)
        {
            //create a new node
            cabeza = new nodo(n, p);
            //set next pointer to head
            p = cabeza;
    
        }
        void borraInicio()
        {
            nodo * aux;
            aux = cabeza->next; 
            delete cabeza;
            cabeza = aux;
        }
        int regresaItem()
        {
            return cabeza->item;
        }
    };
    
    class pila
    {
    private:
        //sz (with getters and setters) used to keep track of the size of the stack
        //(incremented in push, decremented in pop)
        int sz;
        lista lisst;
    public:
        pila()
        {
            sz = 0;
        }
        int size()
        {
            return sz;
        }
        void setsize(int size)
        {
            sz = size;
        }
        void push(int n)
        {
            lisst.insertaInicio(n);
            sz++;
    
        }
        int pop()
        {
            int tam;
            tam = lisst.regresaItem();
            lisst.borraInicio();
            sz--;
            return tam;
        }
        void imprimePila()
        {
            //a lengthy way to print the stack
            //was abit unusual as the pop function
            //was removing elements from the stack,
            //when all that was necessary was to print them.
            //this was a workaround that just copied the stack,
            //printed (and removed) elements from original stack,
            //but set the empty to stack to the copy,
            //to leave it unchanged.
            //feel free to find a better way for this
            lista copy;
            cout << '[';
            int lsize = this->size();
            int arr[3] = {};
            int ind = 2;
            while (this->size() != 0){
                int item = this->pop();
                arr[ind] = item;
                cout<< item;
                cout << ',';
                ind--;
            }
            for (int i = ind; i < 3; i++){
                copy.insertaInicio(arr[i]);
            }
            cout <<  ']';
            lisst = copy;
            this->setsize(lsize);
        }
    };
    //the stacks are instantiated globally so they can be printed at every
    //recursive step from algoritmoDeTorres()
    pila ORIGEN, AUX, META;
    
    void algoritmoDeTorres(int numDiscos, pila &origen, pila &aux, pila &meta)
    {
        //if statement used to rearrange discs ONLY if there are any (if numdiscos is more than 0)
        if (numDiscos > 0){
            //move (numDiscos - 1) discs from origen to aux, so they are out of the way
            algoritmoDeTorres(numDiscos - 1, origen, meta, aux);
    
            //move the exposed disc from origen to meta
            int item;
            item = origen.pop();
            //lista laux;
            //laux.insertaInicio(item);
            //commented this list out since the item
            //is added to the list of stack its being added to in the push call
            meta.push(item);
    
            ORIGEN.imprimePila();
            AUX.imprimePila();
            META.imprimePila();
            cout << endl;
    
            //now move the (numDiscos - 1) discs that we left on aux onto meta
            algoritmoDeTorres(numDiscos - 1, aux, origen, meta);
        }
    }
    
    int main()
    {
        ORIGEN.push(3);
        ORIGEN.push(2);
        ORIGEN.push(1);
    
        ORIGEN.imprimePila();
        AUX.imprimePila();
        META.imprimePila();
        cout << endl;
    
        algoritmoDeTorres(ORIGEN.size(), ORIGEN, AUX, META);
        //objects not allocated with 'new' don't need to be explicitly destroyed
        //ORIGEN.destruirPila();
        //AUX.destruirPila();
        //META.destruirPila();
    
        return 0;
    }