目录
3.current 和 _current 能否合并为一个变量
一、涉及到的知识点
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**
*/