Jump to content
Fórum Script Brasil
  • 0

[Problema] Lista encadeada com template


ThiagoZ
 Share

Question

Oi Pessoal, estou com um problema em uma implementação de lista encadeada usando template.
Quando crio uma lista e manipulo ela, não dá nenhum problema, mas quando coloco lista como um atributo de uma outra classe, não consigo manipular ela.
Também quando tento atribuir a lista pra outro objeto, o programa para inesperadamente. Seguem os códigos:

ListaEncadeada.h (A implementação da lista usando template).

#ifndef LISTAENCADEADA
#define LISTAENCADEADA

template<class T>
class ListaEncadeada{
private:

    //Classe amiga No
    class No{
        friend class ListaEncadeada<T>;
    private:
        T   *_item;
        No  *_proximo;

        No(){
            _item = 0;
            _proximo = 0;
        }

        ~No(){
            if(_item != 0) delete _item;
        }
    };
    //=====================================


    //Atributos
    No  *_primeiro;
    No  *_ultimo;
    No  *_pos;
    int _tamanho;
    //=====================================

public:

    //Construtores e Destrutores
    ListaEncadeada();
    ListaEncadeada(const ListaEncadeada<T> &lista);
    ~ListaEncadeada();
    //=====================================


    //Assinatura dos Metodos
    void insere(T &chave);
    bool retira(T &chave);
    T* primeiro();
    T* proximo();
    bool vazia();
    bool pesquisa(T &chave);
    T* pesquisa(int index);
    int getTamanho();
    //=====================================

    //Sobrecarga do operador de atribuicao
    ListaEncadeada<T> &operator=(ListaEncadeada byValList);
};

#endif // LISTAENCADEADA
/*
    IMPLEMENTACAO
*/

using namespace std;

/*
    Descricao: Construtor da classe.


    Pre-Condicao: Nenhuma.

    Pos-Condicao: Inicializacao dos elementos da lista.
*/
template<class T>
ListaEncadeada<T>::ListaEncadeada(){
    this->_primeiro = new No();
    this->_pos = this->_primeiro;
    this->_ultimo = this->_primeiro;
    this->_primeiro->_proximo = 0;
    this->_tamanho = 0;
}


template<class T>
ListaEncadeada<T>::ListaEncadeada(const ListaEncadeada<T> &lista){
    this->_primeiro = new No();
    this->_pos = this->_primeiro;
    this->_ultimo = this->_primeiro;
    this->_primeiro->_proximo = 0;
    this->_tamanho = 0;

    No* current = lista._primeiro;

    while (current != NULL) {
        this->insere(*current->_item);
        current = current->_proximo;
    }
}


/*
    Descricao: Destrutor da classe Lista.


    Pre-Condicao: Lista criada.

    Pos-Condicao: Lista destruida.
*/
template<class T>
ListaEncadeada<T>::~ListaEncadeada(){
    No *aux = this->_primeiro;

    while(aux != 0){
        this->_primeiro = this->_primeiro->_proximo;
        delete aux;
        aux = this->_primeiro;
    }
}


/*
    Descricao: Insere um elemento na lista.


    Pre-Condicao: Lista criada.

    Pos-Condicao: Elemento inserido no comeco da lista.
*/
template<class T>
void ListaEncadeada<T>::insere(T &chave){
    this->_ultimo->_proximo = new No();
    this->_ultimo = this->_ultimo->_proximo;
    this->_ultimo->_item = new T(chave);
    this->_ultimo->_proximo = 0;
    this->_tamanho++;
}


/*
    Descricao:  Retirar elemento da lista. Retorna verdade se o elemento foi retirado com
                exito.


    Pre-Condicao: Lista criada.

    Pos-Condicao: Caso o elemento exista, ele eh removido da lista, caso nao exista, a lista ficara intacta
*/
template<class T>
bool ListaEncadeada<T>::retira(T &chave){
    if(this->vazia()){
        return  false;
    }else{
        No *aux = this->_primeiro;

        while((aux->_proximo != 0) && (*(aux->_proximo->_item) != chave)){
            aux = aux->_proximo;
        }

        if(aux->_proximo == 0) return false;

        No *q = aux->_proximo;
        //T *item = q->_item;

        aux->_proximo = q->_proximo;
        q->_item = 0;

        if(aux->_proximo == 0) this->_ultimo = aux;
        delete q;

        this->_tamanho--;
        return true;
    }
}


/*
    Descricao: Metodo para retornar o primeiro elemento da lista


    Pre-Condicao: Lista criada.

    Pos-Condicao: Lista intacta.
*/
template<class T>
T* ListaEncadeada<T>::primeiro(){
    this->_pos = this->_primeiro;
    return this->proximo();
}


