Daizc
count.articles51
count.tags25
count.categories3
[Csharp]循环链表封装

[Csharp]循环链表封装

[Csharp]循环链表封装

要求

  • 需要具有线程安全特性
  • 可以直接找出上一个、当前值和下一个值

思路

一开始是打算直接拿LinkedList改改的,打算直接把LinkedListNode首尾连起来,然后直接用就是了。
但随即发现一个问题:要是谁谁谁不小心for了一下这list,那还得了?而且线程安全也没法保证啊。
设计一个CreateCircularList,通过CreateCircularIterator方法生产一个Iterator,再去迭代这个Iterator就没问题了。
但随后也发现一个问题,这不够通用,我必须new一个CreateCircularList

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
using System.Collections.Generic;

#pragma warning disable CS0219 // 变量已被赋值,但从未使用过它的值

namespace Wpf481.Utils;

public class CircularLinkedIterator<TData> where TData : struct {
private readonly CircularLinkedList<TData> _list;

public CircularLinkedIterator(ICollection<TData> collection) {
_list = new CircularLinkedList<TData>(collection);
}

public int CurrentIndex { get; private set; } = -1;

public void Next() {
lock (this) {
if (_list.Count == 0) {
CurrentIndex = -1;
return;
}
var index = CurrentIndex + 1;
CurrentIndex = index == _list.Count ? 0 : index;
}
}

public TData? NextItem { get { return _list.GetNodeByIndex(CurrentIndex + 1)?.Value; } }

public TData? PreviousItem => _list.GetNodeByIndex(CurrentIndex - 1)?.Value;

public TData? CurrentItem => _list.GetNodeByIndex(CurrentIndex)?.Value;


private class CircularLinkedList<T> : LinkedList<T> where T : struct {
internal CircularLinkedList(IEnumerable<T> collection) : base(collection) { }

internal LinkedListNode<T>? GetNodeByIndex(int index) {
if (Count == 0) {
return null;
}

int realIndex = (Count + index) % Count;
var current = First;
for (int i = 0; i < realIndex; i++) {
current = current?.Next ?? First;
}
return current;
}
}
}

单元测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class CircularLinkedListTest {
public static void test() {
LoggerFactory.Create(builder => { }).CreateLogger<CircularLinkedListTest>();

var list = new List<int>();

var iterator = new CircularLinkedIterator<int>(list);

for (int i = 0; i < 3; i++) {
Console.WriteLine(
$"[{iterator.CurrentIndex}]\tlast: {iterator.PreviousItem} \t current: {iterator.CurrentItem}\t next: {iterator.NextItem}");
iterator.Next();
}

for (int i = 1; i <= 2; i++) {
list.Add(i);
}

iterator = new CircularLinkedIterator<int>(list);
for (int i = 0; i < 10; i++) {
Console.WriteLine(
$"[{iterator.CurrentIndex}]\tlast: {iterator.PreviousItem} \t current: {iterator.CurrentItem}\t next: {iterator.NextItem}");
iterator.Next();
}

list.Clear();

iterator = new CircularLinkedIterator<int>(list);
for (int i = 0; i < 3; i++) {
Console.WriteLine(
$"[{iterator.CurrentIndex}]\tlast: {iterator.PreviousItem} \t current: {iterator.CurrentItem}\t next: {iterator.NextItem}");
iterator.Next();
}
}
}
}

copyright.author:Daizc
copyright.permalink:https://note.bequick.run/[Csharp]%E5%BE%AA%E7%8E%AF%E9%93%BE%E8%A1%A8List%E5%B0%81%E8%A3%85/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可