简体   繁体   English

从链接列表的末尾删除项目

[英]Remove items from the end of a linked list

I have the following implementation of a LinkedList. 我具有LinkedList的以下实现。

package assignment10;
// A linked list is a sequence of nodes with efficient
// element insertion and removal.
// This class contains a subset of the methods of the
// standard java.util.LinkedList class.

import java.util.NoSuchElementException;

public class LinkedList {

    //nested class to represent a node
    private class Node {

        public Object data;
        public Node next;
    }

    //only instance variable that points to the first node.
    private Node first;

    // Constructs an empty linked list.
    public LinkedList() {
        first = null;
    }

    // Returns the first element in the linked list.
    public Object getFirst() {
        if (first == null) {
            NoSuchElementException ex
                    = new NoSuchElementException();
            throw ex;
        } else {
            return first.data;
        }
    }

    // Removes the first element in the linked list.
    public Object removeFirst() {
        if (first == null) {
            NoSuchElementException ex = new NoSuchElementException();
            throw ex;
        } else {
            Object element = first.data;
            first = first.next;  //change the reference since it's removed.
            return element;
        }
    }

    // Adds an element to the front of the linked list.
    public void addFirst(Object element) {
        //create a new node
        Node newNode = new Node();
        newNode.data = element;
        newNode.next = first;
        //change the first reference to the new node.
        first = newNode;
    }

    // Returns an iterator for iterating through this list.
    public ListIterator listIterator() {
        return new LinkedListIterator();
    }

    /**
     * *******************************************************
     * Add your methods here
     * *******************************************************
     */
    public String toString() {
        String string;
        if (size() == 0) {
            string = "{ }";
        } else {
            string = "{ ";
            StringBuilder sb = new StringBuilder();
            ListIterator iterator = listIterator();
            while (iterator.hasNext()) {
                sb.append(String.valueOf(iterator.next())).append(" ");
            }
            sb.append("}");
            string = string.concat(sb.toString());
        }

        return string;
    }

    public int size() {
//          int size=0;
//          while(this.listIterator().hasNext()){
//              this.listIterator().next();
//              size++;
//          }
//          return size;
        int size = 0;
        ListIterator iterator = listIterator();
        while (iterator.hasNext()) {
            iterator.next();
            size++;
        }

        return size;
    }

    public void addElementAt(Object element, int index) {
        ListIterator listIterator = this.listIterator();
        int size = size();
        if (size == 0) {
            this.listIterator().add(element);
        } else {
            int i= 0;
            while(i<index-1){
                listIterator.next();
            }
            listIterator.add(element);
//            Node _head = new Node();
//            Node node = new Node();
//            node.data = element;
//            int ix = index - 1;
//            node.next = _head;
//
//            Node previous = _head;
//
//            for (int i = size - 1; i > ix; --i) {
//                previous = previous.next;
//            }
//
//            Node position = previous.next;
//
//            previous.next = node;
//            node.next = position;
//            ++size;
        }
    }

    public void addFewAtEnd(Object element, int howMany) {
        ListIterator listIterator = this.listIterator();
        int i=0;
        while(i<howMany){
           listIterator.add(element);
        }
    }

    public void removeLastFew(int howMany) {
        ListIterator listIterator = this.listIterator();
        int size = size();
        int i=0;
        if(howMany>0){
            if(howMany<size){
                while(i<size){
                    listIterator.next();
                }
                for(int removed=0;removed<howMany;removed++){
                    listIterator.remove();
                    listIterator.next();
                }
            } else {
                while(i<size){
                    listIterator.next();
                }
                for(int removed=0;removed<size;removed++){
                    listIterator.remove();
                    listIterator.next();
                }
            }
        }
    }

    public void removeAllOccurrences(Object stringToBeRemoved) {
         ListIterator listIterator = this.listIterator();
         while(listIterator.hasNext()){
             if(String.valueOf(listIterator.next()).equalsIgnoreCase(stringToBeRemoved.toString())){
                 listIterator.next();
             } else {
                 listIterator.next();
             }

         }
    }

    public void reverseLastFew(int howMany) {
        ListIterator listIterator = this.listIterator();
        int size = size();
        int i=0;
        if(howMany>0){
            if(howMany<size){
                LinkedList linkedList = new LinkedList();
                while(this.listIterator().hasNext()){
                    listIterator.next();
                }
                int count=0;
                while(count<howMany){
                    linkedList.listIterator().add(listIterator.next());
                    listIterator().remove();
                    listIterator.next();
                }

            } else {
                LinkedList linkedList = new LinkedList();
                 int count=0;
                while(count<size){
                    linkedList.listIterator().add(listIterator.next());
                    listIterator().remove();
                    listIterator.next();
                }
                count = 0;
                while(linkedList.listIterator().hasNext()){
                    if(count==0){
                        this.addFirst(linkedList.first);
                    } else {
                        this.addElementAt(linkedList.listIterator().next(), count);
                    }
                }
            }
        }
    }

    //nested class to define its iterator
    private class LinkedListIterator implements ListIterator {

        private Node position; //current position
        private Node previous; //it is used for remove() method

        // Constructs an iterator that points to the front
        // of the linked list.
        public LinkedListIterator() {
            position = null;
            previous = null;
        }

        // Tests if there is an element after the iterator position.
        public boolean hasNext() {
            if (position == null) //not traversed yet
            {
                if (first != null) {
                    return true;
                } else {
                    return false;
                }
            } else {
                if (position.next != null) {
                    return true;
                } else {
                    return false;
                }
            }
        }

