gpt4 book ai didi

java - 删除链表中所有出现的元素

转载 作者:行者123 更新时间:2023-11-30 02:27:33 26 4
gpt4 key购买 nike

为了理解数据结构,我开始用 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());
}

}

最佳答案

您的实现的时间复杂度是 O(n),而不是您认为的 O(n + n^2)。尽管嵌套循环是 O(n^2) 的常见标志,但情况并非总是如此。重要的一点是迭代次数。就你而言,如果您在嵌套循环中执行k步,这会将外循环中的剩余步骤减少 k。全面的,您仍需采取 n 步才能到达终点。

但是你的实现有一些错误,并且还可以改进:

  • 错误:您分配了 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;
}
}
}

顺便说一句,头部的特殊处理可能有点烦人。一个优雅的替代方案是创建一个指向 head 的虚拟对象:

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;
}

关于java - 删除链表中所有出现的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45253705/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com