简体   繁体   English

无法准确删除 LinkedList 中的节点

[英]Trouble with accurately removing Nodes in a LinkedList

I wrote the following class for building a LinkedList with single values on top of a given code template.我编写了以下 class 用于在给定代码模板之上构建具有单个值的 LinkedList。

. . . .

public class LinkedElement<T> {

    private T name;
    private LinkedElement<T> link;

    public LinkedElement(T value) {
        this.name = value;
    }

    /**
     * Returns the value of the i-th linked element, assuming the current element to
     * be at index 0.
     * 
     * @param i 0-based index of the element whose value to return.
     * @return the i-th element's value, or {@code null} if there is no element with
     *         that index.
     */
    public T get(int i) {
        int iterator = i;

        if (iterator == 0) {
            return this.name;
        }
        if (this.link == null) {
            iterator = 0;
            return null;
        }
        if (iterator > 0) {
            iterator = iterator - 1;
            return this.link.get(iterator);
        }

        return null;

    }

    /**
     * Adds a new linked element holding the given value at the end of the linked
     * elements.
     * 
     * @param newVal the new value.
     */
    public void add(T newVal) {
        if (this.link == null) {
            this.link = new LinkedElement(newVal);
        } else {
            this.link.add(newVal);
        }

    }

    **/**
     * Removes the i-th element from the linked elements. If {@code i == 0}, this
     * will effectively remove the head element. Thus, this method returns the
     * linked element that is the new head element.
     * 
     * @param i index of the element to remove.
     * @return the new head element.
     */
    public LinkedElement<T> remove(int i) {
        // Store i as changeable iterator
        int iterator = i;
        // Store current head element;
        LinkedElement<T> tempNode = this;
        // If head element itself is to be removed
        if (iterator == 0) {
            if (this.link != null) {
                this.name = this.link.name;
                this.link = this.link.link;
            }
            if (this.link == null) {
                this.name = null;
                this.link = null;
            }
            return this;
            // If the element is further down in the linkedlist
            // iterate through list and invoke "remove" at the desired position inside
            // the list
        }
        if (iterator > 0) {
            iterator = iterator - 1;
            return this.link.remove(iterator);
        }
        return null;**

    }

}

The "remove" method seems to work fine when I remove just one element and print the elements out one by one.当我只删除一个元素并逐个打印出这些元素时,“删除”方法似乎工作正常。 The trouble starts when I declare a new headElement through a remove method (which returns the new headElement in that respective list)当我通过 remove 方法声明一个新的 headElement 时,麻烦就开始了(它在相应的列表中返回新的 headElement)

public static void main(String[] args) {
    // An example
    LinkedElement<String> headElement = new LinkedElement<String>("Yo!");
    headElement.add("LA");
    headElement.add("is");
    headElement.add("about");
    headElement.add("to");
    headElement.add("witness");
    headElement.add("another");
    headElement.add("sunny");
    headElement.add("day!");

    System.out.println(headElement.get(7));          // prints "sunny"
    headElement = headElement.remove(6);  // removes "another"
    headElement = headElement.remove(0);  // removes "Yo!"
    System.out.println(headElement.get(0));          // prints "sunny"

}

The expected output should be:预期的 output 应该是:

  • sunny晴天
  • sunny晴天

but I get但我明白了

  • sunny晴天
  • null null

Question updated because I worded myself poorly.问题已更新,因为我措辞不佳。

because your headElement after remove(0) is:因为你在 remove(0) 之后的 headElement 是:

LinkedElement<String> headElement = new LinkedElement<String>("what's");//0
headElement.add("up!");//1
headElement.add("That's");//2
headElement.add("Mitch");//3
headElement.add("Jones!");//4

and then you remove(2) from result above: which is "That's";然后从上面的结果中删除(2):这是“那是”; //at index 2 so yo get: //在索引2,所以你得到:

LinkedElement<String> headElement = new LinkedElement<String>("what's");//0
headElement.add("up!");//1
headElement.add("Mitch");//2
headElement.add("Jones!");//3

Try to print after remove(0) and you can get what is happening!尝试在 remove(0) 之后打印,您可以了解发生了什么!

Try this:尝试这个:

public LinkedElement<T> remove(int i) {
        int iterator = i;
        // Store current head element;
        LinkedElement<T> tempNode = this;
        // If head element itself is to be removed
        if (iterator == 0) {
            if (tempNode.link != null) {
                tempNode.name = tempNode.link.name;
                tempNode.link = tempNode.link.link;
            }
            if (tempNode.link == null) {
                tempNode.name = null;
                tempNode.link = null;
            }
            return tempNode;
            // If the element is further down in the linkedlist
            // iterate through list and invoke "remove" at the desired position inside
            // the list
        }
        if (iterator > 0) {
            iterator = iterator - 2;
            return tempNode.link.remove(iterator);
        }
        return tempNode;
    }

Might try the following可以试试以下

public class LinkedElement<T> {

    private T value;

    private LinkedElement<T> linkToNextElement;

    public LinkedElement(T element) {
        value = element;
        linkToNextElement = null;

    }