/*
    Descricao: Metodo que retorna o proximo do elemento da posicao atual.


    Pre-Condicao: Lista criada.

    Pos-Condicao: Elemento "pos" da lista anda uma posicao.
*/
template<class T>
T* ListaEncadeada<T>::proximo(){
    this->_pos = this->_pos->_proximo;

    if(this->_pos == NULL) return NULL;
    else return this->_pos->_item;
}


/*
    Descricao: Retorna verdade caso  lista esteja vazia.


    Pre-Condicao: Lista iniciada.

    Pos-Condicao: Lista intacta.
*/
template<class T>
bool ListaEncadeada<T>::vazia(){
    return (this->_primeiro == this->_ultimo);
}


/*
    Descricao:  Metodo que pesquisa a ocorrencia de um elemento na lista.
                Caso o elemento exista, o metodo retorna true, se nao, false.


    Pre-Condicao: Lista iniciada.

    Pos-Condicao: Lista intacta.
*/
template<class T>
bool ListaEncadeada<T>::pesquisa(T &chave){
    if(this->vazia()) return false;

    No *aux = this->_primeiro;
    while(aux->_proximo != 0){
        if(*(aux->_proximo->_item) == chave){
            return true;
        }

        aux = aux->_proximo;
    }

    return false;
}


/*
    Descricao:  Metodo retorna o elemento do indice de entrada.


    Pre-Condicao: Lista inicializada.

    Pos-Condicao: Lista intacta.
*/
template<class T>
T* ListaEncadeada<T>::pesquisa(int index){
    if(this->vazia()) return 0;
    if(index > this->_tamanho) return 0;

    No *aux = this->_primeiro;
    int i = 0;
    while(aux->_proximo != 0){
        if(i == index){
            return aux->_proximo->_item;
        }

        aux = aux->_proximo;
        i++;
    }

    return 0;
}


/*
    Descricao: Metodo retorna o tamanho da lista.


    Pre-Condicao: Lista inicializada

    Pos-Condicao: Lista intacta.
*/
template <class T>
int ListaEncadeada<T>::getTamanho(){
    return this->_tamanho;
}


template<class T>
ListaEncadeada<T>& ListaEncadeada<T>::operator=(ListaEncadeada byValList)
{
    std::swap(this->_primeiro, byValList._primeiro);
    return *this;
}

Esses arquivos a seguir são os que eu usei pra testar. Segue as implementações de outras classes:

Autor.h

#ifndef AUTOR_H
#define AUTOR_H

#ifndef AUTOR_H
#define AUTOR_H
#include <string>
using namespace std;
class Autor
{
private:
string _nome;
public:
Autor(); //Construtor da classe Autor
Autor(Autor &autor); //Construtor da classe Autor
~Autor();
//Metodo que retorna o nome do Autor
string getNome();
//Metodo que seta o nome do autor
void setNome(string nome);
//Metodo que sobrecarrega o operador de igualdade
// Quando o nome do autor de entrada é o mesmo que o nome do autor
// desta classe, então retorna verdade
bool operator==(Autor autor);
//Metodo que sobrecarrega o operador de desigualdade
// Quando o nome do autor de entrada é diferente que o nome do autor
// desta classe, então retorna verdade
bool operator!=(Autor autor);
};
#endif // AUTOR_H

Autor.cpp

#include "autor.h"
//Construtor da classe Autor
Autor::Autor()
{}
//Construtor da classe Autor
Autor::Autor(Autor &autor)
{
this->_nome = autor.getNome();
}
//Destrutor da classe Autor
Autor::~Autor()
{}
//Retorna o nome do Autor
string Autor::getNome(){
return this->_nome;
}
//Seta um nome para Autor
void Autor::setNome(string nome){
this->_nome = nome;
}
//Sobrecarga do operador de igualdade
bool Autor::operator==(Autor autor){
return (this->_nome == autor.getNome());
}
//SObrecarga do operador de desigualdade
bool Autor::operator!=(Autor autor){
return (this->_nome != autor.getNome());
}

Main.cpp

#include <iostream>

#include "listaencadeada.h"
#include "autor.h"

using namespace std;

int main()
{
    ListaEncadeada<Autor> autores;

    Autor a1;

    a1.setNome("Autor1");
    autores.insere(a1);
    //l1.addAutor(a1);

    a1.setNome("Autor2");
    autores.insere(a1);
    //l1.addAutor(a1);

    a1.setNome("Autor3");
    autores.insere(a1);
    //l1.addAutor(a1);

    a1.setNome("Autor4");
    autores.insere(a1);
    //l1.addAutor(a1);

    cout << "Autores:" << endl;
    for(int i = 0; i < autores.getTamanho(); i++){
        cout << autores.pesquisa(i)->getNome() << endl;
    }

    ListaEncadeada<Autor> autoresAux(autores);
    //autoresAux = autores;

    cout << "Autores Aux:" << endl;
    for(int i = 0; i < autoresAux.getTamanho(); i++){
        cout << autoresAux.pesquisa(i)->getNome() << endl;
    }

    return 0;
}

