Ir para conteúdo
Fórum Script Brasil
  • 0

[Problema] Lista encadeada com template


ThiagoZ

Pergunta

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 para o comentário
Compartilhar em outros sites

1 resposta a esta questão

Posts Recomendados

  • 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 para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152k
    • Posts
      651,8k
×
×
  • Criar Novo...