Как удалить хвостовой список и распечатать список?

#java

#java

Вопрос:

Я экспериментировал с узловыми и односвязными списками, и я хочу удалить хвостовой список и распечатать его. в основном я пытался это сделать, однако это выдает ошибку.

РЕДАКТИРОВАТЬ: вывод с комментарием строки ошибки:

 Circle{radius=2} has a perimeter: 12.56
Circle{radius=1} has a perimeter: 6.28
Square{length=3} has perimeter: 12.0
Square{length=5} has perimeter: 20.0
Triangle{length=1 width=4 height=5} has perimeter: 10.0
Triangle{length=3 width=5 height=7} has perimeter: 15.0
Rectangle{length=1 width=2} has perimeter: 6.0
Rectangle{length=8 width=9} has perimeter: 34.0
 

Если я раскомментирую строку, я получаю эту ошибку в eclipse.

   Exception in thread "main" java.lang.NullPointerException
    at ShapeLinkedList.deleteAtIndex(ShapeLinkedList.java:108)
    at M.main(M.java:35)
 

Главная:

 public class M {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        int[] values = {2,1,3,5,1,4,5,3,5,7,1,2,8,9};
        ShapeLinkedList sll = new ShapeLinkedList();
        Circle c1 = new Circle(values[0]);
        Circle c2 = new Circle(values[1]);
        Square sq1 = new Square(values[2]);
        Square sq2 = new Square(values[3]);
        Triangle t1 = new Triangle(values[4],values[5],values[6]);
        Triangle t2 = new Triangle(values[7],values[8],values[9]);
        Rectangle r1 = new Rectangle(values[10],values[11]);
        Rectangle r2 = new Rectangle(values[12],values[13]);
        sll.insertAtBeginning(r1);
        sll.insertAtBeginning(r2);
        sll.insertAtBeginning(c1);
        sll.insertAtBeginning(c2);
        sll.insertAtEnd(sq1);
        sll.insertAtEnd(sq2);
        sll.insertAtEnd(t1);
        sll.insertAtEnd(t2);

        System.out.println(c1);
        System.out.println(c2);
        System.out.println(sq1);
        System.out.println(sq2);
        System.out.println(t1);
        System.out.println(t2);
        System.out.println(r1);
        System.out.println(r2);

       //ERROR STARTS HERE

        /*sll.deleteAtIndex(sll.length());



        System.out.println(c1);
        System.out.println(c2);
        System.out.println(sq1);
        System.out.println(sq2);
        System.out.println(t1);
        System.out.println(t2);
        System.out.println(r1);
        System.out.println(r2);

    */
    }

}
 

ShapeLinkedList:

 public class ShapeLinkedList {

    public Node head;

    public ShapeLinkedList() {
        head = null;
    }



    public ShapeLinkedList(Node head) {
        this.head = head;
    }
    public boolean isEmpty() {
        return length() == 0;
    }
    public void insertAtEnd(Shape data) {
// TODO to be implemented
        Node n = new Node(data,null);
        if (head == null)
            head = n;
        else
        {

            tail().setNext(n);
        }

    }
    public void insertAtBeginning(Shape data) {
// TODO to be implemented
        Node n = new Node(data, head);
        head = n;
    }
    public Node tail() {
// TODO to be implemented
// returns the last node
        Node temp = head;
        if(temp != null)
        {
           while(temp.getNext() != null)
           {
               temp = temp.getNext();
           }
        }
        return temp;
    }
    public int length() {
// TODO to be implemented
        Node temp = head;

        if(temp == null)
            return 0;
        else
        {
            int i = 1;
            while(temp.getNext() != null)
            {
                temp = temp.getNext();
                i  ;

            }
            return i;
        }
    }
    void insertAtIndex(int idx, Shape data) {
// TODO to be implemented
        if(length() >= idx)
        {
            Node n = new Node(data, null);

            Node temp = findAtIndex(idx);

            n.setNext(temp.getNext());
            temp.setNext(n);
        }

    }
    Node findAtIndex(int idx) {
// TODO to be implemented

        if(length() >= idx)
        {
            Node temp = head;
            for(int i = 0; i < idx; i  )
            {
                temp = temp.getNext();
            }
            return temp;
        }
        else
            return null;

    }
    void deleteAtIndex(int idx) {
// TODO to be implemented

        if(length() >= idx )
        {

            if(idx == 0)
                head = head.getNext();
            else
            {
                Node temp = findAtIndex(idx-1);
                temp.setNext(temp.getNext().getNext());
            }
        }


    }
    @Override
    public String toString() {
        return "";

    }
    void deleteData(Shape s) {
// TODO to be implemented
        Node temp = head;
        for(int i = 0; i < length(); i  )
        {
            if(temp.getData() == s)
                deleteAtIndex(i);
        }

    }
    @Override
    public int hashCode() {
// TODO to be implemented
        return 0;
    }
    @Override
    public boolean equals(Object obj) {
// TODO to be implemented

        return false;
    }
    // Node is nested class because it only exists along with linked list
    public static class Node {
        private Shape data;
        private Node next;
// TODO develop all the methods that are needed
// such as constructors, setters, getters
// toString, equals, hashCode
        public Node(Shape S, Node N)
        {
            data = S;
            next = N;
        }


        public Node getNext()
        {
            return next;
        }

        public Shape getData()
        {
            return data;
        }

        public void setNext(Node N)
        {
            next = N;
        }
    }

}
 

Класс Circle:

 public class Circle implements Shape {

    private int S;

    public Circle(int n)
    {
        S = n;
    }
    public double getPerimeter (){

        double p = 2*3.14*S;
        return p;
    }

    @Override
    public String toString(){

        return "Circle{radius="   S   "} has a perimeter: "   getPerimeter();
    }

    @Override
    public boolean equals(Object o)
    {
        if (this == o)
            return true;

        if (o == null)
            return false;

        if (getClass() != o.getClass())
            return false;


        return false;
    }

    @Override
    public int hashCode()
    {

        return 0;
    }

}
 

Есть ли причина, по которой я делаю это неправильно? Любые возможные решения для решения этой проблемы?

Комментарии:

1. вероятно, вы каким-то образом убегаете от конца списка. начните отладку…

2. Что вы имеете в виду? Я новичок в полном понимании узлов.

3. Что вы имеете в виду, я имел в виду, что вы имеете в виду, начиная с конца списка?

4. Потому что это: temp.setNext(temp.getNext().getNext()); . вы пытаетесь удалить ПОСЛЕДНИЙ элемент в списке. это означает, что теперь вы переходите к концу списка, потому что вы выполняете два getNext() вызова temp , которые уже являются ПОСЛЕДНИМ элементом в списке.

Ответ №1:

Проблема в том, что вы забыли учесть индексы, начинающиеся с 0, когда запрашивали length() для метода deleteAtIndex . Когда у вас есть список из 10 значений, у вас есть индексы 0-9, однако вы передаете deleteAtIndex(10), то есть общий размер, а не индекс последнего значения.

Итак, в вашем методе deleteAtIndex:

   else
        {
            Node temp = findAtIndex(idx-1);
            temp.setNext(temp.getNext().getNext());
        }
 

Он ищет последний индекс или индекс 9. Затем выполняется GetNext().GetNext() .

Обычно это было бы нормально, однако:

в вашем findAtIndex:

         for(int i = 0; i < idx; i  )
        {
            temp = temp.getNext();
        }
 

Если вы передадите 9, то вы переместите более 9 узлов из головы. Оставляя вас в хвосте, однако вы хотели быть на один узел перед хвостом.