Desde já, obrigado pela atenção.

Abraços.

Link to comment
Share on other sites

1 answer to this question

Recommended Posts

  • 0

Repostando os códigos:

ListaEncadeada.h

#ifndef LISTAENCADEADA
#define LISTAENCADEADA

template<class T>
class ListaEncadeada{
private:

    //Classe amiga No
    class No{
        friend class ListaEncadeada<T>;
    private:
        T   *_item;
        No  *_proximo;

        No(){
            _item = 0;
            _proximo = 0;
        }

        ~No(){
            if(_item != 0) delete _item;
        }
    };
    //=====================================


    //Atributos
    No  *_primeiro;
    No  *_ultimo;
    No  *_pos;
    int _tamanho;
    //=====================================

public:

    //Construtores e Destrutores
    ListaEncadeada();
    ListaEncadeada(const ListaEncadeada<T> &lista);
    ~ListaEncadeada();
    //=====================================


    //Assinatura dos Metodos
    void insere(T &chave);
    bool retira(T &chave);
    T* primeiro();
    T* proximo();
    bool vazia();
    bool pesquisa(T &chave);
    T* pesquisa(int index);
    int getTamanho();
    //=====================================

    //Sobrecarga do operador de atribuicao
    ListaEncadeada<T> &operator=(ListaEncadeada byValList);
};

#endif // LISTAENCADEADA
/*
    IMPLEMENTACAO
*/

using namespace std;

/*
    Descricao: Construtor da classe.


    Pre-Condicao: Nenhuma.

    Pos-Condicao: Inicializacao dos elementos da lista.
*/
template<class T>
ListaEncadeada<T>::ListaEncadeada(){
    this->_primeiro = new No();
    this->_pos = this->_primeiro;
    this->_ultimo = this->_primeiro;
    this->_primeiro->_proximo = 0;
    this->_tamanho = 0;
}


template<class T>
ListaEncadeada<T>::ListaEncadeada(const ListaEncadeada<T> &lista){
    this->_primeiro = new No();
    this->_pos = this->_primeiro;
    this->_ultimo = this->_primeiro;
    this->_primeiro->_proximo = 0;
    this->_tamanho = 0;

    No* current = lista._primeiro;

    while (current != NULL) {
        this->insere(*current->_item);
        current = current->_proximo;
    }
}


/*
    Descricao: Destrutor da classe Lista.


    Pre-Condicao: Lista criada.

    Pos-Condicao: Lista destruida.
*/
template<class T>
ListaEncadeada<T>::~ListaEncadeada(){
    No *aux = this->_primeiro;

    while(aux != 0){
        this->_primeiro = this->_primeiro->_proximo;
        delete aux;
        aux = this->_primeiro;
    }
}


/*
    Descricao: Insere um elemento na lista.


    Pre-Condicao: Lista criada.

    Pos-Condicao: Elemento inserido no comeco da lista.
*/
template<class T>
void ListaEncadeada<T>::insere(T &chave){
    this->_ultimo->_proximo = new No();
    this->_ultimo = this->_ultimo->_proximo;
    this->_ultimo->_item = new T(chave);
    this->_ultimo->_proximo = 0;
    this->_tamanho++;
}


/*
    Descricao:  Retirar elemento da lista. Retorna verdade se o elemento foi retirado com
                exito.


    Pre-Condicao: Lista criada.

    Pos-Condicao: Caso o elemento exista, ele eh removido da lista, caso nao exista, a lista ficara intacta
*/
template<class T>
bool ListaEncadeada<T>::retira(T &chave){
    if(this->vazia()){
        return  false;
    }else{
        No *aux = this->_primeiro;

        while((aux->_proximo != 0) && (*(aux->_proximo->_item) != chave)){
            aux = aux->_proximo;
        }

        if(aux->_proximo == 0) return false;

        No *q = aux->_proximo;
        //T *item = q->_item;

        aux->_proximo = q->_proximo;
        q->_item = 0;

        if(aux->_proximo == 0) this->_ultimo = aux;
        delete q;

        this->_tamanho--;
        return true;
    }
}


/*
    Descricao: Metodo para retornar o primeiro elemento da lista


    Pre-Condicao: Lista criada.

    Pos-Condicao: Lista intacta.
*/
template<class T>
T* ListaEncadeada<T>::primeiro(){
    this->_pos = this->_primeiro;
    return this->proximo();
}


/*
    Descricao: Metodo que retorna o proximo do elemento da posicao atual.


    Pre-Condicao: Lista criada.

    Pos-Condicao: Elemento "pos" da lista anda uma posicao.
*/
template<class T>
T* ListaEncadeada<T>::proximo(){
    this->_pos = this->_pos->_proximo;

    if(this->_pos == NULL) return NULL;
    else return this->_pos->_item;
}


