C#数据结构练习——队列
记录数据结构的练习 强调:线程不安全
直接上代码
using System
;
using System
.Collections
;
using System
.Collections
.Generic
;
using System
.Linq
;
using System
.Text
;
using System
.Threading
;
public class MyQueue<T
> : IEnumerator
<T
>,IEnumerable
<T
>, ICollection
{
private int head
;
private T
[] datas
;
private int size
;
private int trail
;
public int Head
=> head
;
public int Trail
=> trail
;
public int Count
=> size
;
public bool IsEmpty
=> size
<= 0;
public MyQueue(int cap
)
{
if (cap
< 0) cap
= 4;
head
= trail
= 0;
size
= trail
- head
;
datas
= new T[cap
];
}
public MyQueue() : this(4) { }
#region 迭代器
private int currIndex
= -1;
public T Current
=> datas
[currIndex
];
object IEnumerator
.Current
=> Current
;
private object syncRoot
;
public object SyncRoot
{
get
{
if (syncRoot
== null)
Interlocked
.CompareExchange(ref syncRoot
, new object(), null);
return syncRoot
;
}
}
public bool IsSynchronized
=> false;
public void Dispose() { }
public IEnumerator GetEnumerator()
{
Reset();
return this;
}
IEnumerator
<T
> IEnumerable
<T
>.GetEnumerator()
{
return this;
}
public bool MoveNext()
{
currIndex
++;
return currIndex
< trail
;
}
public void Reset()
{
currIndex
= head
- 1;
}
#endregion
public void Enqueue(T item
)
{
if (size
== datas
.Length
) Resize();
datas
[trail
] = item
;
size
++;
Console
.WriteLine($
"数据入队:【{item}】,Head:【{head}】,Trail:【{trail}】,Size:【{size}】,Capacity:【{datas.Length}】");
Adjust();
trail
= (trail
+ 1) % datas
.Length
;
}
public void Enqueue(IEnumerable
<T
> collection
)
{
if (collection
== null) throw new ArgumentNullException("参数为空");
IEnumerator
<T
> enumerator
= collection
.GetEnumerator();
if (enumerator
== null)
{
throw new Exception("参数必须是集合或迭代器");
}
while (enumerator
.MoveNext())
{
Enqueue(enumerator
.Current
);
}
}
private void Resize()
{
int len
= datas
.Length
;
len
= (int)(len
* 1.5);
T
[] newArr
= new T[len
];
Array
.Copy(datas
, newArr
, datas
.Length
);
datas
= newArr
;
head
= 0;
trail
= size
;
Console
.WriteLine($
"重置容量:{len}");
}
private void Adjust()
{
if (size
== 0) return;
bool adjust
= trail
== datas
.Length
- 1 && head
!= 0;
adjust
|= datas
.Length
> 10 && size
< datas
.Length
* 0.3;
if (adjust
)
{
Array
.Copy(datas
, head
, datas
, 0, size
);
Array
.Clear(datas
, size
, datas
.Length
- size
);
Console
.WriteLine($
"调整数据位置前---Head:【{head}】---Trail:【{trail}】");
trail
-= head
;
head
= 0;
Console
.WriteLine($
"调整数据位置后---Head:【{head}】---Trail:【{trail}】");
}
}
public T Dequeue()
{
if (size
== 0)
{
Console
.WriteLine("空队");
return default(T
);
}
T item
= datas
[head
];
size
--;
head
= (head
+ 1) % datas
.Length
;
Console
.WriteLine($
"数据出队:【{item}】,Head:【{head}】,Trail:【{trail}】,Size:【{size}】,Capacity:【{datas.Length}】");
return item
;
}
public void CopyTo(Array array
, int index
)
{
if (array
== null) throw new ArgumentNullException("参数为空");
if (index
< 0 || index
> array
.Length
) throw new IndexOutOfRangeException("下标越界");
if (array
.Rank
!= 1) throw new RankException("Rank not Match");
if (array
.Length
- index
< Count
) throw new ArgumentException("给定数组和编号不合适");
try
{
Array
.Copy(datas
, head
, array
, index
, Count
);
}
catch (Exception e
)
{
throw e
;
}
}
public void Reverse()
{
Array
.Reverse(datas
, head
, Count
);
}
}
要点分析
1.队列的特性是先进先出,两端操作,需要维护队首和队尾两个标记 2.本文章内的首标必然是小于尾标 3.增加动态调整数据的功能,便于后续的数据存储和避免过度的扩容造成浪费空间的问题 4.其他细节分析见代码内注释
欢迎留言交流 转载请注明出处
转载请注明原文地址:https://tech.qufami.com/read-27677.html