-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBadSparseDict.cs
More file actions
71 lines (64 loc) · 1.85 KB
/
Copy pathBadSparseDict.cs
File metadata and controls
71 lines (64 loc) · 1.85 KB
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
namespace SparseSet;
/// <summary>
/// 删除的时候没法compact dense的内容
/// 除非牺牲O(n)遍历
/// 需要引入额外信息帮助完成O(1)删除!
/// </summary>
public class BadSparseDict<T>
{
private int[] _sparse;
private T?[] _dense;
private int _count;
private const int None = -1;
private const int MinimumIncrement = 4;
public BadSparseDict(int sparseCap, int denseCap)
{
_sparse = new int[sparseCap];
_dense = new T[denseCap];
Array.Fill(_sparse, None);
_count = 0;
}
public bool Add(int key, T value)
{
EnsureCapacity(key);
if (_sparse[key] != None) return false;
var denseIndex = _count++;
_sparse[key] = denseIndex;
_dense[denseIndex] = value;
return true;
}
public bool Remove(int key)
{
if (key >= _sparse.Length || _sparse[key] == None) return false;
_dense[_sparse[key]] = default;
_sparse[key] = None;
return true;
}
public bool TryGetValue(int key, out T? value)
{
if (key < _sparse.Length && _sparse[key] != None)
{
value = _dense[_sparse[key]];
return true;
}
value = default;
return false;
}
private void EnsureCapacity(int key)
{
if (_sparse.Length <= key)
{
var oldSparseCap = _sparse.Length;
var newSparseCap = oldSparseCap;
while (newSparseCap <= key)
newSparseCap <<= 1;
Array.Resize(ref _sparse, newSparseCap);
Array.Fill(_sparse, None, oldSparseCap, newSparseCap - oldSparseCap);
}
if (_dense.Length <= _count)
{
var newDenseCap = Math.Max(_dense.Length + MinimumIncrement, _dense.Length << 1);
Array.Resize(ref _dense, newDenseCap);
}
}
}