C#单链表实现

C#单链表实现,c#,.net,list,constructor,linked-list,C#,.net,List,Constructor,Linked List,在试图理解如何在C#中实现单个列表时,我遇到了以下链接: 然而,由于我对C#还不熟悉,我对上面讨论的第一部分中列出的语法感到困惑。正在声明一个名为Node的类,该类中还有另一条语句声明为“public Node next”。这个语句称为构造函数吗?请帮忙 public class Node { public Node next; public Object data; } 这是一个班级领域。引用:请记住,链表不仅包含数据,还包含指向列表中下一个节点的引用/指针。由于类是C语

在试图理解如何在C#中实现单个列表时,我遇到了以下链接:

然而,由于我对C#还不熟悉,我对上面讨论的第一部分中列出的语法感到困惑。正在声明一个名为Node的类,该类中还有另一条语句声明为“public Node next”。这个语句称为构造函数吗?请帮忙

public class Node {
    public Node next;
    public Object data;
 }

这是一个班级领域。引用:

请记住,链表不仅包含数据,还包含指向列表中下一个节点的引用/指针。由于类是C语言中的引用类型,所以在C或C++中,你不会看到任何特殊的语法。
struct Node
{
    int Number;
    struct Node* next; /* this points to the next node in the linked list */
};

在一个简单的单链表实现中,
节点
类型包含对列表中下一项的引用,这是您发布的
节点
类型中的
下一个
字段所做的。此引用用于允许列表的迭代

封闭的
LinkedList
类(或您希望称之为的任何类)将包含对列表中第一项的单个
节点
引用。从第一个节点开始,您可以通过获取
next
字段逐步浏览列表。当
next
为空时,表示您已到达列表的末尾

以这段代码为例:

public class LinkedList
{
    public class Node
    {
        // link to next Node in list
        public Node next = null;
        // value of this Node
        public object data;
    }

    private Node root = null;

    public Node First { get { return root; } }

    public Node Last 
    {
        get
        {
            Node curr = root;
            if (curr == null)
                return null;
            while (curr.next != null)
                curr = curr.next;
            return curr;
        }
    }
}
First
属性只返回根节点,它是列表中的第一个节点。
Last
属性从根节点开始,逐步遍历列表,直到找到
next
属性为空的节点,表示列表结束

这使得在列表中添加项目变得简单:

public void Append(object value)
{
    Node n = new Node { data = value };
    if (root == null)
        root = n;
    else
        Last.next = n;
}
要删除节点,必须在列表中找到其前面的节点,然后更新该节点的
next
链接,指向要删除的节点后面的节点:

public void Delete(Node n)
{
    if (root == node) 
    {
        root = n.next;
        n.next = null;
    }
    else
    {
        Node curr = root;
        while (curr.next != null)
        {
            if (curr.next == n)
            {
                curr.next = n.next;
                n.next = null;
                break;
            }
            curr = curr.next;
        }
    }
}
您还可以执行一些其他操作,如在列表中的位置插入值、交换节点等。在节点之后插入是快的,在节点之前插入是慢的,因为您必须找到之前的节点。如果确实需要快速“在之前插入”,则需要使用双链接列表,其中
节点
类型既有
下一个
链接,也有
上一个
链接


要在评论中详细说明您的问题

在C#中,所有类型都分为两种基本分类:值类型和引用类型。名称反映了它们在代码块之间的传递方式:值类型按值传递(值复制到新变量),而引用类型按引用传递(引用/指针复制到新变量)。不同之处在于,对值类型参数的更改不会影响调用方的值副本,而对引用类型参数的更改将反映在调用方的引用副本中

为变量赋值和引用也是如此。在以下情况下,
a
的值在
b
更改时不会更改:

int a = 0;
int b = a;
b = 1;
这是相当直观的。可能会让你大吃一惊的是,在C#a
struct
中也是一种值类型:

public struct test
{
    public string value;
}

static void Main()
{
    test a;
    a.value = "a";
    test b = a;
    b.value = "b";

    Console.WriteLine("{0} {1}", a.value, b.value);
}
上面将给出输出
ab
,因为当您将
a
分配给
b
时,已制作了一份副本。但如果我们更改类的结构:

public class test
{
    public string value;
}

static void Main()
{
    test a = new test(); // Note the 'new' keyword to create a reference type instance
    a.value = "a";
    test b = a;
    b.value = "b";
    Console.WriteLine("{0} {1}", a.value, b.value);
}
由于变量
b
引用的对象与变量
a
引用的对象相同,因此此处的输出将为
b
。这两个变量引用同一个对象

如果您来自C/C++或其他类似语言,可以将引用类型变量视为指针。这并不完全相同,C#确实有指针(它们隐藏在普通托管代码中),但已经足够接近了。在将其指向该类型的实例之前,它不是完全可用的。就像C/C++中的
char*
一样,除非您将其指向某个地方,否则它不会特别有用


约瑟夫·阿尔哈巴里(他写了一篇关于价值和参考类型的伟大文章:非常值得一读,正如他所写的一样。我也强烈建议你去读一本他的书。

< P>有一个简单的方法来创建单链表。让我们尝试理解这个概念。如果概念清楚,那么你就可以理解逻辑本身。单链表的节点有两个部分。一个部分包含数据值,另一个部分包含下一个节点的引用地址。请查看以下代码:

首先,我们需要创建链表节点类

/// <summary>
/// Creating the Real World Entity of Linked List Node
/// </summary>
public class LinkedListNode
{
    public Object Value { get; set; }

    public LinkedListNode Next { get; set; }

}

让我知道它是否有意义:)

谢谢大家的帮助。在阅读了Microsoft网站上的字段描述后,我的理解更清楚了。但是,只有一个问题:如果字段声明与类同名,是否有术语来定义这种类型的字段?@user3011489我肯定有……因为似乎所有的字段都有一个术语……但我很抱歉我没有意识到这一点,或者我一时想不起来。我认为,当使用从开发人员那里抽象出这么多内容的高级语言时,实现诸如链表、双链表等问题的解决方案是复杂的。感谢您的帮助。Node curr=root;抱歉,如果这是一个愚蠢的问题,但我只是想成为b在C#时,我不想做任何假设。当你做这个声明时,我对你正在安装Node类型的对象的理解是否正确?如果是的话,让我困惑的是内存空间将如何分配,因为当“Node curr”时,里面有另一个“public Node next”声明不执行,声明是一个变量,它可以保存一个引用,它在概念上类似于C或C++中的指针。这是所有类变量的真实性。要创建类对象的实例,需要使用<代码>新< /Cord>关键字。
/// <summary>
/// Creating the Linked List Class Itself. It defines the First and Last Nodes of Linked List
/// </summary>
public class LinkedList
{
    public LinkedListNode First { get; set; }
    public LinkedListNode Last { get; set; }

    /// <summary>
    /// Method to Add items into the Linked List
    /// </summary>
    /// <param name="_value"></param>
    public void AddToLinkedList(object _value)
    {
        LinkedListNode node = new LinkedListNode();
        node.Value = _value;

        if (First == null)
        {
            First = node;
            Last = node;
        }
        else
        {
            Last.Next = node;
            Last = node;
        }
    }

    /// <summary>
    /// Method to display all items. We can further implement the IEnumerable interface
    /// to Yield IEnumerator Interface.
    /// </summary>
    public void DisplayAllItems()
    {
        LinkedListNode current = First;
        while (current != null)
        {
            Console.WriteLine(current.Value);
            current = current.Next;
        }
    }
}
class Program
{
    static void Main(string[] args)
    {
        LinkedList singlyLinkedList = new LinkedList();
        singlyLinkedList.AddToLinkedList(4);
        singlyLinkedList.AddToLinkedList(5);
        singlyLinkedList.AddToLinkedList(7);
        singlyLinkedList.AddToLinkedList(2);
        singlyLinkedList.AddToLinkedList(1);
        singlyLinkedList.AddToLinkedList(10);

        singlyLinkedList.DisplayAllItems();
        Console.ReadLine();
    }
}