167 lines
3.4 KiB
C#
167 lines
3.4 KiB
C#
|
namespace KumiScript.Common
|
||
|
{
|
||
|
public class FastLinkedList<T>
|
||
|
{
|
||
|
ListNode<T>? _first;
|
||
|
ListNode<T>? _last;
|
||
|
uint _length;
|
||
|
public FastLinkedList()
|
||
|
{
|
||
|
_length = 0;
|
||
|
}
|
||
|
|
||
|
public void InsertLast(T addend)
|
||
|
{
|
||
|
ListNode<T> n = new ListNode<T>(addend);
|
||
|
if (_length == 0)
|
||
|
{
|
||
|
_first = n;
|
||
|
_last = n;
|
||
|
_length = 1;
|
||
|
return;
|
||
|
}
|
||
|
_last!.SetNext(n);
|
||
|
n.SetPrev(_last);
|
||
|
_last = n;
|
||
|
_length++;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
public void InsertFirst(T addend)
|
||
|
{
|
||
|
ListNode<T> n = new ListNode<T>(addend);
|
||
|
if (_length == 0)
|
||
|
{
|
||
|
_first = n;
|
||
|
_last = n;
|
||
|
_length = 1;
|
||
|
return;
|
||
|
}
|
||
|
_first!.SetPrev(n);
|
||
|
n.SetNext(_first);
|
||
|
_first = n;
|
||
|
_length++;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
private ListNode<T>? FindNth(uint index)
|
||
|
{
|
||
|
if (index > _length - 1)
|
||
|
return null;
|
||
|
|
||
|
if (index - 1 == _length)
|
||
|
return _last;
|
||
|
|
||
|
ListNode<T>? ni = _first;
|
||
|
if (ni is null)
|
||
|
return null;
|
||
|
|
||
|
for (uint i = 0; i < index; i++)
|
||
|
{
|
||
|
ni = ni!.GetNext();
|
||
|
}
|
||
|
return ni;
|
||
|
}
|
||
|
|
||
|
public void InsertAfter(uint index, T value)
|
||
|
{
|
||
|
ListNode<T> nn = new ListNode<T>(value);
|
||
|
ListNode<T>? ni = FindNth(index);
|
||
|
|
||
|
}
|
||
|
|
||
|
public T? Find(IEqualityComparer<T> eq, T other)
|
||
|
{
|
||
|
ListNode<T>? n = _first;
|
||
|
if (n is null)
|
||
|
return default;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
T nv = n.GetValue();
|
||
|
if (eq.Equals(nv, other))
|
||
|
{
|
||
|
return nv;
|
||
|
}
|
||
|
n = n.GetNext();
|
||
|
} while (n is not null);
|
||
|
return default;
|
||
|
}
|
||
|
|
||
|
public T? GetFirst()
|
||
|
{
|
||
|
if (_first is null)
|
||
|
return default;
|
||
|
|
||
|
return _first.GetValue();
|
||
|
}
|
||
|
|
||
|
public T? GetLast()
|
||
|
{
|
||
|
if (_last is null)
|
||
|
return default;
|
||
|
|
||
|
return _last.GetValue();
|
||
|
}
|
||
|
|
||
|
public uint GetLength()
|
||
|
{
|
||
|
return _length;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal class ListNode<T>
|
||
|
{
|
||
|
ListNode<T>? _next;
|
||
|
ListNode<T>? _prev;
|
||
|
T _value;
|
||
|
|
||
|
internal ListNode(T value)
|
||
|
{
|
||
|
_value = value;
|
||
|
}
|
||
|
|
||
|
internal T GetValue()
|
||
|
{
|
||
|
return _value;
|
||
|
}
|
||
|
|
||
|
internal void SetValue(T value)
|
||
|
{
|
||
|
_value = value;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
internal void SetNext(ListNode<T> next)
|
||
|
{
|
||
|
_next = next;
|
||
|
}
|
||
|
|
||
|
internal void SetPrev(ListNode<T> prev)
|
||
|
{
|
||
|
_prev = prev;
|
||
|
}
|
||
|
|
||
|
internal bool HasNext()
|
||
|
{
|
||
|
return _next is not null;
|
||
|
}
|
||
|
|
||
|
internal bool HasPrev()
|
||
|
{
|
||
|
return _prev is not null;
|
||
|
}
|
||
|
|
||
|
internal ListNode<T>? GetNext()
|
||
|
{
|
||
|
return _next;
|
||
|
}
|
||
|
|
||
|
internal ListNode<T>? GetPrev()
|
||
|
{
|
||
|
return _prev;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|