/*
    Descricao: Retorna verdade caso  lista esteja vazia.


    Pre-Condicao: Lista iniciada.

    Pos-Condicao: Lista intacta.
*/
template<class T>
bool ListaEncadeada<T>::vazia(){
    return (this->_primeiro == this->_ultimo);
}


/*
    Descricao:  Metodo que pesquisa a ocorrencia de um elemento na lista.
                Caso o elemento exista, o metodo retorna true, se nao, false.


    Pre-Condicao: Lista iniciada.

    Pos-Condicao: Lista intacta.
*/
template<class T>
bool ListaEncadeada<T>::pesquisa(T &chave){
    if(this->vazia()) return false;

    No *aux = this->_primeiro;
    while(aux->_proximo != 0){
        if(*(aux->_proximo->_item) == chave){
            return true;
        }

        aux = aux->_proximo;
    }

    return false;
}


/*
    Descricao:  Metodo retorna o elemento do indice de entrada.


    Pre-Condicao: Lista inicializada.

    Pos-Condicao: Lista intacta.
*/
template<class T>
T* ListaEncadeada<T>::pesquisa(int index){
    if(this->vazia()) return 0;
    if(index > this->_tamanho) return 0;

    No *aux = this->_primeiro;
    int i = 0;
    while(aux->_proximo != 0){
        if(i == index){
            return aux->_proximo->_item;
        }

        aux = aux->_proximo;
        i++;
    }

    return 0;
}


/*
    Descricao: Metodo retorna o tamanho da lista.


    Pre-Condicao: Lista inicializada

    Pos-Condicao: Lista intacta.
*/
template <class T>
int ListaEncadeada<T>::getTamanho(){
    return this->_tamanho;
}


template<class T>
ListaEncadeada<T>& ListaEncadeada<T>::operator=(ListaEncadeada byValList)
{
    std::swap(this->_primeiro, byValList._primeiro);
    return *this;
}

(Para meus testes usei):

Autor.h

#ifndef AUTOR_H
#define AUTOR_H

#include <string>

using namespace std;

class Autor
{
private:
    string _nome;

public:
    Autor(); //Construtor da classe Autor
    Autor(Autor &autor); //Construtor da classe Autor
    ~Autor();

    //Metodo que retorna o nome do Autor
    string getNome();

    //Metodo que seta o nome do autor
    void setNome(string nome);

    //Metodo que sobrecarrega o operador de igualdade
    //  Quando o nome do autor de entrada eh o mesmo que o nome do autor
    //  desta classe, entao retorna verdade
    bool operator==(Autor autor);

    //Metodo que sobrecarrega o operador de desigualdade
    //  Quando o nome do autor de entrada eh diferente que o nome do autor
    //  desta classe, entao retorna verdade
    bool operator!=(Autor autor);
};

#endif // AUTOR_H

Autor.cpp

#include "autor.h"

//Construtor da classe Autor
Autor::Autor()
{}

//Construtor da classe Autor
Autor::Autor(Autor &autor)
{
    this->_nome = autor.getNome();
}

//Destrutor da classe Autor
Autor::~Autor()
{}

//Retorna o nome do Autor
string Autor::getNome(){
    return this->_nome;
}

//Seta um nome para Autor
void Autor::setNome(string nome){
    this->_nome = nome;
}

//Sobrecarga do operador de igualdade
bool Autor::operator==(Autor autor){
    return (this->_nome == autor.getNome());
}


//SObrecarga do operador de desigualdade
bool Autor::operator!=(Autor autor){
    return (this->_nome != autor.getNome());
}

Main.cpp

#include <iostream>

#include "listaencadeada.h"
#include "autor.h"

using namespace std;

int main()
{
    ListaEncadeada<Autor> autores;

    Autor a1;

    a1.setNome("Autor1");
    autores.insere(a1);
    //l1.addAutor(a1);

    a1.setNome("Autor2");
    autores.insere(a1);
    //l1.addAutor(a1);

    a1.setNome("Autor3");
    autores.insere(a1);
    //l1.addAutor(a1);

    a1.setNome("Autor4");
    autores.insere(a1);
    //l1.addAutor(a1);

    cout << "Autores:" << endl;
    for(int i = 0; i < autores.getTamanho(); i++){
        cout << autores.pesquisa(i)->getNome() << endl;
    }

    ListaEncadeada<Autor> autoresAux(autores);
    //autoresAux = autores;

    cout << "Autores Aux:" << endl;
    for(int i = 0; i < autoresAux.getTamanho(); i++){
        cout << autoresAux.pesquisa(i)->getNome() << endl;
    }

    return 0;
}

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

  • Forum Statistics

    • Total Topics
      149.8k
    • Total Posts
      646.6k
×
×
  • Create New...