如何以这种方式使用和分配这个类?

时间:2018-02-08 13:25:44

标签: java singly-linked-list

我目前正在尝试了解Singly链表。

我不了解SinglyLinkedList.java类中的一些代码。如何调用Node类,然后将其分配为:private Node first;

我原本以为你必须做这样的事情

 Node<T> help =new Node<>();

 help = first;

如果有人可以解释,或者给我一个可以帮助我的链接,我们将不胜感激。 谢谢!

public class Node<T> {

    public T elem;
    public Node<T> next;

    public Node(T elem) {
        this.elem = elem;
        next = null;
    }

    public Node(T elem, Node<T> next) {
        this.elem = elem;
        this.next = next;
    }

    @Override
    public String toString() {
        return "Node{" + "elem=" + elem + '}';
    }

}
package list;

/**
 *
 * @author dcarr
 */
public class SinglyLinkedList<T> implements List<T> {

    private Node<T> first;
    private Node<T> last;

    public SinglyLinkedList() {
        first = null;
        last = null;
    }

    @Override
    public boolean isEmpty() {
        return first == null;
    }

    @Override
    public int size() {
        if (isEmpty()){
            return 0;
        } else {
            int size = 1;
            Node<T> current = first;
            while(current.next != null){
                current = current.next;
                size++;
            }
            return size;
        }
    }

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

    @Override
    public void insert(T elem) {
        // if there is nothing in the list
        if (isEmpty()){
            first = new Node<>(elem);
            last = first;
        // if the list has elements already
        } else {
            // the new element will be the next of what was the last element
            last.next = new Node<>(elem);
            last = last.next; 
        }
    }

    @Override
    public void remove(T elem) {
        if (!isEmpty()){
            int index = 0;
            Node<T> current = first;
            while (current != null && current.elem != elem){
                current= current.next;
                index++;
            }
            remove(index);
        }
    }

    @Override
    public String toString() {
        if (isEmpty()){
            return "Empty List";
        } else {
            String str = first.elem.toString() + " ";
            Node<T> current = first;
            while(current.next != null){
                current = current.next;
                str += current.elem.toString() + " ";

            }
            return str;
        }
    }

    @Override
    public void insertAt(int index, T e) {

        if (index == 0){
            first = new Node<>(e, first);
            if (last == null){
                last = first;
            }
            return;
        }
        Node<T> pred = first;
        for (int i = 0; i < index-1; i++) {
           pred = pred.next;
        }
        pred.next = new Node<>(e, pred.next);
        System.out.println(pred);

        if (pred.next.next == null){
            // what does this mean pred.next is?
            last = pred.next;
        }
    }

    @Override
    public void remove(int index) {
        if (index < 0 || index >= size()){
            throw new IndexOutOfBoundsException();
        } else if (isEmpty()){
            return;
        }

        if (index == 0){
            first = first.next;
            if (first == null){
                last = null;
            }
            return;
        }
        Node<T> pred = first;
        for (int i = 1; i <= index-1; i++) {
            pred = pred.next;
        }
        // remove pred.next
        pred.next = pred.next.next;
        if (pred.next == null){
            last = pred;
        }
    }

}

1 个答案:

答案 0 :(得分:0)

first字段会自动初始化为null

private Node<T> first;

我假设会有一些方法在最后添加一个元素,如下所示:

public void add(T element) {
   if (first == null) {
       first = new Node<T>(element);
       last = first;
   }
   else {
       last.next = new Node<>(element);
       last = last.next;
   }
}

所以当你创建一个新的SinglyLinkedList时:

SinglyLinkedList<String> sillyList = new SinglyLinkedList<>();

firstlast字段都包含空引用。

请注意,first方法此时将导致NullPointerException。更好的实施方式是:

@Override
public Optional<T> first() {
    if (first != null) {
        return Optional.ofNullable(first.elem);
    }
    else {
        return Optional.empty();
    }
}

现在,如果你添加一个元素:

sillyList.add("Adam");

add方法中执行的代码是:

first = new Node<>(elem);
last = first;

所以first指向一个新的Node实例,其elem字段保存值为“Adam”。 last指向同一个Node实例。

本课程中的一些方法我将以不同的方式实现,例如:

@Override
public void remove(int index) {     
    if (index < 0) {
        throw new IndexOutOfBoundsException("Index cannot be negative");
    }
    else if (index == 0 && first != null) {
        first = null;
        last = null;            
    }        
    else {
        Node<T> curr = new Node<>("dummy", first);
        int c = 0;
        while (curr.next != null) {                 
            if (c == index) {
                curr.next = curr.next.next;
                if (curr.next == null) {
                    last = curr;
                }
                return;
            }
            curr = curr.next;
            c++;
        }
        throw new IndexOutOfBoundsException(String.valueOf(c));

}

此外,java.util.List接口中实际上并不存在某些方法,例如insert,insertAt和first。所以这些方法不能有@Override注释。