    public static void main(String args[]) {
        LinkedElement<String> head = new LinkedElement("a");
        head.add("b");
        head.add("c");
        head.add("d");
        head.add("e");
        LinkedElement<String> newHead = head;
        for (int i = 0; i <= 6; i++) {
            System.out.println("list[" + i + "]=" + head.get(i));
        }
        System.out.println("Head: value="+newHead.value+"\n");
        
        System.out.println("###remove(1)###");
        newHead =  head.remove(1);
        for (int i = 0; i <= 6; i++) {
            System.out.println("list[" + i + "]=" + head.get(i));
        }
        System.out.println("Head: value="+newHead.value+"\n");
        
        System.out.println("###remove(3)###");
        newHead =head.remove(3);
        for (int i = 0; i <= 6; i++) {
            System.out.println("list[" + i + "]=" + head.get(i));
        }
        System.out.println("Head: value="+newHead.value+"\n");
        
        System.out.println("###remove(0)###");
        newHead =head.remove(0);
        for (int i = 0; i <= 6; i++) {
            System.out.println("list[" + i + "]=" + head.get(i));
        }
        System.out.println("Head: value="+newHead.value+"\n");
        
        System.out.println("###remove(0)###");
        newHead =head.remove(0);
        for (int i = 0; i <= 6; i++) {
            System.out.println("list[" + i + "]=" + head.get(i));
        }
        System.out.println("Head: value="+newHead.value+"\n");
        
        System.out.println("###remove(i)###");
        newHead =head.remove(7);
        for (int i = 0; i <= 6; i++) {
            System.out.println("list[" + i + "]=" + head.get(i));
        }
        System.out.println("Head: value="+newHead.value+"\n");
        
        System.out.println("###remove(0)###");
        newHead =head.remove(0);
        for (int i = 0; i <= 6; i++) {
            System.out.println("list[" + i + "]=" + head.get(i));
        }
        //empty List
        if(newHead == null)
        {
            System.out.println("Head: value= NULL : no value for emplty list" );
        }
    }

    /**
     * Returns the value of the i-th linked element, assuming the current element to
     * be at index 0.
     * 
     * @param i 0-based index of the element whose value to return.
     * @return the i-th element's value, or {@code null} if there is no element with
     *         that index.
     */
    public T get(int i) {
        int counter = 0;
        LinkedElement<T> currElement = this;
        if (i == 0) {
            return value;
        }
        while (counter < i) {
            if (currElement.linkToNextElement != null) {
                currElement = currElement.linkToNextElement;
            } else {
                return null;
            }
            counter++;
        }
        return currElement.value;
    }

    /**
     * Adds a new linked element holding the given value at the end of the linked
     * elements.
     * 
     * @param newVal the new value.
     */
    public void add(T newVal) {
        if (linkToNextElement == null) {
            linkToNextElement = new LinkedElement<T>(newVal);
        } else {
            linkToNextElement.add(newVal);
        }
    }

    /**
     * Removes the i-th element from the linked elements. If {@code i == 0}, this
     * will effectively remove the head element. Thus, this method returns the
     * linked element that is the new head element.
     * 
     * @param i index of the element to remove.
     * @return the new head element.
     */
    public LinkedElement<T> remove(int i) {
        int counter = 0;
        LinkedElement<T> currElement = this;
        LinkedElement<T> prevElement = null;
        LinkedElement<T> nextElement = null;
        if (i == 0) {
            if (currElement.linkToNextElement != null) {
                nextElement = currElement.linkToNextElement;
                value = nextElement.value;
                if (nextElement.linkToNextElement != null) {
                    linkToNextElement = nextElement.linkToNextElement;
                } else {
                    linkToNextElement = null;
                }
                // ;
                return nextElement;

            } else {
                value = null;
                linkToNextElement = null;

            }
            return linkToNextElement;
        }
        while (counter < i) {
            if (currElement.linkToNextElement != null) {
                prevElement = currElement;
                currElement = currElement.linkToNextElement;
            } else {
                return this;
            }
            counter++;
        }
        if (currElement.linkToNextElement != null) {
            nextElement = currElement.linkToNextElement;
            prevElement.linkToNextElement = nextElement;
        }
        // last element
        else {
            prevElement.linkToNextElement = null;

        }
        return this;
    }
}

Output Output

list[0]=a
list[1]=b
list[2]=c
list[3]=d
list[4]=e
list[5]=null
list[6]=null
Head: value=a

###remove(1)###
list[0]=a
list[1]=c
list[2]=d
list[3]=e
list[4]=null
list[5]=null
list[6]=null
Head: value=a

###remove(3)###
list[0]=a
list[1]=c
list[2]=d
list[3]=null
list[4]=null
list[5]=null
list[6]=null
Head: value=a

###remove(0)###
list[0]=c
list[1]=d
list[2]=null
list[3]=null
list[4]=null
list[5]=null
list[6]=null
Head: value=c

###remove(0)###
list[0]=d
list[1]=null
list[2]=null
list[3]=null
list[4]=null
list[5]=null
list[6]=null
Head: value=d

###remove(7)###
list[0]=d
list[1]=null
list[2]=null
list[3]=null
list[4]=null
list[5]=null
list[6]=null
Head: value=d

###remove(0)###
list[0]=null
list[1]=null
list[2]=null
list[3]=null
list[4]=null
list[5]=null
list[6]=null
Head: value= NULL : no value for empty list

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

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