如何在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(); }

如何从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();
        }
        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));