如何在Java中从链表中删除特定值?
如何从java链表中删除特定值?如何在Java中从链表中删除特定值?,java,algorithm,linked-list,Java,Algorithm,Linked List,如何从java链表中删除特定值? 我试图在我的实现中实现它,但这并不容易 以下是我想做的: //How to do this...;<.. int remove(Item item) { Node cur = first.next; Node prev = first; while (cur !=null) { if (cur.item.equals(item)) { item = dequeue(); }
我试图在我的实现中实现它,但这并不容易 以下是我想做的:
//How to do this...;<..
int remove(Item item) {
Node cur = first.next;
Node prev = first;
while (cur !=null) {
if (cur.item.equals(item)) {
item = dequeue();
}
cur = cur.next;
// TODO
}
return 0;
}
//怎么做 在if语句中,您正在检查cur
节点是否等于传入的项:if(cur.equals(Item))
我认为您应该检查存储在cur
节点中的项是否等于传递到您的函数中的项:如果(cur.Item.equals(Item))
根据问题的细节,我假设您对Java相当陌生。
你的要求和你展示的细节完全不同
LinkedQueue q=新建LinkedQueue()代码>
仅当LinkedQueue是genreic类而不是特定的impl for Item类型类时才适用。i、 e您没有创建LinkedQueue
类的对象<代码>链接队列和链接队列
不同
cur.equals(item)
缺乏平等契约的知识,以及==vs equal
的差异。i、 你在比较两个完全不同的物体。一个是节点,另一个是项目类对象
建议:清晰的基础知识,阅读cathy Sierra的书。Scjp Sun认证的Java 6程序员
至于答案,您实际上并没有从main调用remove(通过打印测试它)
删除方法中的语句)。这就是为什么你总是得到相同的答案
注意:即使我们告诉您,您也无法消化真正的解决方案。下面的代码片段包含各种remove()
方法,这些方法取自我的LinkedList
实现之一,用Java
编写
代码
LinkedList.java(部分)
所有测试用例都将通过
解释
方法:
T删除(int k)
,按索引删除
步骤:
*循环到目标节点,
*对于每一步,
记录:
*前一个节点,
*这个节点,,
*获取目标节点的下一个节点,
*获取目标节点的值,
作为以后的返回值,
*如果目标是结束,
*如果也是头,,
head=null;
*如果不是头部,
preNode.next=null;
*端=前极;
*如果targe没有结束,
将其替换为下一个节点,
逻辑:
*node.value=nextNode.value;
*node.next=nextNode.next;
*返回以前跟踪的目标节点值,
布尔删除值(tV)
,按值删除,仅删除第一个匹配项(如果有)。
逻辑类似于按索引删除。
区别在于:
- 在初始搜索时,将元素而不是循环与索引进行比较,以找到目标
- 返回布尔值,指示是否删除,而不是删除值
int removeAllValue(tv)
,按值删除所有内容,删除所有出现的内容。
这类似于按值删除
差异:
- [内部while()]
- 它将搜索所有事件直到结束
- 删除事件后,将“继续”重新检查当前节点。
因为当前节点已实际替换为其下一个节点
- 如果删除的节点已结束,则返回。
此继电器的返回值为removeNode()
- 它记录已删除事件的计数
- [返回值]
- 它返回已删除事件的计数,而不是布尔值
布尔删除节点(LinkedListNode节点,LinkedListNode前节点)
,按节点删除,且前节点已给定。
删除保证存在的给定节点,并删除给定的前一个节点,该节点可能为空。
返回值表示删除的节点是否为end,主要用于支持removeAllValue()
T removeed()
,T removeEnd()
,移除头部/末端。
只需调用remove by index,并传递相应的索引0
和size-1
提示:
LinkedList
表示LinkedList,带有字段size
、head
、end
、泛型类型T
(对于节点中的值类型),它不是线程安全的
checkElementIndex()
方法,检查给定的索引,如果超出范围则抛出异常
LinkedListNode
,表示链接列表中的节点。带有字段值
,下一步
复杂性
- 删除单个:
O(k)
- 按值删除所有内容:
O(n)
其中:
k
,是目标的索引
n
,是linkedlist的大小
自Java 8以来,存在
removeIf(谓词prev.next=cur.next;
对我来说似乎也没有多大意义。prev始终是中的最后一个,而loop我改变了问题。
public class LinkedQueue<Item> implements Iterable<Item> {
private int N; // number of elements on queue
private Node first; // beginning of queue
private Node last; // end of queue
// helper linked list class
private class Node {
private Item item;
private Node next;
}
/**
* Initializes an empty queue.
*/
public LinkedQueue() {
first = null;
last = null;
N = 0;
assert check();
}
public Item dequeue() {
if (isEmpty()) throw new NoSuchElementException("Queue
underflow");
Item item = first.item;
first = first.next;
N--;
if (isEmpty()) last = null; // to avoid loitering
assert check();
return item;
}
public static void main(String[] args) {
LinkedQueue<String> q = new LinkedQueue<String>();
q.enqueue("a");
q.enqueue("b");
q.enqueue("c");
q.enqueue("a");
q.enqueue("b");
q.enqueue("d");
q.enqueue("b");
q.enqueue("abba");
q.enqueue("a");
q.enqueue("z");
q.enqueue("a");
System.out.println(q);
System.out.println("Remove some of elements.");
q.remove("a");
q.remove("f");
q.remove("c");
System.out.println(q);
}
}
a b c a b d b abba a z a
Remove some of elements.
a b d b abba a z a
private int size; // node count,
private LinkedListNode<T> head; // first node,
private LinkedListNode<T> end; // last node,
/**
* Remove by index.
*
* @param k index, start from 0,
* @return value of removed node, or null if not removed,
*/
@Override
public T remove(int k) {
checkElementIndex(k);
// find target node, and remember previous node,
LinkedListNode<T> preNode = null;
LinkedListNode<T> node = head;
while (k-- > 0) {
preNode = node;
node = node.next;
}
T result = (T) node.value; // keep return value,
removeNode(node, preNode); // remove
return result;
}
/**
* Remove by value, only remove the first occurrence, if any.
*
* @param v
* @return whether removed,
*/
@Override
public boolean removeValue(T v) {
// find target node, and remember previous node,
LinkedListNode<T> preNode = null;
LinkedListNode<T> node = head;
while (true) {
if (node == null) return false;// not found,
if (node.getValue().compareTo(v) == 0) break; // value found,
preNode = node;
node = node.next;
}
removeNode(node, preNode); // remove
return true;
}
/**
* Remove by value, remove all occurrences.
*
* @param v
* @return count of nodes removed,
*/
@Override
public int removeAllValue(T v) {
int rc = 0;
// find target node, and remember previous node,
LinkedListNode<T> preNode = null;
LinkedListNode<T> node = head;
while (true) {
if (node == null) return rc; // reach end,
if (node.getValue().compareTo(v) == 0) { // value found,
rc++;
if (removeNode(node, preNode)) break; // remove, break if it's end,
continue; // recheck this node, since it become the next node,
}
preNode = node;
node = node.next;
}
return rc;
}
/**
* Remove given node, which guarantee to exists. Also reduce the size by 1.
*
* @param node node to delete,
* @param preNode previous node, could be null,
* @return indicate whether removed node is end,
*/
protected boolean removeNode(LinkedListNode node, LinkedListNode preNode) {
LinkedListNode nextNode = node.next; // next node,
boolean isEnd = (nextNode == null);
if (isEnd) { // target is end,
if (preNode == null) { // target is also head,
head = null;
} else { // target is not head, thus preNode is not null,
preNode.next = null;
}
end = preNode;
} else { // target is not end,
// replace target with next node,
node.next = nextNode.next;
node.value = nextNode.value;
}
size--; // reduce size by 1,
return isEnd;
}
/**
* Remove head node,
*
* @return
*/
@Override
public T removeHead() {
return remove(0);
}
/**
* Remove end node,
*
* @return
*/
@Override
public T removeEnd() {
return remove(size - 1);
}
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
/**
* LinkedList test.
*
* @author eric
* @date 1/28/19 6:03 PM
*/
public class LinkedListTest {
private int n = 10;
private LinkedList<Integer> llist; // linked list,
private LinkedList<Integer> dupEvenLlist; // linked list, with duplicated even values,
@BeforeMethod
public void init() {
// init llist,
llist = new LinkedList(); // create linked list,
Assert.assertTrue(llist.isEmpty());
LinkedList.appendRangeNum(llist, 0, n); // append range,
// init dupEvenLlist,
dupEvenLlist = new LinkedList(); // create linked list,
LinkedList.appendRangeNum(dupEvenLlist, 0, n); // append range,
LinkedList.appendRangeNum(dupEvenLlist, 0, n, 2); // append range, again, with step as 2 (only even numbers),
Assert.assertEquals(dupEvenLlist.size(), n + n / 2);
}
// non-remove related test cases ... are deleted,
// remove(k) - remove by index,
@Test
public void testRemoveByIndex() {
for (int i = 0; i < n; i++) {
Assert.assertEquals(llist.removeEnd().intValue(), n - 1 - i); // remove by end, in turn it remove by index,
Assert.assertEquals(llist.size(), n - 1 - i);
}
Assert.assertTrue(llist.isEmpty());
}
// remove(v) - remove by value,
@Test
public void testRemoveByValue() {
Assert.assertFalse(llist.removeValue(n)); // not exists,
for (int i = n - 1; i >= 0; i--) {
Assert.assertTrue(llist.removeValue(i)); // remove by value,
Assert.assertEquals(llist.size(), i);
}
Assert.assertTrue(llist.isEmpty());
Assert.assertFalse(llist.removeValue(0)); // empty,
// remove from list with duplicated value,
for (int i = 0; i < n; i++) {
Assert.assertTrue(dupEvenLlist.removeValue(i));
}
Assert.assertFalse(dupEvenLlist.isEmpty());
Assert.assertEquals(dupEvenLlist.size(), n / 2);
}
// removeAll(v) - remove all occurrences by value,
@Test
public void testRemoveAllByValue() {
Assert.assertEquals(dupEvenLlist.removeAllValue(n), 0); // not exists,
int remainSize = dupEvenLlist.size();
for (int i = 0; i < n; i++) {
int rc = dupEvenLlist.removeAllValue(i); // remove all by value,
Assert.assertEquals(rc, i % 2 == 0 ? 2 : 1);
remainSize -= rc;
Assert.assertEquals(dupEvenLlist.size(), remainSize);
}
Assert.assertTrue(dupEvenLlist.isEmpty());
Assert.assertEquals(dupEvenLlist.removeAllValue(0), 0); // empty,
}
}
Steps:
* loop to target node,
* for each step,
record:
* previous node,
* this node,
* get next node, of target node,
* get value of target node,
as return value later,
* if target is end,
* if also head,
head = null;
* if not head,
preNode.next = null;
* end = preNode;
* if targe is not end,
replace it with its next node,
logic:
* node.value = nextNode.value;
* node.next = nextNode.next;
* return previously tracked value of target node,
list.removeIf(cur -> cur.item.equals(item));