【问题标题】:Finding the second-to last node in a singly linked list在单链表中查找倒数第二个节点
【发布时间】:2019-06-21 10:37:20
【问题描述】:

所以我有一个单链表的实现,我正在尝试添加一个方法来报告列表的倒数第二个节点。但是,我不确定是否允许我在 Node 类下编写该方法,然后从单链表类访问它。如果这样做,节点类的实例变量('head' 将用作访问倒数第二个方法的变量,但也用作倒数第二个方法的输入。可以吗?下面是我的实现/尝试。

public class SinglyLinkedList { 

    private static class Node<Integer>{
        private Integer element;
        private Node<Integer> next;
        private Node<Integer> penultimate;

        public Node(Integer e, Node<Integer> n) {
            element = e;
            next = n;
            penultimate = null;
        }
        public Integer getElement() {return element;}
        public Node<Integer> getNext(){return next;}
        public void setNext(Node<Integer> n) {next = n;}
        public Node<Integer> penultimate(Node<Integer> head) {
            Node<Integer> current = head;
            while(current != null) {
                if(head.getNext() == null) {
                    penultimate = head;
                }
                else {
                    current = current.getNext();
                }
            }
            return penultimate;
        }
    }

    private Node<Integer> head = null;
    private Node<Integer> tail = null;
    private int size = 0;

    public SinglyLinkedList() {}

        public int size() {
            return size;
        }
        public boolean isEmpty() {
            return size == 0;
        }
        public Integer first() {
            if (isEmpty()) {
                return null;
            }
            return head.getElement();
        }
        public Integer last() {
            if(isEmpty()) {
                return null;
            }
            return tail.getElement();
        }
        public void addFirst(Integer i) {
            head = new Node<> (i, head);
            if(size == 0) {
                tail = head;
            }
            size++;
        }
        public void addLast(Integer i) {
            Node<Integer> newest = new Node<>(i,null);
            if(isEmpty()) {
                head = newest;
            }
            else {
                tail.setNext(newest);
            tail = newest;
            size++;
            }
        }
        public Integer removeFirst() {
            if(isEmpty()) {
                return null;
                }
            Integer answer = head.getElement();
            head = head.getNext();
            size--;
            if(size == 0) {
                tail = null;
            }
            return answer;
        }
        public void getPenultimate() {

            if(isEmpty()) {
                System.out.println("List is empty. Please check.");
            }
            else {
                System.out.println("The second last node is: " + head.penultimate(head));
            }

        }

【问题讨论】:

  • 我认为penultimate不应该在Node类中实现。因为这是来自孔列表而不是来自单个节点。所以理想情况下它应该在SinglyLinkedList 类中
  • 啊,我明白你的意思了!

标签: java list singly-linked-list


【解决方案1】:

删除字段penultimate。你不希望它在每个节点中,实际上没有节点,而是计算出来的。

在Node的倒数第二个方法中head不应该在循环中使用。

//private Node<Integer> penultimate;

// head: ...#->#->#->P->null
public Node<Integer> penultimate(Node<Integer> head) {
    Node<Integer> penultimate = null;
    Node<Integer> current = head;
    while (current != null) {
        if (current.getNext() == null) {
            penultimate = current;
            break;
        }
        current = current.getNext();
    }
    return penultimate;
}

或倒数第三个(第二个?)节点:

// head: ...#->#->#->P->#->null
public Node<Integer> penultimate(Node<Integer> head) {
    Node<Integer> penultimate = null;
    Node<Integer> current = head;
    while (current != null) {
        if (current.getNext() == null) {
            break;
        }
        penultimate = current;
        current = current.getNext();
    }
    return penultimate;
}

【讨论】:

  • 谢谢!但我有一个后续问题。在节点类中有倒数第二个方法可以吗?我想知道它是否仍会遍历整个列表?
  • 一般都可以,但不是public方法,是需要列表的head的内部方法。
  • 所以:列表中有一个公共方法,但它可能会调用节点类中的方法。
  • 所以你的意思是我应该在SinglyLinkedList类中声明一个公共方法(getPenultimate方法),然后从Node类调用一个私有方法(在这种情况下,倒数第二个方法)?非常感谢您的宝贵时间,顺便说一句!
【解决方案2】:

为什么不跟踪倒数第二个节点?

private Node<Integer> head = null;
private Node<Integer> tail = null;
private Node<Integer> secondToLast = null;
private int size = 0;

public SinglyLinkedList() {}

public int size() {
    return size;
}
public boolean isEmpty() {
    return size == 0;
}
public Integer first() {
    if (isEmpty()) {
        return null;
    }
    return head.getElement();
}
public Integer last() {
    if(isEmpty()) {
        return null;
    }
    return tail.getElement();
}
public void addFirst(Integer i) {
    if (size == 1) {
        secondToLast = head;
    }
    head = new Node<> (i, head);
    if(size == 0) {
        tail = head;
    }
    size++;
}
public void addLast(Integer i) {
    Node<Integer> newest = new Node<>(i,null);
    if(isEmpty()) {
        head = newest;
    }
    else {
        tail.setNext(newest);
        secondToLast = tail;
    }
    tail = newest;
    size++;

}
public Integer removeFirst() {
    if(isEmpty()) {
        return null;
        }
    Integer answer = head.getElement();
    head = head.getNext();
    size--;
    if(size == 0) {
        tail = null;
    }
    if (size == 1) {
        secondToLast = null;
    }
    return answer;
}
public void getPenultimate() {

    if(isEmpty()) {
        System.out.println("List is empty. Please check.");
    }
    else {
        System.out.println("The second last node is: " + secondToLast);
    }

}

【讨论】:

    猜你喜欢
    • 2011-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多