目录

一、涉及到的知识点

1.插入算法

2.示例中current 和 _current 的作用

3.current 和 _current 能否合并为一个变量

4.单向链表节点类的三个属性

(1)Next属性:

(2) Value属性:

(3)Previous属性:

二、Insert()方法实例


一、涉及到的知识点

1.插入算法

        在单向链表的当前位置插入一个新的节点,在插入新节点之前,需要找到当前节点。如果当前节点为空,需要找到链表的最后一个节点,然后将最后一个节点设置为当前节点。这样,新节点就可以插入到链表的末尾。

·        在插入新节点时,需要正确设置新节点的 Next 和 Previous 属性。设置新节点的 Next 和 Previous 属性具体如下:

newNode.Next = current.Next;
newNode.Previous = current;
current.Next = newNode;
_current = newNode;

        这样设置确保了新节点被正确地插入到链表中,并且链表的其他部分也得到正确更新。 

2.示例中current 和 _current 的作用

        在实例程序中,current 和 _current 的作用是有区别的。它们主要用于在插入新节点时跟踪链表中的当前节点。让我来解释一下它们各自的用途:

  • current:是一个临时变量,用于在插入新节点之前找到链表中的当前节点。如果链表不为空,它会从链表头节点开始遍历,直到找到最后一个节点。在这个过程中,current 会被不断更新为当前节点的下一个节点。最后,current 会被设置为最后一个节点。
  • _current:是一个静态变量,用于在整个链表操作过程中跟踪当前节点。在插入新节点时,_current 会被设置为新插入的节点。这样,在后续的操作中,可以使用 _current 来访问链表中的当前节点。

3.current 和 _current 能否合并为一个变量

        在源程序中将 current 和 _current 可以合并为一个变量。但是,将它们分开好处更多:

  • 代码的可读性:使用两个不同的变量名可以更清楚地表明它们在代码中的不同作用。使用 _current 作为静态变量可以清楚地表明它在整个链表操作过程中的作用,而使用 current 作为局部变量可以清楚地表明它在插入新节点过程中的作用。
  • 代码的简洁性:将它们分开可以使代码更简洁。如果将它们合并为一个变量,那么在插入新节点之前需要不断地更新这个变量。而将它们分开,只需要在找到最后一个节点后,将 _current 设置为 current,就可以完成链表的插入操作。

        总之,虽然可以将 current 和 _current 统一为一个变量,但将它们分开可以使代码更易读、更简洁。

4.单向链表节点类的三个属性

        在C#中,单向链表节点(通常称为节点或列表节点)通常使用一个公共类来表示,该类具有三个主要属性:

(1)Next属性:

        此属性表示链表中当前节点的下一个节点。在单向链表中,只能从头节点开始向前遍历节点,因此每个节点仅需维护一个指向其后继节点的引用。Next属性通常是一个指向ListNode类型对象的引用。在链表的末尾,Next属性将为null。

public class ListNode
{
    public int Value { get; set; }
    public ListNode Next { get; set; }
    
    public ListNode(int value)
    {
        Value = value;
    }
}

         或

public class ListNode(int value)
{
    public int Value { get; set; } = value;
    public ListNode? Next { get; set; } = null;
    public ListNode? Previous { get; set; } = null;
}

(2) Value属性:

        此属性表示当前节点所存储的值。在链表中,每个节点都存储一个值,该值可以是任何类型,如int、double、string等。Value属性通常是一个泛型类型T,以便在不同类型的链表中重用相同的节点类。

public class ListNode<T>
{
    public T Value { get; set; }
    public ListNode<T> Next { get; set; }
    
    public ListNode(T value)
    {
        Value = value;
    }
}

         或

 public class ListNode<T>(T value)
 {
     public T Value { get; set; } = value;
     public ListNode<T>? Next { get; set; }
 }

(3)Previous属性:

        在某些情况下,需要使用双向链表即每个节点不仅维护一个指向其后继节点的引用,还维护一个指向其前驱节点的引用。在这种情况下,Previous属性表示链表中当前节点的前一个节点。Previous属性通常是一个指向ListNode类型对象的引用。在链表的头部,Previous属性将为null。

public class ListNode<T> 
{ 
    public T Value { get; set; } 
    public ListNode<T> Next { get; set; } 
    public ListNode<T> Previous { get; set; }
    public ListNode(T value) { Value = value; } 
}

二、Insert()方法实例

// 单向链表在当前位置插入新数据的方法
namespace _131_10
{
    public class ListNode(int value)
    {
        public int Value { get; set; } = value;
        public ListNode? Next { get; set; } = null;
        public ListNode? Previous { get; set; } = null;
    }

    public class LinkedList
    {
        private static ListNode? _head;
        private static ListNode? _current;

        public LinkedList() => _head = null;

        /// <summary>
        /// 在当前位置插入数据,
        /// 不对数据排序,也不比较数据
        /// </summary>
        public static void Insert(int value)
        {
            // 创建一个新的节点
            var newNode = new ListNode(value);

            // 如果链表为空,将新节点设置为头节点
            if (_head == null)
            {
                _head = newNode;
                _current = newNode;
                return;
            }

            // 找到当前节点
            var current = _current;
            if (current == null)
            {
                //current = _head;
                _current = _head;
                while (_current.Next != null)
                {
                    _current = _current.Next;
                }
                current = _current;
            }

            // 在当前位置插入新节点
            newNode.Next = current.Next;
            newNode.Previous = current;
            current.Next = newNode;
            _current = newNode;
        }

        public static void Display()
        {
            var current = _head;
            while (current != null)
            {
                Console.Write(current.Value + " ");
                current = current.Next;
            }
            Console.WriteLine();
        }

        class Program
        {
            static void Main(string[] args)
            {
                ArgumentNullException.ThrowIfNull(args);

                // 链表数据初始化
                _head = new(5)
                {
                    Next = new ListNode(2)
                };
                _head.Next.Next = new ListNode(8)
                {
                    Next = new ListNode(1)
                };
                Display();
                Console.WriteLine("**初始数据**");

                _current = _head.Next.Next; //设置当前节点为第三个节点(值为8)
                Insert(9);                  //在当前位置插入数据9
                Display(); 
                Console.WriteLine("**插入9**");
            }
        }
    }
}
//运行结果:
/*
5 2 8 1
**初始数据**
5 2 8 9 1
**插入9**

*/
03-02 10:22