Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 删除linkedlist中元素的所有引用_Java_Linked List_Implementation - Fatal编程技术网

Java 删除linkedlist中元素的所有引用

Java 删除linkedlist中元素的所有引用,java,linked-list,implementation,Java,Linked List,Implementation,为了理解数据结构,我开始用java实现它们。deleteAll的时间复杂度将是O(n+n^2)。如何改进deleteAll方法 /* * Singly linked list */ package linkedlisttest; class Node { int data; Node next; public Node(int data) { this.data = data; } } class LinkedList {

为了理解数据结构,我开始用java实现它们。
deleteAll
的时间复杂度将是
O(n+n^2)
。如何改进
deleteAll
方法

/*
 * Singly linked list
 */
package linkedlisttest;

class Node {

    int data;
    Node next;

    public Node(int data) {
        this.data = data;
    }

}

class LinkedList {

    Node head;
    int size;

    /**
     *
     * @param data element to add to list 
     * Time Complexity : O(n)
     */
    public void add(int data) {
        if (head == null) {
            head = new Node(data);
            size += 1;
            return;
        }

        Node current = head;
        while (current.next != null) {
            current = current.next;
        }
        current.next = new Node(data);
        size += 1;
    }

    /**
     *
     * @return size of list 
     * Time Complexity: O(1) 
     * This is because we use a class
     * variable size to keep track of size of linked list
     */
    public int getSize() {
        return size;
    }
    /**
     * 
     * @param data element to insert 
     * @param index position at which to insert the element (zero based)
     * Time Complexity : O(n)
     */
    public void add(int data, int index) {

        if (index > getSize()) {
            return; // invalid position
        }

        Node current = head; //iterate through whole list 
        int pos = 0;
        Node newNode = new Node(data);

        if (index == 0) // special case, since its a single reference change!
        {
            newNode.next = head;
            head = newNode; // this node is now the head
            size += 1;
            return;
        }
        while (current.next != null) {
            if (pos == index - 1) {
                break;
            }
            pos++;
            current = current.next;
        }
        // These are 2 reference changes, as compared to adding at index 0
        newNode.next = current.next; // here we are changing a refernce
        current.next = newNode; // changing a reference here as well
        size += 1;

    }
    /**
     * Find the first occurrence of an element  
     * @param data element to find
     * @return index at which element is found , -1 if not exist
     * Time Complexity: O(n)
     */
    public int find(int data) {
        Node current = head;
        int pos = 0;
        int index = -1;
        if(head == null) { //empty list
            return index;
        }
        while(current != null) {
            if (current.data == data) {
                index = pos;
                break;
            }
            pos++;
            current = current.next;
        }
        return index;
    }

    /**
     * Delete the first occurrence of data 
     * @param data element to delete 
     * Time complexity : O(n)
     */
    public void delete(int data) {
        Node current = head;
        if (head == null) { // list is empty
            return;
        }
        if(head.data == data) { // if we want to delete the head , make next node head
            head = head.next;
            size -= 1;
            return;
        }
        while(current.next != null) {
            if (current.next.data == data) {
                current.next = current.next.next;
                size -= 1;
                return;
            }
            current = current.next;
        }
    }

    /**
     * Delete all occurrences of data 
     * @param data element to delete 
     * 
     */
    public void deleteAll(int data) {
        Node current = head;
        if (head == null) { // list is empty
            return;
        }
        //while loop to delete consecutive occurances of data
        while(head.data == data) { // if we want to delete the head , make next node head
            head = head.next;
            size -= 1;
        }
        while(current.next != null) {
            //while loop to delete consecutive occurances of data
            while (current.next.data == data) { 
                current.next = current.next.next;
                size -= 1;
            }
            current = current.next;
        }
    }

    public void reverse() {

    }



    /**
     * Prints the whole linked list 
     * Time Complexity : O(n)
     */
    public void print() {

        if(head == null) { //list is empty
            return;
        }
        Node current = head;
        while (current.next != null) {
            System.out.print(current.data + "->");
            current = current.next;
        }
        System.out.print(current.data + "\n"); 
    }
}

public class LinkedListTest {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        LinkedList lt = new LinkedList();
        lt.print();
        lt.add(3);
        lt.add(5);
        lt.add(6);
        lt.print();
        lt.add(4, 1);
        lt.print();
        lt.add(4, 7);// 7 is an invalid index
        lt.add(8, 3);
        lt.add(8, 4);
        lt.print();
        System.out.println("Position : " + lt.find(8));
        lt.delete(5);
        lt.print();
        lt.deleteAll(8);
        lt.print();
        System.out.println("Size : " + lt.getSize());
    }

}

请注意,Java中的所有内容都是引用,但这些基本类型除外。因此,
当前的
仍然停留在原始的
头部

没有必要将连续发生的事件视为特殊情况。使用
O(n)
-线性复杂度在链表中进行简单的迭代和判断将完全满足您的要求

此外,嵌套循环并不一定意味着它一定要花费O(n^2)。如果每次移动
current
,它仍然会在线性时间内遍历链表


另一个个人建议:如果在处理链表时需要编写类似node.next.next的东西,那么是时候设置另一个引用或重构代码了。

实现的时间复杂性是
O(n)
,而不是您认为的
O(n+n^2)
。 尽管嵌套循环是O(n^2)的常见符号,但情况并非总是如此。 重要的一点是迭代次数。 就你而言, 如果在嵌套循环中执行
k
步骤, 这将外部循环中的剩余步骤减少
k
。 总的来说, 您仍将采取
n
步骤以达到目的

但是您的实现有一些bug, 还可以改进:

  • 错误:您分配了
    current=head
    ,但是如果
    head.data==data
    ,它将被删除,并且
    current
    仍将指向它
  • 不需要嵌套循环。在对头部进行特殊处理后,您可以简单地跟踪节点并删除匹配项
像这样:

public void deleteAll(int data) {
    while (head != null && head.data == data) {
        head = head.next;
        size -= 1;
    }

    if (head == null) {
        return;
    }

    Node current = head;
    while (current.next != null) {
        if (current.next.data == data) {
            current.next = current.next.next;
            size -= 1;
        } else {
            current = current.next;
        }
    }
}
顺便说一下,头部的特殊处理可能有点烦人。 一个优雅的替代方法是创建一个指向
头部的虚拟对象

public void deleteAll(int data) {
    Node dummy = new Node();
    dummy.next = head;

    Node current = dummy;
    while (current.next != null) {
        if (current.next.data == data) {
            current.next = current.next.next;
            size -= 1;
        } else {
            current = current.next;
        }
    }

    head = dummy.next;
}

如果此代码工作正常,那么此问题与堆栈溢出无关,但可能对我们的姐妹站点有好处。感谢全面的解释和代码示例。
}否则{current=current.next;}
是这里的关键,我早期的实现基于delete,它总是迭代到下一个节点