mirror of
https://github.com/zrwusa/data-structure-typed.git
synced 2024-11-23 12:54:04 +00:00
refactor: Discard the unnecessary Iterator class in Deque and HashMap, and instead implement using Generators.
This commit is contained in:
parent
b089cf47b3
commit
b4e89d9f72
47
README.md
47
README.md
|
@ -807,53 +807,8 @@ Array.from(dijkstraResult?.seen ?? []).map(vertex => vertex.key) // ['A', 'B', '
|
|||
|
||||
[//]: # (No deletion!!! Start of Replace Section)
|
||||
<div class="json-to-html-collapse clearfix 0">
|
||||
<div class='collapsible level0' ><span class='json-to-html-label'>comparison</span></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>SRC 10,000 add</td><td>0.57</td><td>1745.23</td><td>4.83e-6</td></tr><tr><td>CJS 10,000 add</td><td>0.57</td><td>1752.47</td><td>4.64e-6</td></tr><tr><td>MJS 10,000 add</td><td>0.59</td><td>1687.89</td><td>1.40e-4</td></tr><tr><td>SRC PQ 10,000 add & pop</td><td>3.41</td><td>293.00</td><td>2.65e-5</td></tr><tr><td>CJS PQ 10,000 add & pop</td><td>4.92</td><td>203.31</td><td>3.60e-5</td></tr><tr><td>MJS PQ 10,000 add & pop</td><td>4.88</td><td>204.72</td><td>4.35e-5</td></tr></table></div>
|
||||
</div><div class="json-to-html-collapse clearfix 0">
|
||||
<div class='collapsible level0' ><span class='json-to-html-label'>avl-tree</span></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>10,000 add randomly</td><td>31.02</td><td>32.24</td><td>2.83e-4</td></tr><tr><td>10,000 add & delete randomly</td><td>71.45</td><td>14.00</td><td>0.00</td></tr><tr><td>10,000 addMany</td><td>40.21</td><td>24.87</td><td>4.47e-4</td></tr><tr><td>10,000 get</td><td>28.34</td><td>35.29</td><td>5.15e-4</td></tr></table></div>
|
||||
</div><div class="json-to-html-collapse clearfix 0">
|
||||
<div class='collapsible level0' ><span class='json-to-html-label'>binary-tree</span></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000 add randomly</td><td>13.04</td><td>76.71</td><td>1.56e-4</td></tr><tr><td>1,000 add & delete randomly</td><td>15.79</td><td>63.33</td><td>1.40e-4</td></tr><tr><td>1,000 addMany</td><td>10.25</td><td>97.60</td><td>1.08e-4</td></tr><tr><td>1,000 get</td><td>18.31</td><td>54.60</td><td>1.50e-4</td></tr><tr><td>1,000 dfs</td><td>155.22</td><td>6.44</td><td>8.11e-4</td></tr><tr><td>1,000 bfs</td><td>56.66</td><td>17.65</td><td>6.70e-4</td></tr><tr><td>1,000 morris</td><td>254.79</td><td>3.92</td><td>5.27e-4</td></tr></table></div>
|
||||
</div><div class="json-to-html-collapse clearfix 0">
|
||||
<div class='collapsible level0' ><span class='json-to-html-label'>bst</span></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>10,000 add randomly</td><td>28.23</td><td>35.42</td><td>3.20e-4</td></tr><tr><td>10,000 add & delete randomly</td><td>68.35</td><td>14.63</td><td>8.46e-4</td></tr><tr><td>10,000 addMany</td><td>28.94</td><td>34.56</td><td>0.00</td></tr><tr><td>10,000 get</td><td>28.97</td><td>34.51</td><td>4.57e-4</td></tr></table></div>
|
||||
</div><div class="json-to-html-collapse clearfix 0">
|
||||
<div class='collapsible level0' ><span class='json-to-html-label'>rb-tree</span></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>100,000 add</td><td>89.12</td><td>11.22</td><td>0.00</td></tr><tr><td>100,000 add & delete randomly</td><td>219.00</td><td>4.57</td><td>0.00</td></tr><tr><td>100,000 getNode</td><td>105.74</td><td>9.46</td><td>6.09e-4</td></tr></table></div>
|
||||
</div><div class="json-to-html-collapse clearfix 0">
|
||||
<div class='collapsible level0' ><span class='json-to-html-label'>directed-graph</span></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000 addVertex</td><td>0.10</td><td>9902.14</td><td>9.12e-7</td></tr><tr><td>1,000 addEdge</td><td>6.11</td><td>163.67</td><td>1.29e-4</td></tr><tr><td>1,000 getVertex</td><td>0.05</td><td>2.16e+4</td><td>3.51e-7</td></tr><tr><td>1,000 getEdge</td><td>23.63</td><td>42.33</td><td>0.00</td></tr><tr><td>tarjan</td><td>222.85</td><td>4.49</td><td>0.01</td></tr><tr><td>tarjan all</td><td>223.79</td><td>4.47</td><td>0.00</td></tr><tr><td>topologicalSort</td><td>181.77</td><td>5.50</td><td>0.00</td></tr></table></div>
|
||||
</div><div class="json-to-html-collapse clearfix 0">
|
||||
<div class='collapsible level0' ><span class='json-to-html-label'>hash-map</span></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>10,000 set</td><td>1.00</td><td>1001.93</td><td>2.06e-5</td></tr><tr><td>10,000 set & get</td><td>1.51</td><td>661.53</td><td>2.65e-5</td></tr></table></div>
|
||||
</div><div class="json-to-html-collapse clearfix 0">
|
||||
<div class='collapsible level0' ><span class='json-to-html-label'>heap</span></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>10,000 add & pop</td><td>5.82</td><td>171.79</td><td>5.13e-5</td></tr><tr><td>10,000 fib add & pop</td><td>359.24</td><td>2.78</td><td>0.00</td></tr></table></div>
|
||||
</div><div class="json-to-html-collapse clearfix 0">
|
||||
<div class='collapsible level0' ><span class='json-to-html-label'>doubly-linked-list</span></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 push</td><td>214.50</td><td>4.66</td><td>0.05</td></tr><tr><td>1,000,000 unshift</td><td>205.89</td><td>4.86</td><td>0.05</td></tr><tr><td>1,000,000 unshift & shift</td><td>168.93</td><td>5.92</td><td>0.04</td></tr><tr><td>1,000,000 insertBefore</td><td>291.32</td><td>3.43</td><td>0.05</td></tr></table></div>
|
||||
</div><div class="json-to-html-collapse clearfix 0">
|
||||
<div class='collapsible level0' ><span class='json-to-html-label'>singly-linked-list</span></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>10,000 push & pop</td><td>215.82</td><td>4.63</td><td>0.02</td></tr><tr><td>10,000 insertBefore</td><td>248.56</td><td>4.02</td><td>0.01</td></tr></table></div>
|
||||
</div><div class="json-to-html-collapse clearfix 0">
|
||||
<div class='collapsible level0' ><span class='json-to-html-label'>max-priority-queue</span></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>10,000 refill & poll</td><td>8.85</td><td>113.01</td><td>1.90e-4</td></tr></table></div>
|
||||
</div><div class="json-to-html-collapse clearfix 0">
|
||||
<div class='collapsible level0' ><span class='json-to-html-label'>priority-queue</span></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>100,000 add & pop</td><td>104.23</td><td>9.59</td><td>0.00</td></tr></table></div>
|
||||
</div><div class="json-to-html-collapse clearfix 0">
|
||||
<div class='collapsible level0' ><span class='json-to-html-label'>deque</span></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 push</td><td>14.25</td><td>70.18</td><td>1.63e-4</td></tr><tr><td>1,000,000 push & pop</td><td>23.15</td><td>43.21</td><td>2.07e-4</td></tr><tr><td>1,000,000 push & shift</td><td>24.16</td><td>41.40</td><td>1.78e-4</td></tr><tr><td>1,000,000 unshift & shift</td><td>22.28</td><td>44.88</td><td>1.56e-4</td></tr></table></div>
|
||||
</div><div class="json-to-html-collapse clearfix 0">
|
||||
<div class='collapsible level0' ><span class='json-to-html-label'>queue</span></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 push</td><td>45.72</td><td>21.87</td><td>0.01</td></tr><tr><td>1,000,000 push & shift</td><td>81.75</td><td>12.23</td><td>0.00</td></tr></table></div>
|
||||
</div><div class="json-to-html-collapse clearfix 0">
|
||||
<div class='collapsible level0' ><span class='json-to-html-label'>stack</span></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 push</td><td>44.30</td><td>22.57</td><td>0.01</td></tr><tr><td>1,000,000 push & pop</td><td>49.69</td><td>20.12</td><td>0.01</td></tr></table></div>
|
||||
</div><div class="json-to-html-collapse clearfix 0">
|
||||
<div class='collapsible level0' ><span class='json-to-html-label'>trie</span></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>100,000 push</td><td>43.10</td><td>23.20</td><td>6.46e-4</td></tr><tr><td>100,000 getWords</td><td>85.45</td><td>11.70</td><td>0.00</td></tr></table></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 push</td><td>13.49</td><td>74.16</td><td>1.40e-4</td></tr><tr><td>1,000,000 push & pop</td><td>22.48</td><td>44.48</td><td>0.00</td></tr><tr><td>1,000,000 push & shift</td><td>23.42</td><td>42.71</td><td>1.59e-4</td></tr><tr><td>1,000,000 unshift & shift</td><td>21.62</td><td>46.25</td><td>2.77e-4</td></tr></table></div>
|
||||
</div>
|
||||
|
||||
[//]: # (No deletion!!! End of Replace Section)
|
||||
|
|
|
@ -6,127 +6,8 @@
|
|||
* @license MIT License
|
||||
*/
|
||||
|
||||
import { isObjOrFunc, rangeCheck, throwRangeError } from '../../utils';
|
||||
import { HashMapLinkedNode, IterableWithSizeOrLength, IterateDirection } from '../../types';
|
||||
|
||||
/**
|
||||
* Because the implementation of HashMap relies on JavaScript's built-in objects and arrays,
|
||||
* these underlying structures have already dealt with dynamic expansion and hash collisions.
|
||||
* Therefore, there is no need for additional logic to handle these issues.
|
||||
*/
|
||||
export class HashMapIterator<K, V> {
|
||||
readonly hashMap: HashMap<K, V>;
|
||||
readonly iterateDirection: IterateDirection;
|
||||
protected _node: HashMapLinkedNode<K, V>;
|
||||
protected readonly _sentinel: HashMapLinkedNode<K, V>;
|
||||
|
||||
/**
|
||||
* This is a constructor function for a linked list iterator in a HashMap data structure.
|
||||
* @param node - The `node` parameter is a reference to a `HashMapLinkedNode` object. This object
|
||||
* represents a node in a linked list used in a hash map data structure. It contains a key-value pair
|
||||
* and references to the previous and next nodes in the linked list.
|
||||
* @param sentinel - The `sentinel` parameter is a reference to a special node in a linked list. It
|
||||
* is used to mark the beginning or end of the list and is typically used in data structures like
|
||||
* hash maps or linked lists to simplify operations and boundary checks.
|
||||
* @param hashMap - A HashMap object that stores key-value pairs.
|
||||
* @param {IterateDirection} iterateDirection - The `iterateDirection` parameter is an optional
|
||||
* parameter that specifies the direction in which the iterator should iterate over the elements of
|
||||
* the HashMap. It can take one of the following values:
|
||||
* @returns The constructor does not return anything. It is used to initialize the properties and
|
||||
* methods of the object being created.
|
||||
*/
|
||||
constructor(
|
||||
node: HashMapLinkedNode<K, V>,
|
||||
sentinel: HashMapLinkedNode<K, V>,
|
||||
hashMap: HashMap<K, V>,
|
||||
iterateDirection: IterateDirection = IterateDirection.DEFAULT
|
||||
) {
|
||||
this._node = node;
|
||||
this._sentinel = sentinel;
|
||||
this.iterateDirection = iterateDirection;
|
||||
|
||||
if (this.iterateDirection === IterateDirection.DEFAULT) {
|
||||
this.prev = function () {
|
||||
if (this._node.prev === this._sentinel) {
|
||||
throwRangeError();
|
||||
}
|
||||
this._node = this._node.prev;
|
||||
return this;
|
||||
};
|
||||
this.next = function () {
|
||||
if (this._node === this._sentinel) {
|
||||
throwRangeError();
|
||||
}
|
||||
this._node = this._node.next;
|
||||
return this;
|
||||
};
|
||||
} else {
|
||||
this.prev = function () {
|
||||
if (this._node.next === this._sentinel) {
|
||||
throwRangeError();
|
||||
}
|
||||
this._node = this._node.next;
|
||||
return this;
|
||||
};
|
||||
this.next = function () {
|
||||
if (this._node === this._sentinel) {
|
||||
throwRangeError();
|
||||
}
|
||||
this._node = this._node.prev;
|
||||
return this;
|
||||
};
|
||||
}
|
||||
this.hashMap = hashMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* The above function returns a Proxy object that allows access to the key and value of a node in a
|
||||
* data structure.
|
||||
* @returns The code is returning a Proxy object.
|
||||
*/
|
||||
get current() {
|
||||
if (this._node === this._sentinel) {
|
||||
throwRangeError();
|
||||
}
|
||||
|
||||
return new Proxy(<[K, V]>(<unknown>[]), {
|
||||
get: (target, prop: '0' | '1') => {
|
||||
if (prop === '0') return this._node.key;
|
||||
else if (prop === '1') return this._node.value;
|
||||
target[0] = this._node.key;
|
||||
target[1] = this._node.value;
|
||||
return target[prop];
|
||||
},
|
||||
set: (_, prop: '1', newValue: V) => {
|
||||
if (prop !== '1') {
|
||||
throw new TypeError(`prop should be string '1'`);
|
||||
}
|
||||
this._node.value = newValue;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* The function checks if a node is accessible.
|
||||
* @returns a boolean value indicating whether the `_node` is not equal to the `_sentinel`.
|
||||
*/
|
||||
isAccessible() {
|
||||
return this._node !== this._sentinel;
|
||||
}
|
||||
|
||||
prev() {
|
||||
return this;
|
||||
}
|
||||
|
||||
next() {
|
||||
return this;
|
||||
}
|
||||
|
||||
clone() {
|
||||
return new HashMapIterator<K, V>(this._node, this._sentinel, this.hashMap, this.iterateDirection)
|
||||
}
|
||||
}
|
||||
import { isObjOrFunc, rangeCheck } from '../../utils';
|
||||
import { HashMapLinkedNode, IterableWithSizeOrLength } from '../../types';
|
||||
|
||||
export class HashMap<K = any, V = any> {
|
||||
readonly OBJ_KEY_INDEX = Symbol('OBJ_KEY_INDEX');
|
||||
|
@ -158,53 +39,6 @@ export class HashMap<K = any, V = any> {
|
|||
return this._size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The function returns a new iterator object for a HashMap.
|
||||
* @returns A new instance of the HashMapIterator class is being returned.
|
||||
*/
|
||||
get begin() {
|
||||
return new HashMapIterator<K, V>(this._head, this._sentinel, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The function returns a new HashMapIterator object with the _sentinel value as both the start and
|
||||
* end values.
|
||||
* @returns A new instance of the HashMapIterator class is being returned.
|
||||
*/
|
||||
get end() {
|
||||
return new HashMapIterator<K, V>(this._sentinel, this._sentinel, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The reverseBegin function returns a new HashMapIterator object that iterates over the elements of
|
||||
* a HashMap in reverse order.
|
||||
* @returns A new instance of the HashMapIterator class is being returned.
|
||||
*/
|
||||
get reverseBegin() {
|
||||
return new HashMapIterator<K, V>(this._tail, this._sentinel, this, IterateDirection.REVERSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The reverseEnd function returns a new HashMapIterator object that iterates over the elements of a
|
||||
* HashMap in reverse order.
|
||||
* @returns A new instance of the HashMapIterator class is being returned.
|
||||
*/
|
||||
get reverseEnd() {
|
||||
return new HashMapIterator<K, V>(this._sentinel, this._sentinel, this, IterateDirection.REVERSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
|
@ -231,6 +65,29 @@ export class HashMap<K = any, V = any> {
|
|||
return <[K, V]>[this._tail.key, this._tail.value];
|
||||
}
|
||||
|
||||
/**
|
||||
* The `begin()` function in TypeScript iterates over a linked list and yields key-value pairs.
|
||||
*/
|
||||
* begin() {
|
||||
let node = this._head;
|
||||
while (node !== this._sentinel) {
|
||||
yield [node.key, node.value];
|
||||
node = node.next;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The function `reverseBegin()` iterates over a linked list in reverse order, yielding each node's
|
||||
* key and value.
|
||||
*/
|
||||
* reverseBegin() {
|
||||
let node = this._tail;
|
||||
while (node !== this._sentinel) {
|
||||
yield [node.key, node.value];
|
||||
node = node.prev;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
|
@ -332,34 +189,6 @@ export class HashMap<K = any, V = any> {
|
|||
return <[K, V]>[node.key, node.value];
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The function `getIterator` returns a new instance of `HashMapIterator` based on the provided key
|
||||
* and whether it is an object key or not.
|
||||
* @param {K} key - The `key` parameter is the key used to retrieve the iterator from the HashMap. It
|
||||
* can be of any type, depending on how the HashMap is implemented.
|
||||
* @param {boolean} [isObjectKey] - The `isObjectKey` parameter is an optional boolean parameter that
|
||||
* indicates whether the `key` parameter is an object key. If `isObjectKey` is `true`, it means that
|
||||
* the `key` parameter is an object and needs to be handled differently. If `isObjectKey` is `false`
|
||||
* @returns a new instance of the `HashMapIterator` class.
|
||||
*/
|
||||
getIterator(key: K, isObjectKey?: boolean) {
|
||||
let node: HashMapLinkedNode<K, V>;
|
||||
if (isObjectKey) {
|
||||
const index = (<Record<symbol, number>>(<unknown>key))[this.OBJ_KEY_INDEX];
|
||||
if (index === undefined) {
|
||||
node = this._sentinel;
|
||||
} else {
|
||||
node = this._nodes[index];
|
||||
}
|
||||
} else {
|
||||
node = this._orgMap[<string>(<unknown>key)] || this._sentinel;
|
||||
}
|
||||
return new HashMapIterator<K, V>(node, this._sentinel, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
|
|
|
@ -40,7 +40,7 @@ export class Deque<E> {
|
|||
if ('length' in elements) {
|
||||
if (elements.length instanceof Function) _size = elements.length(); else _size = elements.length;
|
||||
} else {
|
||||
if (elements.size instanceof Function) _size = elements.size();else _size = elements.size;
|
||||
if (elements.size instanceof Function) _size = elements.size(); else _size = elements.size;
|
||||
}
|
||||
|
||||
this._bucketSize = bucketSize;
|
||||
|
@ -161,7 +161,10 @@ export class Deque<E> {
|
|||
this._firstInBucket = this._lastInBucket = this._bucketSize >> 1;
|
||||
}
|
||||
|
||||
*begin(): Generator<E> {
|
||||
/**
|
||||
* The below function is a generator that yields elements from a collection one by one.
|
||||
*/
|
||||
* begin(): Generator<E> {
|
||||
let index = 0;
|
||||
while (index < this.size) {
|
||||
yield this.getAt(index);
|
||||
|
@ -169,15 +172,11 @@ export class Deque<E> {
|
|||
}
|
||||
}
|
||||
|
||||
*end(): Generator<E> {
|
||||
let index = this.size;
|
||||
while (index > 0) {
|
||||
index--;
|
||||
yield this.getAt(index);
|
||||
}
|
||||
}
|
||||
|
||||
*reverseBegin(): Generator<E> {
|
||||
/**
|
||||
* The function `reverseBegin()` is a generator that yields elements in reverse order starting from
|
||||
* the last element.
|
||||
*/
|
||||
* reverseBegin(): Generator<E> {
|
||||
let index = this.size - 1;
|
||||
while (index >= 0) {
|
||||
yield this.getAt(index);
|
||||
|
@ -185,14 +184,6 @@ export class Deque<E> {
|
|||
}
|
||||
}
|
||||
|
||||
*reverseEnd(): Generator<E> {
|
||||
let index = -1;
|
||||
while (index < this.size - 1) {
|
||||
index++;
|
||||
yield this.getAt(index);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity - Amortized O(1) (possible reallocation)
|
||||
* Space Complexity - O(n) (due to potential resizing).
|
||||
|
|
|
@ -172,15 +172,14 @@ describe('HashMap', () => {
|
|||
stdMap.forEach((value, key) => {
|
||||
if (index === 0) {
|
||||
expect(hashMap.first).toEqual([key, value]);
|
||||
expect(hashMap.begin.current[0]).toEqual(key);
|
||||
expect(hashMap.begin().next().value).toEqual([key, value]);
|
||||
} else if (index === hashMap.size - 1) {
|
||||
expect(hashMap.last).toEqual([key, value]);
|
||||
expect(hashMap.reverseBegin.current[0]).toEqual(key);
|
||||
expect(hashMap.reverseBegin().next().value).toEqual([key, value]);
|
||||
} else if (index <= 1000) {
|
||||
expect(hashMap.getAt(index)).toEqual([key, value]);
|
||||
}
|
||||
expect(hashMap.get(key)).toEqual(value);
|
||||
expect(hashMap.getIterator(key).current[1]).toEqual(value);
|
||||
index++;
|
||||
});
|
||||
}
|
||||
|
@ -210,8 +209,8 @@ describe('HashMap', () => {
|
|||
test('should iterate correctly with reverse iterators', () => {
|
||||
hashMap.set('key1', 'value1');
|
||||
hashMap.set('key2', 'value2');
|
||||
const iterator = hashMap.reverseBegin;
|
||||
expect(iterator.next().current).toEqual(['key1', 'value1']);
|
||||
const iterator = hashMap.reverseBegin();
|
||||
expect(iterator.next().value).toEqual(['key2', 'value2']);
|
||||
});
|
||||
|
||||
test('should return the last element', () => {
|
||||
|
|
|
@ -434,19 +434,6 @@ describe('Deque', () => {
|
|||
});
|
||||
});
|
||||
|
||||
//Test end method
|
||||
describe('end()', () => {
|
||||
it('should return an iterator at the end of the deque', () => {
|
||||
deque.push(1);
|
||||
deque.push(2);
|
||||
deque.push(3);
|
||||
|
||||
const iterator = deque.end();
|
||||
|
||||
expect(iterator.next().value).toBe(3);
|
||||
});
|
||||
});
|
||||
|
||||
// Test the reverse Begin method
|
||||
describe('reverseBegin()', () => {
|
||||
it('should return a reverse iterator at the beginning of the deque', () => {
|
||||
|
@ -460,16 +447,4 @@ describe('Deque', () => {
|
|||
});
|
||||
});
|
||||
|
||||
// Test the reverse End method
|
||||
describe('reverseEnd()', () => {
|
||||
it('should return a reverse iterator at the end of the deque', () => {
|
||||
deque.push(1);
|
||||
deque.push(2);
|
||||
deque.push(3);
|
||||
|
||||
const iterator = deque.reverseEnd();
|
||||
|
||||
expect(iterator.next().value).toBe(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue