简体   繁体   English

从概念上理解此链接列表代码时遇到麻烦

[英]Having trouble conceptually understanding this Linked List code

I am having some trouble understanding why the function delete() below works for deleting a node in a linked list. 我在理解为什么下面的delete()函数可用于删除链表中的节点时有些麻烦。 I abridged the rest of the code to make this all easier to read. 我删节了其余代码,以使所有内容都易于阅读。

So, I understand we have a node first with a bunch of nodes linked to first . 因此,我了解我们first拥有一个节点,并且有许多节点链接到first I also understand that in the delete() function, we need to create a new node n to traverse the list. 我也了解在delete()函数中,我们需要创建一个新节点n来遍历列表。 Here's my hang up: 这是我的挂断电话:

If we create a new node n , and set n = first , we've created a new node, and the node constructor defines that n will have a new node n.next as well. 如果我们创建一个新节点n并设置n = first ,那么我们创建了一个新节点,并且节点构造函数定义n也将有一个新节点n.next So, haven't we created a whole new list, separate from the list that begins with first ? 因此,我们是否创建了一个与first开头的列表分开的全新列表? When the delete() function gets to the point where it sets n.next = n.next.next , isn't that deleting a node in a whole separate list of n nodes? delete()函数达到设置n.next = n.next.next ,难道不是要删除一个单独的n节点列表中的一个节点吗? How does this delete the node that is linked off of first ? 这如何删除first链接的节点? Conceptually, this is my hang up. 从概念上讲,这是我的挂断电话。

How are we actually deleting the node in the list that begins with first ? 我们实际上如何删除以first开头的列表中的节点?

Edit: I think maybe I answered my own question but I was hoping someone could verify. 编辑:我想也许我回答了我自己的问题,但我希望有人可以验证。 Does this work because both the first and n nodes are actually just references back to the New Node() object created in the Add() function? 这是否可行,因为第first和第n节点实际上只是对Add()函数中创建的New Node()对象的引用? When I learned programming it was with C++ so I'm used to seeing pointers, and this code didn't make much sense; 当我学习编程时,它是使用C ++编写的,因此我习惯于查看指针,而这段代码并没有多大意义。 but as I understand it Java doesn't explicitly have pointers... so am I correct about all of this? 但是据我了解,Java没有显式的指针...所以我对所有这些都正确吗?

public class LinkedList {
    static class Node {
        public Node() { }
        public double item;
        public Node next;
    }

    int N;
    Node first;

    public LinkedList () {
        first = null;
        N = 0;

    public void delete (int k) {
        if (k == 0) {
            first = first.next;
            N--;
        }

        else {
            Node n = first;
            for (int i = 0; i < k-1; i++) {
                n = n.next;
            }
            n.next = n.next.next;
            N--;
        }
    }

    public void add (double item) {
        Node newfirst = new Node ();
        newfirst.item = item;
        newfirst.next = first;
        first = newfirst;
        N++;
    }

    private static void testDelete () {
        MyLinked b = new MyLinked ();
        b.add (1);
        print ("singleton", b);
        b.delete (0);
        print ("deleted", b);
        for (double i = 1; i < 13; i++) {
            b.add (i);
        }
        print ("bigger list", b);
        b.delete (0);
        print ("deleted at beginning", b);
        b.delete (10);
        print ("deleted at end", b);
        b.delete (4);
        print ("deleted in middle", b);
    }

    public static void main (String args[]) {    
        testDelete();
    }

}

This is because each linked list node simply contains a reference to your object and a reference to the next node. 这是因为每个链接列表节点仅包含对您的对象的引用和对下一个节点的引用。 In order to delete a node, you simply need to make the previous node point to the one after it. 为了删除一个节点,您只需要使前一个节点指向其后的节点即可。

ie. 即。 Initial list: 初始清单:

linkedList
  ↓
node0 -> node1 -> node2 -> node3

1) If you then were to remove node1 , then it'd look like this 1)如果要删除node1 ,则它看起来像这样

linkedList
  ↓
node0 ----------> node2 -> node3
         node1 ----↑

node0 would no longer point to node1 , so if you tried to iterate from node0 you'd go to node2 next. node0将不再指向node1 ,因此,如果您尝试从node0进行迭代,则node0将转到node2 However, node1 would still "point" to node2 (until it's garbage collected of course). 但是, node1仍将“指向” node2 (当然,直到收集到垃圾为止)。

2) If you instead removed node0 , it look like this: 2)如果您删除了node0 ,则它看起来像这样:

       linkedList
           ↓
node0 -> node1 -> node2 -> node3

You simply move the first field of the LinkedList to point to node1 and so, if you were to do linkedList.first you'd be accessing node1 . 您只需将LinkedListfirst字段移至指向node1 ,因此,如果要执行linkedList.first ,则将访问node1 node0 however will eventually get garbage collected because nothing references it (unless you do that somewhere else). 但是, node0最终将被垃圾回收,因为没有东西引用它(除非您在其他地方这样做)。

Keep in mind that these cases are true for a singly-linked LinkedList. 请记住,这些情况对于单链接的LinkedList都是正确的。 If you had a doubly-linked LinkedList then, the detaching and reattaching becomes a bit more complicated. 如果您有一个双向链接的LinkedList,则分离和重新附加会变得更加复杂。

-- -

I think you have a misunderstanding of what "delete" does. 我认为您对“删除”的功能有误解。 In Java, users don't manually manage memory, so you don't call malloc or delete , destroy , etc. You simply remove all references to the object and they will eventually get garbage collected by the JVM. 在Java中,用户不会手动管理内存,因此您不会调用mallocdeletedestroy等。您只需删除对对象的所有引用,它们最终将被JVM收集。

In the above code, we're simply talking about "deleting" a Node from a LinkedList in terms of data structures. 在上面的代码中,我们只是在谈论根据数据结构从LinkedList中“删除”一个Node

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

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