        // Moves the iterator past the next element, and returns
        // the traversed element's data.
        public Object next() {
            if (!hasNext()) {
                NoSuchElementException ex = new NoSuchElementException();
                throw ex;
            } else {
                previous = position; // Remember for remove

                if (position == null) {
                    position = first;
                } else {
                    position = position.next;
                }

                return position.data;
            }
        }

        // Adds an element before the iterator position
        // and moves the iterator past the inserted element.
        public void add(Object element) {
            if (position == null) //never traversed yet
            {
                addFirst(element);
                position = first;
            } else {
                //making a new node to add
                Node newNode = new Node();
                newNode.data = element;
                newNode.next = position.next;
                //change the link to insert the new node
                position.next = newNode;
                //move the position forward to the new node
                position = newNode;
            }
            //this means that we cannot call remove() right after add()
            previous = position;
        }

        // Removes the last traversed element. This method may
        // only be called after a call to the next() method.
        public void remove() {
            if (previous == position) //not after next() is called
            {
                IllegalStateException ex = new IllegalStateException();
                throw ex;
            } else {
                if (position == first) {
                    removeFirst();
                } else {
                    previous.next = position.next; //removing
                }
                //stepping back
                //this also means that remove() cannot be called twice in a row.
                position = previous;
            }
        }

        // Sets the last traversed element to a different value.
        public void set(Object element) {
            if (position == null) {
                NoSuchElementException ex = new NoSuchElementException();
                throw ex;
            } else {
                position.data = element;
            }
        }

    } //end of LinkedListIterator class
} //end of LinkedList class

And

package assignment10;
// The ListIterator interface allows access of a position in a linked list.
// This interface contains a subset of the methods of the
//  standard java.util.ListIterator interface. The methods for
//  backward traversal are not included.

public interface ListIterator
{
   //Move Moves the iterator past the next element.
   Object next();

   // Tests if there is an element after the iterator position.
   boolean hasNext();

   // Adds an element before the iterator position
   // and moves the iterator past the inserted element.
   void add(Object element);


   // Removes the last traversed element. This method may
   // only be called after a call to the next() method.
   void remove();

   // Sets the last traversed element to a different value.
   void set(Object element);
}

The method removeLastFew() is supposed to remove the specified number of items from the LinkedList at the end. 方法removeLastFew()应该从末尾的LinkedList中删除指定数量的项目。 How can I achieve this? 我该如何实现? At the moment, the method is not working. 目前,该方法无效。

You have a few options here. 您在这里有一些选择。

Option 1: 选项1:

This is the ugly and slow but easy. 这是丑陋且缓慢但容易的。

Create a removeLast() and call it as many times as needed. 创建一个removeLast()并根据需要多次调用它。

Of course, if you need this for a serious production, it will be too slow (but I doubt that, given the -non existent- complexity of the question). 当然,如果您需要用它来进行认真的生产,那将会太慢(但是,鉴于问题的“不存在”的复杂性,我对此表示怀疑)。 And if it is for an assignment and I were your professor you would most likely fail that one. 如果是为了一项任务,而我是你的教授,那么您很可能会失败。

I guess you can do that by yourself. 我想你可以自己做。

Option 2: 选项2:

This might be the most efficient, and it's not hard either (but it's not really elegant either). 这可能是最有效的,也不难(但也不是很优雅)。

For every element node on the list, just check if n th element (being n the number of elements you want to erase) since node is null. 对于列表中的每个元素node ,只需检查第n个元素(要删除的元素数为n),因为node为空。 If that is the case, set to null the reference to node (you have to store the previous Node, yes). 如果是这种情况,请将对node的引用设置为null(必须存储以前的Node,是的)。

If you need to do it with the "remove" function, just use a simple loop once you have found the element described above. 如果您需要使用“删除”功能来完成此操作,找到上述元素后,只需使用一个简单的循环即可。

Option 3: (recursive). 选项3 :(递归)。

This one is the one I like the most, but I have always been a big fan of recursion. 这个是我最喜欢的一个,但是我一直是递归的忠实粉丝。

Create a function that goes all the way to the end, and then starts erasing. 创建一个功能,直到最后,然后开始擦除。

Simple example (you will have to adapt it to your code, of course): 一个简单的例子(当然,您必须将其适应您的代码):

private int removeLast (int n, Node node) {
    int remaining = n;

    if (node.next != null) {
        remaining = removeLast (n, node.next);
    }

    if (remaining > 0) {
        remove(node);
        remaining--;
    }

    return remaining;
}

NOTE: I'm not sure if this would work, jsut made it from the top of my head, and didn't test it, just a pseudocode in case you want to do it this way (recommended Opt 2). 注意:我不确定这是否行得通,jsut是从我的头顶上制作出来的,并且没有测试它,只是一个伪代码,以防万一您想这样做(建议选项2)。

I see probably bug here: 我可能在这里看到错误:

while(i<size) {
    listIterator.next();
}

there is missing increment of i. i缺少增量。 And fix the condition something like this: 并修复这种情况:

i < (size-howMany)

Also when deleting item, you must firstly save the value from "next". 同样,在删除项目时,必须首先保存“ next”中的值。

a simple way 一种简单的方法

add a length property in your LinkedList then when you need to delete n nodes, go to the "length-n th" Node (some getNext()s in a while loop) and delete the rest! LinkedList添加一个length属性,然后当您需要删除n个节点时,转到“ length-n th”节点(while循环中的一些getNext()s)并删除其余的!

don't forget to keep length valid 别忘了保持长度有效

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM