Advertisement
Guest User

Untitled

a guest
May 27th, 2016
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.38 KB | None | 0 0
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Diagnostics;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8.  
  9. namespace SkipList
  10. {
  11. [DebuggerTypeProxy(typeof(SkipListProxy<,>))]
  12. [DebuggerDisplay("Count = {Count}")]
  13. public class SkipList<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>
  14. {
  15. private readonly Random _rnd = new Random();
  16. private const double Probability = 0.5;
  17. private const int MaxLevel = 30;
  18.  
  19. private IComparer<TKey> _comparer;
  20. private Node[] _heads;
  21. private int _count;
  22. private int _currentLevel;
  23. private int _version;
  24.  
  25. public int Count { get { return _count; } }
  26. public IComparer<TKey> Comparer { get { return _comparer; } }
  27.  
  28. public SkipList() : this(null) { }
  29.  
  30. public SkipList(IComparer<TKey> comparer)
  31. {
  32. _heads = new Node[MaxLevel+1];
  33. for (int i = 0; i < _heads.Length; i++)
  34. _heads[i] = new Node();
  35.  
  36. _count = 0;
  37. _currentLevel = 0;
  38. _version = 0;
  39. _comparer =comparer ?? Comparer<TKey>.Default;
  40. }
  41.  
  42. public void Add(TKey key, TValue value)
  43. {
  44. _version++;
  45. var pathArray = new Node[_currentLevel + 1];
  46. var level = GetRandomLevel();
  47. var node = _heads[_currentLevel];
  48. if (_count == 0)
  49. {
  50. node.Next = new Node(key, value);
  51. for (int i = 0; i < level; i++)
  52. {
  53. var newHead = new Node();
  54. newHead.Next = new Node(key, value) { Down = _heads[_currentLevel].Next };
  55. newHead.Down = _heads[_currentLevel];
  56. _heads[_currentLevel+1] = newHead;
  57. _currentLevel++;
  58. }
  59. _count++;
  60. return;
  61. }
  62.  
  63. Node nextNode;
  64. Node previous;
  65. for (int i = _currentLevel; i > level; i--)//Без добавления
  66. {
  67. nextNode = node.Next;
  68. if (nextNode != null && _comparer.Compare(key, nextNode.Key) > 0)
  69. {
  70. do
  71. {
  72. previous = nextNode;
  73. nextNode = nextNode.Next;
  74. } while (nextNode != null && _comparer.Compare(key, nextNode.Key) > 0);
  75. node = previous.Down;
  76. continue;
  77. }
  78. node = node.Down;
  79. }
  80.  
  81. var temp = Math.Min(level, _currentLevel);
  82. nextNode = node.Next;
  83. if (nextNode != null && _comparer.Compare(key, nextNode.Key) > 0)
  84. {
  85. do
  86. {
  87. previous = nextNode;
  88. nextNode = nextNode.Next;
  89. } while (nextNode != null && _comparer.Compare(key, nextNode.Key) > 0);
  90. previous.Next = new Node(key, value) { Next = previous.Next };
  91. pathArray[temp] = previous.Next;
  92. node = previous.Down;
  93. }
  94. else
  95. {
  96. node.Next = new Node(key, value) { Next = node.Next };
  97. pathArray[temp] = node.Next;
  98. node = node.Down;
  99. }
  100.  
  101. for (int i = temp - 1; i >= 0; i--)
  102. {
  103. nextNode = node.Next;
  104. if (nextNode != null && _comparer.Compare(key, nextNode.Key) > 0)
  105. {
  106. do
  107. {
  108. previous = nextNode;
  109. nextNode = nextNode.Next;
  110. } while (nextNode != null && _comparer.Compare(key, nextNode.Key) > 0);
  111. previous.Next = new Node(key, value) { Next = previous.Next };
  112. pathArray[i] = previous.Next;
  113. pathArray[i + 1].Down = previous.Next;
  114. node = previous.Down;
  115. continue;
  116. }
  117. node.Next = new Node(key, value) { Next = node.Next };
  118. pathArray[i] = node.Next;
  119. pathArray[i + 1].Down = node.Next;
  120. node = node.Down;
  121. }
  122. _count++;
  123. if (pathArray[0].Next != null && _comparer.Compare(key, pathArray[0].Next.Key) == 0)
  124. throw new ArgumentException("Элемент с таким ключем уже существует.", nameof(key));
  125.  
  126. if (_currentLevel < level)
  127. {
  128. Node newHead;
  129. newHead = new Node() { Down = _heads[_currentLevel] };
  130. newHead.Next = new Node(key, value) { Down = pathArray[pathArray.Length - 1] };
  131. _heads[_currentLevel+1] = newHead;
  132. for (int i = _currentLevel + 1; i < level; i++)
  133. {
  134. newHead = new Node() { Down = _heads[i] };
  135. newHead.Next = new Node(key, value) { Down = _heads[i].Next };
  136. _heads[i+1] = newHead;
  137. }
  138. _currentLevel = level;
  139. }
  140. }
  141.  
  142. public bool Remove(TKey key)
  143. {
  144. _version++;
  145. var node = _heads[_currentLevel];
  146. Node nextNode = null;
  147. Node previous = null;
  148. bool isDeleted = false;
  149. while (node != null)
  150. {
  151. previous = node;
  152. nextNode = node.Next;
  153. while (nextNode != null && _comparer.Compare(key, nextNode.Key) > 0)
  154. {
  155. previous = nextNode;
  156. nextNode = nextNode.Next;
  157. }
  158. if (previous.Next != null && _comparer.Compare(key, previous.Next.Key) == 0)
  159. {
  160. isDeleted = true;
  161. previous.Next = previous.Next.Next;
  162. }
  163.  
  164. node = previous.Down;
  165. }
  166.  
  167. if (isDeleted)
  168. {
  169. for (int i = _currentLevel; i > 0; i--)
  170. {
  171. if (_heads[_currentLevel].Next == null) _currentLevel--;
  172. else break;
  173. }
  174. _count--;
  175. }
  176.  
  177. return isDeleted;
  178. }
  179.  
  180. public bool Containts(TKey key)
  181. {
  182. return FindNode(key) != null;
  183. }
  184.  
  185. public TValue this[TKey ind]
  186. {
  187. get
  188. {
  189. var node = FindNode(ind);
  190. if (node == null) throw new ArgumentOutOfRangeException(nameof(ind));
  191. return node.Value;
  192. }
  193. set
  194. {
  195. var node = FindNode(ind);
  196. if (node == null) throw new ArgumentOutOfRangeException(nameof(ind));
  197. while (node != null)
  198. {
  199. node.Value = value;
  200. node = node.Down;
  201. }
  202. }
  203.  
  204. }
  205.  
  206.  
  207. #if DEBUG
  208. public TKey GetFirstKey()
  209. {
  210. return _heads[_currentLevel].Next.Key;
  211. }
  212. #endif
  213.  
  214. public TKey[] GetRange()
  215. {
  216. if (_count == 0) return new TKey[0];
  217. var keys = GetRangeAtLevel(0);
  218. return keys;
  219. }
  220.  
  221. public Dictionary<int, TKey[]> GetAllLevels()
  222. {
  223. var dict = new Dictionary<int, TKey[]>();
  224. for (int level = _currentLevel; level >= 0; level--)
  225. {
  226. dict[level] = GetRangeAtLevel(level);
  227. }
  228. return dict;
  229. }
  230. public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
  231. {
  232. return new Enumerator(this);
  233. }
  234.  
  235. IEnumerator IEnumerable.GetEnumerator()
  236. {
  237. return GetEnumerator();
  238. }
  239.  
  240. private class Node
  241. {
  242. public TKey Key;
  243. public TValue Value;
  244. public Node Next;
  245. public Node Down;
  246.  
  247. public Node() { }
  248. public Node(TKey key, TValue value)
  249. {
  250. Key = key;
  251. Value = value;
  252. }
  253. }
  254.  
  255. private struct Enumerator : IEnumerator<KeyValuePair<TKey, TValue>>
  256. {
  257. private SkipList<TKey, TValue> list;
  258. private Node current;
  259. private int version;
  260. public KeyValuePair<TKey, TValue> Current { get { return new KeyValuePair<TKey, TValue>(current.Key, current.Value); } }
  261.  
  262. public Enumerator(SkipList<TKey, TValue> list)
  263. {
  264. this.list = list;
  265. current = list._heads[0];
  266. version = list._version;
  267. }
  268. public void Dispose() { }
  269.  
  270. public bool MoveNext()
  271. {
  272. if (version != list._version) throw new InvalidOperationException(nameof(list));
  273. current = current.Next;
  274. return current != null;
  275. }
  276.  
  277. public void Reset()
  278. {
  279. current = list._heads[0];
  280. version = list._version;
  281. }
  282.  
  283. object IEnumerator.Current
  284. {
  285. get { return Current; }
  286. }
  287. }
  288.  
  289. #region Методы для внутреннего использования
  290.  
  291. private Node FindNode(TKey key)
  292. {
  293. var node = _heads[_currentLevel];
  294. Node nextNode = null;
  295. Node previous = null;
  296. while (node != null)
  297. {
  298. previous = node;
  299. nextNode = node.Next;
  300. while (nextNode != null && _comparer.Compare(key, nextNode.Key) > 0)
  301. {
  302. previous = nextNode;
  303. nextNode = nextNode.Next;
  304. }
  305. if (previous.Next != null && _comparer.Compare(key, previous.Next.Key) == 0)
  306. {
  307. return previous.Next;
  308. }
  309. node = previous.Down;
  310. }
  311. return null;
  312. }
  313.  
  314. private TKey[] GetRangeAtLevel(int level)
  315. {
  316. if (level < 0 || level > _currentLevel) return new TKey[0];
  317. var node = _heads[level];
  318. var list = new List<TKey>();
  319. node = node.Next;
  320. while (node != null)
  321. {
  322. list.Add(node.Key);
  323. node = node.Next;
  324. }
  325. return list.ToArray();
  326. }
  327.  
  328. private int GetRandomLevel()
  329. {
  330. var level = 0;
  331. for (int i = 0; i < MaxLevel; i++)
  332. {
  333. var temp = _rnd.NextDouble();
  334. if (temp <= Probability) level++;
  335. else break;
  336. }
  337. return level;
  338. }
  339.  
  340. #endregion
  341. }
  342.  
  343. internal class SkipListProxy<K,V>
  344. {
  345. private SkipList<K, V> _skipList;
  346.  
  347. public SkipListProxy(SkipList<K, V> skipList)
  348. {
  349. _skipList = skipList;
  350. }
  351.  
  352. [DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
  353. public KeyValuePair<K,V>[] Items
  354. {
  355. get { return _skipList.ToArray(); }
  356. }
  357. }
  358. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement