2025-08-20 02:24:48 +08:00

427 lines
9.2 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
//+-------------------------------------------------------------------------------------------------------------------------------------------------------------
public class ViDoubleLinkNode3<T>
{
public ViDoubleLinkNode3()
{
}
public ViDoubleLinkNode3(T data)
{
Data = data;
}
internal void _Detach()
{
if (_pre != null)
{
_pre._next = _next;
_next._pre = _pre;
_pre = null;
_next = null;
}
}
public T Data;
//
internal ViDoubleLinkNode3<T> _pre;
internal ViDoubleLinkNode3<T> _next;
}
//+-------------------------------------------------------------------------------------------------------------------------------------------------------------
public class ViDoubleLink3<T> : IEnumerable<T>
{
//+-----------------------------------------------------------------------------------------------------------------------------
public static void Next(ref ViDoubleLinkNode3<T> node)
{
//ViDebuger.AssertError(node != null && node._next != null);
node = node._next;
}
public static void Pre(ref ViDoubleLinkNode3<T> node)
{
//ViDebuger.AssertError(node != null && node._pre != null);
node = node._pre;
}
public static void PushAfter(ViDoubleLinkNode3<T> before, T value)
{
ViDoubleLinkNode3<T> node = new ViDoubleLinkNode3<T>(value);
_PushAfter(before, node);
}
public static void PushBefore(ViDoubleLinkNode3<T> after, T value)
{
ViDoubleLinkNode3<T> node = new ViDoubleLinkNode3<T>(value);
_PushBefore(after, node);
}
//public static void PushAfter(ViDoubleLinkNode3<T> before, ViDoubleLink3<T> list)
//{
// if (before.IsAttach() == false)
// {
// return;
// }
// if (list.IsEmpty())
// {
// return;
// }
// _PushAfter(before, list);
//}
//public static void PushBefore(ViDoubleLinkNode3<T> after, ViDoubleLink3<T> list)
//{
// if (after.IsAttach() == false)
// {
// return;
// }
// if (list.IsEmpty())
// {
// return;
// }
// _PushBefore(after, list);
//}
//+-----------------------------------------------------------------------------------------------------------------------------
public ViDoubleLink3()
{
_Init();
}
public bool IsEmpty()
{
return _root._next == _root;
}
public bool IsNotEmpty()
{
return _root._next != _root;
}
public bool IsEnd(ViDoubleLinkNode3<T> node)
{
return node == _root;
}
public ViDoubleLinkNode3<T> GetHead()
{
return _root._next;
}
public ViDoubleLinkNode3<T> GetTail()
{
return _root._pre;
}
public void PushBack(T value)
{
ViDoubleLinkNode3<T> node = new ViDoubleLinkNode3<T>(value);
++_count;
_PushBefore(_root, node);
}
public void PushFront(T value)
{
ViDoubleLinkNode3<T> node = new ViDoubleLinkNode3<T>(value);
++_count;
_PushAfter(_root, node);
}
public T GetFront(T defaultValue)
{
if (IsEmpty())
{
return defaultValue;
}
else
{
return _root._next.Data;
}
}
public T GetBack(T defaultValue)
{
if (IsEmpty())
{
return defaultValue;
}
else
{
return _root._pre.Data;
}
}
public void PopFront()
{
if (!IsEmpty())
{
--_count;
_root._next._Detach();
}
}
public void PopBack()
{
if (!IsEmpty())
{
--_count;
_root._pre._Detach();
}
}
public bool Has(T value)
{
EqualityComparer<T> comparer = EqualityComparer<T>.Default;
ViDoubleLinkNode3<T> next = _root._next;
while (next != _root)
{
if (comparer.Equals(next.Data, value))
{
return true;
}
next = next._next;
}
return false;
}
public void Remove(ViDoubleLinkNode3<T> node)
{
_IsChild(node);
node._Detach();
--_count;
}
//public void PushBack(ViDoubleLink3<T> list)
//{
// _PushBefore(_root, list);
//}
//public void PushFront(ViDoubleLink3<T> list)
//{
// _PushAfter(_root, list);
//}
public void SetValue(T value)
{
ViDoubleLinkNode3<T> next = _root._next;
while (next != _root)
{
next.Data = value;
next = next._next;
}
}
public void Clear()
{
ViDoubleLinkNode3<T> next = _root._next;
while (next != _root)
{
ViDoubleLinkNode3<T> nextCopy = next._next;
next._pre = null;
next._next = null;
next = nextCopy;
}
_Init();
}
public UInt32 Count { get { return _count; } }
//+-----------------------------------------------------------------------------------------------------------------------------
static void _PushAfter(ViDoubleLinkNode3<T> before, ViDoubleLinkNode3<T> node)
{
ViDoubleLinkNode3<T> next = before._next;
ViDebuger.AssertError(next);
_Link(before, node);
_Link(node, next);
}
static void _PushBefore(ViDoubleLinkNode3<T> after, ViDoubleLinkNode3<T> node)
{
ViDoubleLinkNode3<T> pre = after._pre;
ViDebuger.AssertError(pre);
_Link(pre, node);
_Link(node, after);
}
static void _PushAfter(ViDoubleLinkNode3<T> before, ViDoubleLink3<T> list)
{
if (list.IsEmpty())
{
return;
}
ViDoubleLinkNode3<T> first = list._root._next;
ViDoubleLinkNode3<T> back = list._root._pre;
ViDoubleLinkNode3<T> next = before._next;
_Link(before, first);
_Link(back, next);
list._Init();
}
static void _PushBefore(ViDoubleLinkNode3<T> after, ViDoubleLink3<T> list)
{
if (list.IsEmpty())
{
return;
}
ViDoubleLinkNode3<T> first = list._root._next;
ViDoubleLinkNode3<T> back = list._root._pre;
ViDoubleLinkNode3<T> pre = after._pre;
_Link(pre, first);
_Link(back, after);
list._Init();
}
static void _Link(ViDoubleLinkNode3<T> pre, ViDoubleLinkNode3<T> next)
{
pre._next = next;
next._pre = pre;
}
private void _Init()
{
_Link(_root, _root);
_count = 0;
}
private bool _IsChild(ViDoubleLinkNode3<T> node)
{
ViDoubleLinkNode3<T> next = _root._next;
while (next != _root)
{
if (node == next)
{
return true;
}
next = next._next;
}
return false;
}
//+-----------------------------------------------------------------------------------------------------------------------------
private ViDoubleLinkNode3<T> _root = new ViDoubleLinkNode3<T>();
private UInt32 _count;
///<foreach>
public IEnumerator<T> GetEnumerator()
{
return new Enumerator(this);
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return this.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
internal struct Enumerator : IEnumerator<T>, IEnumerator
{
private ViDoubleLinkNode3<T> _root;
private ViDoubleLinkNode3<T> _node;
private T _current;
internal Enumerator(ViDoubleLink3<T> list)
{
_root = list._root;
_node = list._root._next;
_current = default(T);
}
T IEnumerator<T>.Current { get { return _current; } }
object IEnumerator.Current { get { return _current; } }
public bool MoveNext()
{
if (_node != _root)
{
_current = _node.Data;
_node = _node._next;
return true;
}
return false;
}
public void Reset() { _node = _root._next; }
public void Dispose() { }
}
}
public class Demo_ViDoubleLink3
{
#pragma warning disable 0219
public static void Test()
{
ViDoubleLink3<int> list = new ViDoubleLink3<int>();
list.PushBack(1);
list.PushBack(3);
{///<正向迭代>
ViDoubleLinkNode3<int> iter = list.GetHead();
while (!list.IsEnd(iter))
{
int value = iter.Data;
ViDoubleLink3<int>.Next(ref iter);
///<使用>
Console.WriteLine(value);
///</使用>
}
}
{///<反向迭代>
ViDoubleLinkNode3<int> iter = list.GetTail();
while (!list.IsEnd(iter))
{
int value = iter.Data;
ViDoubleLink3<int>.Pre(ref iter);
///<使用>
Console.WriteLine(value);
///</使用>
}
}
foreach (int value in list)
{
Console.WriteLine(value);
}
}
#pragma warning restore 0219
}
public class Performance_ViDoubleLink3
{
#pragma warning disable 0219
public static void Test0()
{
Console.WriteLine("Performance_ViDoubleLink3.Test0");
ViDoubleLink3<UInt32> list = new ViDoubleLink3<UInt32>();
UInt32 cnt = 10000000;
UInt32 round = 100;
Console.WriteLine(DateTime.Now);
for (UInt32 idx = 0; idx < cnt; ++idx)
{
list.PushBack(idx);
}
Console.WriteLine(DateTime.Now);
for (UInt32 idx = 0; idx < round; ++idx)
{
ViDoubleLinkNode3<UInt32> iter = list.GetHead();
while (!list.IsEnd(iter))
{
UInt32 value = iter.Data;
ViDoubleLink3<UInt32>.Next(ref iter);
///<使用>
///</使用>
}
}
Console.WriteLine(DateTime.Now);
}
public static void Test1()
{
Console.WriteLine("Performance_ViDoubleLink3.Test1");
ViDoubleLink3<UInt32> list = new ViDoubleLink3<UInt32>();
UInt32 cnt = 10000000;
UInt32 round = 100;
Console.WriteLine(DateTime.Now);
for (UInt32 idx = 0; idx < cnt; ++idx)
{
list.PushBack(idx);
}
Console.WriteLine(DateTime.Now);
for (UInt32 idx = 0; idx < round; ++idx)
{
foreach (UInt32 value in list)
{
}
}
Console.WriteLine(DateTime.Now);
}
public static void Test2()
{
Console.WriteLine("Performance_ViDoubleLink3.Test2");
LinkedList<UInt32> list = new LinkedList<UInt32>();
UInt32 cnt = 10000000;
UInt32 round = 100;
Console.WriteLine(DateTime.Now);
for (UInt32 idx = 0; idx < cnt; ++idx)
{
list.AddLast(idx);
}
Console.WriteLine(DateTime.Now);
for (UInt32 idx = 0; idx < round; ++idx)
{
foreach (UInt32 value in list)
{
}
}
Console.WriteLine(DateTime.Now);
}
#pragma warning restore 0219
}