这个链表没有暴露node接口,而是把链表本身包装成了一个Collection和List,实现了ICollection , IEnumerable , IList 接口,写的过程中参考了BCL中的实现以及Wintellect.PowerCollection的实现以及写法。并且初步通过测试。
namespace
FengChen.Practices
{
internal
class
ListNode
<
T
>
{
public
T Item;
//
Element item
public
ListNode
<
T
>
Next;
public
ListNode(T value) :
this
() {
this
.Item
=
value; }
internal
ListNode() {
this
.Next
=
null
; }
}
public
class
LinkList
<
T
>
: ICollection
<
T
>
, IEnumerable
<
T
>
, IList
<
T
>
{
private
ListNode
<
T
>
m_Head;
private
ListNode
<
T
>
m_End;
private
Int32 m_Count;
EqualityComparer
<
T
>
m_Comparer
=
EqualityComparer
<
T
>
.Default;
#region
ctor
public
LinkList()
{
m_Head
=
new
ListNode
<
T
>
();
m_End
=
m_Head;
}
public
LinkList(T[] array)
:
this
()
{
if
(array
==
null
)
throw
new
ArgumentNullException(
“
array
“
);
foreach
(T item
in
array)
this
.Add(item);
}
#endregion
#region
Utility methods
public
bool
IsEmpty {
get
{
return
m_Head.Next
==
null
; } }
private
ListNode
<
T
>
Find(T value,
out
Int32 index)
{
ListNode
<
T
>
node
=
m_Head.Next;
index
=
0
;
while
(node
!=
null
&&
!
m_Comparer.Equals(value, node.Item))
{
node
=
node.Next;
index
++
;
}
if
(node
==
null
) index
=
–
1
;
return
node;
}
private
ListNode
<
T
>
FindPrevious(T value)
{
ListNode
<
T
>
node
=
m_Head;
while
(node.Next
!=
null
&&
!
m_Comparer.Equals(value, node.Next.Item))
node
=
node.Next;
return
node;
}
#endregion
#region
ICollection<T> Members
public
void
Add(T item)
//
Add the item at end
{
ListNode
<
T
>
node
=
new
ListNode
<
T
>
(item);
m_End.Next
=
node;
m_End
=
node;
m_Count
++
;
}
public
void
Clear()
{
ListNode
<
T
>
pos, temp;
pos
=
m_Head;
while
(pos
!=
null
)
{
temp
=
pos.Next;
pos.Next
=
null
;
pos
=
temp;
}
m_Count
=
0
;
m_End
=
m_Head;
}
public
bool
Contains(T item)
{
Int32 i
=
0
;
return
this
.Find(item,
out
i)
!=
null
;
}
public
void
CopyTo(T[] array,
int
index)
{
if
(array
==
null
)
throw
new
ArgumentNullException(
“
array
“
);
if
((index
<
0
)
||
(index
>=
array.Length))
throw
new
ArgumentOutOfRangeException(
“
index
“
, index,
“
Please check the index value!
“
);
if
((array.Length
–
index)
<
this
.Count)
throw
new
ArgumentException(
“
Insufficient Space!
“
);
ListNode
<
T
>
node
=
m_Head.Next;
while
(node
!=
null
)
{
array[index
++
]
=
node.Item;
node
=
node.Next;
}
}
public
int
Count {
get
{
return
m_Count; } }
public
bool
IsReadOnly {
get
{
return
false
; } }
public
bool
Remove(T item)
{
ListNode
<
T
>
preNode
=
this
.FindPrevious(item);
ListNode
<
T
>
tempNode
=
null
;
if
(preNode.Next
!=
null
)
//
item is found
{
if
(m_End
==
preNode.Next) m_End
=
preNode;
tempNode
=
preNode.Next;
//
node to be deleted
preNode.Next
=
tempNode.Next;
tempNode
=
null
;
m_Count
—
;
return
true
;
}
return
false
;
}
#endregion
#region
IEnumerable<T> Members
public
IEnumerator
<
T
>
GetEnumerator()
{
ListNode
<
T
>
node
=
this
.m_Head.Next;
while
(node
!=
null
)
{
yield
return
node.Item;
node
=
node.Next;
}
}
#endregion
#region
IEnumerable Members
IEnumerator IEnumerable.GetEnumerator()
{
return
this
.GetEnumerator();
}
#endregion
///
<summary>
///
StreamWriter = new StreamWriter(Console.OpenStandardOutput());
///
</summary>
///
<param name=”writer”></param>
public
void
Display(StringWriter writer)
{
//
Use it like this
ListNode
<
T
>
p
=
m_Head.Next;
writer.Write(
“
The List Item is:
“
);
while
(p
!=
null
)
{
writer.Write(
“
{0}–>
“
, p.Item);
p
=
p.Next;
}
writer.Write(
“
NULL
“
);
writer.Write(Environment.NewLine);
}
public
override
String ToString ()
{
StringBuilder sb
=
new
StringBuilder();
StringWriter writer
=
new
StringWriter(sb);
this
.Display (writer);
writer.Close ();
return
sb.ToString();
}
#region
IList<T> Members
public
int
IndexOf(T item)
{
Int32 index
=
0
;
this
.Find(item,
out
index);
return
index;
}
public
void
Insert(
int
index, T item)
{
if
(index
<
0
||
index
>=
this
.m_Count)
throw
new
ArgumentOutOfRangeException(
“
index
“
, index,
“
Index value is out of range, please check!
“
);
ListNode
<
T
>
previousNode
=
this
.m_Head.Next;
ListNode
<
T
>
node
=
new
ListNode
<
T
>
(item);
while
( index
—
>
0
) previousNode
=
previousNode.Next;
node.Next
=
previousNode.Next;
previousNode.Next
=
node;
if
(m_End.Next
!=
null
) m_End
=
node;
m_Count
++
;
}
public
void
RemoveAt(
int
index)
{
if
(index
<
0
||
index
>=
this
.m_Count)
throw
new
ArgumentOutOfRangeException(
“
index
“
, index,
“
Index value is out of range, please check!
“
);
ListNode
<
T
>
previousNode
=
this
.m_Head;
while
(index
—
>
0
) previousNode
=
previousNode.Next;
ListNode
<
T
>
node
=
previousNode.Next;
if
(node
==
null
)
return
;
if
(node
==
m_End) m_End
=
previousNode;
previousNode.Next
=
node.Next;
node.Next
=
null
;
node
=
null
;
m_Count
—
;
}
private
ListNode
<
T
>
GetNode(
int
index)
{
if
(index
<
0
||
index
>=
this
.m_Count)
throw
new
ArgumentOutOfRangeException(
“
index
“
, index,
“
Index value is out of range, please check!
“
);
ListNode
<
T
>
node
=
this
.m_Head.Next;
while
(index
—
>
0
) node
=
node.Next;
return
node;
}
public
T
this
[
int
index]
{
get
{
return
this
.GetNode(index).Item; }
set
{
this
.GetNode(index).Item
=
value; }
}
#endregion
}
}
欢迎多提意见。