Double chained list with remove method that does not work

Asked

Viewed 271 times

1

I have this algorithm for a double-chained list, but I get an error in the last interaction on both methods of removing. Any idea what might be wrong with my methods?

Main class

public class Teste<T> extends Node<T> {

    public static void main(String[] args) {

        List<Double> lista = new DoublyLinkedList();

    //TESTANDO SE A LISTA ESTA VAZIA OU NAO
        if(lista.isEmpty())
            System.out.println("lista vazia\n");
        else
            System.out.println("lista nao esta vazia\n");

        System.out.println("preenchendo...\n");

    //PREENCHENDO A LISTA
        for(int i = 0;i<=4;i++) {
            Integer n = new Integer(i);
            lista.add(n *1.0);
        }

    //TESTANDO SE A LISTA ESTA VAZIA DEPOIS DE PREENCHER
        if(lista.isEmpty())
            System.out.println("lista vazia\n");
        else
            System.out.println("lista nao esta vazia\n");

        System.out.println("\n");

    //IMPRIMINDO A LISTA  
        System.out.println("imprimindo a lista!");
        for (int i = 0;i<=4;i++) {
            System.out.println("objeto "+i+ ") "+lista.get(i));
        }


        //REMOVER DA LISTA NA POSICAO 
            lista.remove(1); 
            System.out.println("imprimindo a lista depois de remover na posicao 1!");
            for (int i = 0;i<=4;i++) {
                System.out.println("objeto "+i+ ") "+lista.get(i));
            }

            System.out.println("\n");       

    //PRIMEIRO ELEMENTO DA LISTA
        System.out.println("Valor do primeiro elemento é : "+lista.first()+"\n");

    //LISTA CONTEM VALOR
        System.out.println("A lista contem o valor ? "+lista.contains(2.0)+"\n");

    //REMOVER ESSE VALOR DA LISTA
        lista.remove(3.0);
        System.out.println("imprimindo a lista depois de remover o 3.0!");
        for (int i = 0;i<=4;i++) {
            System.out.println("objeto "+i+ ") "+lista.get(i));
        }   

    //SETANDO ESSE VALOR
        System.out.println("\nSetando o valor");    
        lista.set(2, 8.0);
        System.out.println("imprimindo a lista novamente!");
        for (int i = 0;i<=4;i++) {
            System.out.println("objeto "+i+ ") "+lista.get(i));
        }

    }
}

List Class

public class DoublyLinkedList<T> implements List<T> {

    private Node<T> list;

    public DoublyLinkedList() {
        this.list = null;
    }

    @Override
    public void add(T obj) {


        Node<T> node = new Node<>(obj);

        if (list == null) {
            list = node;
        } else {
            list.setPrevious(node);
            node.setNext(list);
            list = node;
        }
    }

    @Override
    public void set(int position, T obj) {

        Node<T> node = list;

        int i=1;
              while(node.getNext()!=null) {
                  if(i==position) {
                      node.getNext().setValue(obj);
                  }

                    node=node.getNext();
                    i++;  
              } 
    }

    @Override
    public void remove(T obj) {

        Node<T> node = list;

        while (node != null) {

            if(node.getValue().equals(obj)){

                //se for o primeiro da lista
                if(node.getPrevious() != null)
                    node.getPrevious().setNext(node.getNext());
                else 
                    list = node.getNext();

                //se for o ultimo da lista
                if(node.getNext() != null)
                    node.getNext().setPrevious(node.getPrevious());
                else 
                    node.getNext().setNext(null);


                node.setNext(null);
                node.setPrevious(null);

                break;

            }

            node = node.getNext();

        }

    }

    @Override
    public void remove(int position) {
        Node<T> node = list;

        int i=1;

        while(node.getNext()!=null) {

            if(i==position) {
                break;
            }
                node=node.getNext();
                i++;
        }

        Node<T> aux = node.getNext();
        node.setNext(aux.getNext());
        aux.setNext(null);

    }

    @Override
    public T get(int position) {
        Node<T> node = list;
        int i = 0;
        if(position == 0) {
            return node.getValue();
        }else {
        while(node.getNext() != list) {
            if(i == position){
                break;
            }
            i++;
            node = node.getNext();
        }
        return node.getValue();
        }
    }

    @Override
    public T first() {
            return (T) list.getValue();
    }

    @Override
    public T last(){
        Node<T> node= list;

        while(node.getNext()!=null) {
            node=node.getNext();
        }
        return (T)node.getValue();
    }

    @Override
    public boolean isEmpty() {
        if(list == null) 
            return true;
        else 
            return false;

    }

    @Override
    public boolean contains(T obj) {

        Node<T> node=list;

        while(node.getNext()!=null) {
            if(node.getNext().getValue().equals(obj)){
                return true;
            }
            node=node.getNext();
        }
        return false;
    }

}

1 answer

1


Here I identified a Nullpointerexception error in your method get (int position):

@Override
public T get(int position) {
    Node<T> node = list;
    int i = 0;
    if (position == 0) {
        return node.getValue();
    } else {
        // Estava node.getNext() != list
        while (node.getNext() != null) {
            node = node.getNext();
            i++;

            if(i == position){
                return node.getValue();
            }
        }
        // Adicionei essa exceção porque ele estava ultrapassando
        // os limites do array (Opcional)
        if(i < position){
            throw new IndexOutOfBoundsException();
        }
    }
    return null;
}

To act together with this new get method you would have to create a size() method to know the list size: (so at the time of the for will be i < list.size() )

@Override
public int size() {
    Node<T> node = list;
    int size = 0;

    while (node.getNext() != null) {
        node = node.getNext();
        size++;
    }
    // Falta somar o último nó
    return size + 1;
}

Moreover, in the methods remove you don’t need so many ifs, just see how it looks:

@Override
public void remove(T obj) {

    Node<T> node = list;
    while (node != null) {

        if (node.getValue().equals(obj)) {
            Node<T> n = node.getNext();
            Node<T> p = node.getPrevious();
            node.setNext(null);

            if (p != null){
                // Se for o último elemento n vai ser nulo
                p.setNext(n);
            }else{
                // Se for o primeiro elemento o ponteiro inicial da lista vai para o próximo
                list = n;
            }

            if (n != null){
                // Se o no tiver um próximo
                n.setPrevious(p);
            }


            break;
        }

        node = node.getNext();
    }

}

@Override
public void remove(int position) {
    Node<T> node = list;

    int i = 0;

    while (node.getNext() != null) {

        if (i == position) {
            break;
        }
        node = node.getNext();
        i++;
    }

    Node<T> n = node.getNext();
    Node<T> p = node.getPrevious();
    node.setNext(null);

    if (p != null){
        p.setNext(n);
    }else{
        list = n;
    }

    if (n != null) {
        n.setPrevious(p);
    }  
}

I hope it helps.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.