Implementing custom LinkedList in C#: Best practices for Node and List classes (Ungureanu approach)
asked 8 hours ago by @qa-1ijyrkztjlf2eozxgpvz 0 rep · 74 views
I am currently learning data structures and decided to implement my own singly linked list in C#. I have created two separate classes: Node (representing the elements) and MyLinkedList (managing the list operations like Add, Push, and Pop).
However, I want to make sure my implementation follows C# best practices and handles edge cases correctly.
Here is my Node class implementation:
csharp:
namespace Verkettete_Liste
{
internal class Node
{
// _name is just an example but this could be any object
private string _name;
private Node _next = null;
public Node(string name)
{
_name = name;
}
public Node Next
{
get
{
return _next;
}
set
{
_next = value;
}
}
public override string ToString()
{
return _name;
}
}
}
And here is my MyLinkedList class implementation:
csharp:
using System;
namespace Verkettete_Liste
{
internal class MyLinkedList
{
private Node _head = null;
public void Add(string name)
{
if (_head == null)
{
_head = new Node(name);
}
else
{
Node temp = _head;
// this is where I iterate through the intire list
while (temp.Next != null)
{
temp = temp.Next;
}
temp.Next = new Node(name);
}
}
public void Push(string name)
{
if (_head == null)
{
_head = new Node(name);
}
else
{
Node temp = _head;
_head = new Node(name);
_head.Next = temp;
}
}
public Node Pop()
{
Node temp = null;
if (_head == null)
{
Console.WriteLine("Noch kein Element in der Liste");
}
else
{
temp = _head;
_head = _head.Next;
}
return temp;
}
public override string ToString()
{
string s = string.Empty;
if (_head != null)
{
Node temp = _head;
s += temp.ToString();
while (temp.Next != null)
{
s += temp.Next.ToString();
temp = temp.Next;
}
}
else
{
s = "Liste ist leer";
}
return s;
}
}
}
I have a few specific questions regarding this code:
Memory & Performance: In
MyLinkedList.Add, I always iterate through the entire list to append an element. Is it better to maintain a_tailpointer to achieve \(O(1)\) efficiency?String Concatenation: In
ToString(), I use a standardwhileloop with string concatenation (s += ...). Is ist worth to replace this withStringBuilderto avoid performance bottlenecks with larger lists?Encapsulation: My
Pop()method returns theNodeobject itself, exposing internal structural properties (Next) to the outside world. Is it better practice to only return thestring(the name)?Code Duplication: In
Push(), myif (_head == null)block does exactly the same thing as theelseblock would do iftempwas null. Can this logic be simplified to fewer lines?C# Conventions: Are the properties, backing fields, and null-initializations aligned with modern C# standards?
Any feedback or optimization tips would be highly appreciated!