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

314 lines
6.5 KiB
C#

using System;
//+-------------------------------------------------------------------------------------------------------------------------------------------------------------
public class ViRefNode2<T>
{
public ViRefNode2()
{
}
public ViRefNode2(T data)
{
Data = data;
}
public bool IsAttach()
{
return (_list != null);
}
public bool IsAttach(ViRefList2<T> list)
{
return (list == _list);
}
public void Detach()
{
if (_list != null)
{
_list._Detach(this);
_list = null;
}
}
public T Data;
//
internal ViRefNode2<T> _pre;
internal ViRefNode2<T> _next;
internal ViRefList2<T> _list;
}
//+-------------------------------------------------------------------------------------------------------------------------------------------------------------
public class ViRefList2<T>
{
public static void Next(ref ViRefNode2<T> node)
{
ViDebuger.AssertError(node != null && node._next != null);
node = node._next;
}
//+--------------------------------------------------------------------------------------------------------------
public ViRefList2()
{
_root._list = this;
_Init();
}
//+--------------------------------------------------------------------------------------------------------------
public bool IsEmpty()
{
return _root._next == _root;
}
public UInt32 Size { get { return _cnt; } }
public ViRefNode2<T> GetHead()
{
return _root._next;
}
public ViRefNode2<T> GetTail()
{
return _root._pre;
}
public ViRefNode2<T> CurrentNode
{
get { return _next; }
}
public void Next()
{
Next(ref _next);
}
public void BeginIterator()
{
_next = _root;
Next(ref _next);
}
public void EndIterator()
{
_next = _root;
}
public bool IsEnd(ViRefNode2<T> node)
{
return node == _root;
}
public bool IsEnd() { return _next == _root; }
public void PushBack(ViRefNode2<T> node)
{
node.Detach();
++_cnt;
node._list = this;
_PushBefore(_root, node);
}
public void PushFront(ViRefNode2<T> node)
{
node.Detach();
++_cnt;
node._list = this;
_PushAfter(_root, node);
}
public void Push(ViRefNode2<T> node)
{
if (IsEnd())
{
PushBack(node);
}
else
{
PushFront(node);
}
}
public void PushBack(ViRefList2<T> list)
{
if (list == this)
{
return;
}
PushBefore(_root, list);
}
public void PushFront(ViRefList2<T> list)
{
if (list == this)
{
return;
}
PushAfter(_root, list);
}
public void PushAfter(ViRefNode2<T> before, ViRefNode2<T> node)
{
node.Detach();
++_cnt;
node._list = this;
_PushAfter(before, node);
}
public void PushBefore(ViRefNode2<T> after, ViRefNode2<T> node)
{
node.Detach();
++_cnt;
node._list = this;
_PushBefore(after, node);
}
public void PushAfter(ViRefNode2<T> before, ViRefList2<T> list)
{
if (list.Size == 0)
{
return;
}
if (before.IsAttach(list))
{
return;
}
if (before.IsAttach() == false)
{
return;
}
ViDebuger.AssertError(before._list);
ViRefList2<T> receiveList = before._list;
ViRefNode2<T> iter = list._root._next;
while (iter != list._root)
{
iter._list = receiveList;
iter = iter._next;
}
ViDebuger.AssertError(receiveList != list);
ViRefNode2<T> first = list._root._next;
ViRefNode2<T> back = list._root._pre;
ViRefNode2<T> next = before._next;
_Link(before, first);
_Link(back, next);
receiveList._cnt += list.Size;
list._Init();
}
public void PushBefore(ViRefNode2<T> after, ViRefList2<T> list)
{
if (list.Size == 0)
{
return;
}
if (after.IsAttach(list))
{
return;
}
if (after.IsAttach() == false)
{
return;
}
ViDebuger.AssertError(after._list);
ViRefList2<T> receiveList = after._list;
ViRefNode2<T> iter = list._root._next;
while (iter != list._root)
{
iter._list = receiveList;
iter = iter._next;
}
ViDebuger.AssertError(receiveList != list);
ViRefNode2<T> first = list._root._next;
ViRefNode2<T> back = list._root._pre;
ViRefNode2<T> pre = after._pre;
_Link(pre, first);
_Link(back, after);
receiveList._cnt += list.Size;
list._Init();
}
public void SetValue(T value)
{
ViRefNode2<T> next = _root._next;
while (next != _root)
{
next.Data = value;
next = next._next;
}
}
public void Clear()
{
ViRefNode2<T> next = _root._next;
while (next != _root)
{
ViRefNode2<T> nextCopy = next._next;
next._pre = null;
next._next = null;
next._list = null;
next = nextCopy;
}
_Init();
}
public void ClearAndClearContent()
{
ViRefNode2<T> next = _root._next;
while (next != _root)
{
ViRefNode2<T> nextCopy = next._next;
next._pre = null;
next._next = null;
next._list = null;
next.Data = default(T);
next = nextCopy;
}
_Init();
}
internal void _Detach(ViRefNode2<T> node)
{
ViDebuger.AssertError(node._list == this);
if (node == _next)//! 如果是正在迭代的点, 则自动将Next移到下个点
{
Next(ref _next);
}
_Link(node._pre, node._next);
node._pre = null;
node._next = null;
--_cnt;
}
//+--------------------------------------------------------------------------------------------------------------
static void _PushAfter(ViRefNode2<T> before, ViRefNode2<T> node)
{
ViRefNode2<T> next = before._next;
ViDebuger.AssertError(next);
_Link(before, node);
_Link(node, next);
}
static void _PushBefore(ViRefNode2<T> after, ViRefNode2<T> node)
{
ViRefNode2<T> pre = after._pre;
ViDebuger.AssertError(pre);
_Link(pre, node);
_Link(node, after);
}
static void _Link(ViRefNode2<T> pre, ViRefNode2<T> next)
{
pre._next = next;
next._pre = pre;
}
private void _Init()
{
_Link(_root, _root);
_next = _root;
_cnt = 0;
}
//+--------------------------------------------------------------------------------------------------------------
internal ViRefNode2<T> _root = new ViRefNode2<T>();
internal UInt32 _cnt;
internal ViRefNode2<T> _next;
}
//+-------------------------------------------------------------------------------------------------------------------------------------------------------------
public class Demo_RefList2
{
#pragma warning disable 0219
public static void Test()
{
ViRefList2<int> list = new ViRefList2<int>();
ViRefNode2<int> node0 = new ViRefNode2<int>(); node0.Data = 0;
ViRefNode2<int> node1 = new ViRefNode2<int>(); node1.Data = 1;
ViRefNode2<int> node2 = new ViRefNode2<int>(); node2.Data = 2;
list.PushBack(node0);
list.PushBack(node1);
list.PushBack(node2);
list.BeginIterator();
while (!list.IsEnd())
{
ViRefNode2<int> node = list.CurrentNode;
list.Next();
///<使用>
///</使用>
}
list.Clear();
}
#pragma warning restore 0219
}