C#内存分配和链接列表实现

时间:2018-10-01 09:23:09

标签: c# algorithm memory memory-management linked-list

我对C#如何实现链接列表类有一些疑问 第一个问题:

public class Node {  
    int data;  
    Node next;   
} 

它看起来像而不是链接列表,它是一个Big对象,内部具有递归相同的类

我的第二个问题是更具体的,针对如下所示的简单反向链表算法:

 public void ReverseList(ref ListNode head){
    if(head ==null || head.next == null) return head;
    ListNode cur = head;
    ListNode prev = null;
    ListNode next = head.next;
    while (cur != null){
        ListNode nextNode = head.next;
        cur.next= prev;
        prev=cur;
        cur=nextNode;
    }
    head = prev ;
} 

不是cur = head是指“ cur”复制所有链接列表元素吗? 而且很难考虑算法中发生了什么。

2 个答案:

答案 0 :(得分:6)

  

它看起来像而不是链接列表,它是一个Big对象,内部具有递归相同的类

Nodeclass,这意味着字段Node next;是引用(就术语而言,可以与指针广泛互换)。所以不:这绝对是一个链表。 Node包含一个Node。它包含一个字段,该字段是对另一个Node的引用(认为:指针)。

  

不是cur = head意味着“ cur”复制了所有链接列表元素吗?

它没有复制任何元素。它正在更改某些现有对象上的引用字段(认为:指针),而就这样。不能复制。但是,这是访问所有元素并更改所有元素上的指针-因此,如果您算上“在所有元素上复制引用(认为:指针)”:当然,它就是这样做的。没有任何分配,等等。

答案 1 :(得分:1)

链接列表使用引用来创建列表结构。

关键是要了解C#中引用类型之间的区别。像intboolstruct这样的值类型实际上是存储在堆栈中的值,当您分配它们时,实际上是在将数据从一个位置复制到另一位置。引用类型在C#中为classes,区别在于它们只是指向内存堆中数据的指针。默认情况下,它们是null,您首先必须在堆上为其分配内存,以便它们实际上使用new指向某个地方。

在这种情况下,您有一个Node类型的字段作为Node类的属性,这很好,因为它只是null或指向其中的另一个位置存储下一个节点的内存堆。如果将class更改为struct,则将无法编译,因为这将导致您提到的“递归”问题。但是对于类来说,它只是一个引用,默认值为null,因此它不必指向实例,实例化Node仅创建一个{{ 1}}实例在内存中,带有Node

这也应该有助于您理解第二个问题-设置next == null意味着您只是将next = head指向next指向内存中的相同位置。您没有移动任何数据,只是在设置参考。

Linked list

我发现在构建链接列表算法时使用图像会有所帮助。您可以想象每个head字段就像一个指向某处的箭头。当值为next时,它仅指向“无处”。最后,当您为null分配内容时,只需更改箭头指向的位置。