mqtt and socket added

This commit is contained in:
Miisa Ekholm
2022-10-21 11:17:48 +03:00
parent 52370df9ce
commit 9e3d953b9e
751 changed files with 185105 additions and 153 deletions

127
WebUI/node_modules/js-sdsl/CHANGELOG.md generated vendored Normal file
View File

@@ -0,0 +1,127 @@
# Change Log
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog and this project adheres to Semantic Versioning.
## [4.1.4] - 2022.09.07
### Added
- Add some notes.
### Changed
- Optimize hash container.
- Abstracting out the hash container.
### Fixed
- Fixed tree get height function return one larger than the real height.
- Tree-shaking not work in ES module.
- `Queue` and `Deque` should return `undefined` when container is empty.
## [4.1.4-beta.0] - 2022.08.31
### Added
- Add function update key by iterator.
- Add iterator copy function to get a copy of itself.
- Add insert by iterator hint function in tree container.
### Changed
- Changed OrderedMap's iterator pointer get from `Object.defineProperty'` to `Proxy`.
- Improve iterator performance by remove some judgment.
- Change iterator type description from `normal` and `reverse` to boolean.
## [4.1.2-beta.0] - 2022.08.27
### Added
- Make `SequentialContainer` and `TreeBaseContainer` export in the index.
### Changed
- Change rbTree binary search from recursive to loop implementation (don't effect using).
- Reduce memory waste during deque initialization.
## Fixed
- Fixed priority queue not dereference on pop.
## [4.1.1] - 2022.08.23
### Fixed
- Forgot to reset root node on rotation in red-black tree delete operation.
- Fix iterator invalidation after tree container removes iterator.
## [4.1.0] - 2022.08.21
### Changed
- Change some functions from recursive to loop implementation (don't effect using).
- Change some iterator function parameter type.
- Change commonjs target to `es6`.
- Change `Deque` from sequential queue to circular queue.
- Optimize so many places (don't affect using).
### Fixed
- Fix `Vector` length bugs.
## [4.0.3] - 2022-08-13
### Changed
- Change `if (this.empty())` to `if (!this.length)`.
- Change some unit test.
- Change class type and optimized type design
### Fixed
- Fix can push undefined to deque.
## [4.0.0] - 2022-07-30
### Changed
- Remove InternalError error as much as possible (don't affect using).
- Change `HashSet` api `eraseElementByValue`'s name to `eraseElementByKey`.
- Change some unit tests to improve coverage (don't affect using).
## [4.0.0-beta.0] - 2022-07-24
### Added
- Complete test examples (don't effect using).
- The error thrown is standardized, you can catch it according to the error type.
### Changed
- Refactor all container from function to class (don't affect using).
- Abstracting tree containers and hash containers, change `Set`'s and `Map`'s name to `OrderedSet` and `OrderedMap` to distinguish it from the official container.
- Change `OrderedSet` api `eraseElementByValue`'s name to `eraseElementByKey`.
### Fixed
- Fixed so many bugs.
## [3.0.0-beta.0] - 2022-04-29
### Added
- Bidirectional iterator is provided for all containers except Stack, Queue, HashSet and HashMap.
- Added begin, end, rBegin and rEnd functions to some containers for using iterator.
- Added `eraseElementByIterator` function.
### Changed
- Changed Pair type `T, K` to `K, V` (don't affect using).
- Changed `find`, `lowerBound`, `upperBound`, `reverseLowerBound` and `reverseUpperBound` function's returned value to `Iterator`.
### Fixed
- Fixed an error when the insert value was 0.
- Fixed the problem that the lower version browser does not recognize symbol Compilation error caused by iterator.

21
WebUI/node_modules/js-sdsl/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 Zilong Yao
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

146
WebUI/node_modules/js-sdsl/README.md generated vendored Normal file
View File

@@ -0,0 +1,146 @@
<p align="center">
<a href="https://js-sdsl.github.io/" target="_blank" rel="noopener noreferrer">
<img src="https://js-sdsl.github.io/assets/logo-removebg.png" alt="js-sdsl logo" width="120" />
</a>
</p>
<h3><p align="center">A javascript standard data structure library which benchmark against C++ STL</p></h3>
<p align="center">
<a href="https://www.npmjs.com/package/js-sdsl"><img src="https://img.shields.io/npm/v/js-sdsl.svg" alt="NPM Version" /></a>
<a href="https://github.com/js-sdsl/js-sdsl/actions/workflows/build.yml"><img src="https://img.shields.io/github/workflow/status/js-sdsl/js-sdsl/js-sdsl%20CI" alt="Build Status" /></a>
<a href='https://coveralls.io/github/js-sdsl/js-sdsl?branch=main'><img src='https://coveralls.io/repos/github/js-sdsl/js-sdsl/badge.svg?branch=main' alt='Coverage Status' /></a>
<a href="https://github.com/js-sdsl/js-sdsl"><img src="https://img.shields.io/github/stars/js-sdsl/js-sdsl.svg" alt="GITHUB Star" /></a>
<a href="https://npmcharts.com/compare/js-sdsl?minimal=true"><img src="https://img.shields.io/npm/dm/js-sdsl.svg" alt="NPM Downloads" /></a>
<a href="https://unpkg.com/js-sdsl/dist/umd/js-sdsl.min.js"><img src="https://img.badgesize.io/https://unpkg.com/js-sdsl/dist/umd/js-sdsl.min.js?compression=gzip&style=flat-square/" alt="Gzip Size"></a>
<a href="https://openbase.com/js/js-sdsl?utm_source=embedded&amp;utm_medium=badge&amp;utm_campaign=rate-badge"><img src="https://badges.openbase.com/js/rating/js-sdsl.svg?token=fh3LMNOV+JSWykSjtg1rA8kouSYkJoIDzGbvaByq5X0=" alt="Rate this package"/></a>
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/npm/l/js-sdsl.svg" alt="MIT-license" /></a>
<a href="https://github.com/js-sdsl/js-sdsl/"><img src="https://img.shields.io/github/languages/top/js-sdsl/js-sdsl.svg" alt="GITHUB-language" /></a>
</p>
<p align="center">English | <a href="https://github.com/js-sdsl/js-sdsl/blob/main/README.zh-CN.md">简体中文</a></p>
## Included data structures
- Vector
- Stack
- Queue
- LinkList
- Deque
- PriorityQueue
- OrderedSet (using RBTree)
- OrderedMap (using RBTree)
- HashSet
- HashMap
## Benchmark
We are benchmarking against other popular data structure libraries. In some ways we're better than the best library. See [benchmark](https://js-sdsl.github.io/#/test/benchmark-analyze).
## Supported platforms
- node.js (using commonjs)
- react/vue (using es5)
- browser (support most browsers)
## Download
Download directly
- [js-sdsl.js](https://unpkg.com/js-sdsl/dist/umd/js-sdsl.js) (for development)
- [js-sdsl.min.js](https://unpkg.com/js-sdsl/dist/umd/js-sdsl.min.js) (for production)
Or install js-sdsl using npm
```bash
npm install js-sdsl
```
## Usage
You can visit our [official website](https://js-sdsl.github.io/) to get more information.
To help you have a better use, we also provide this [API document](https://js-sdsl.github.io/js-sdsl/index.html).
### For browser
```html
<!-- you can download the file locally and import it or import it dynamically by using url. -->
<script src="https://unpkg.com/js-sdsl/dist/umd/js-sdsl.min.js"></script>
<script>
const {
Vector,
Stack,
Queue,
LinkList,
Deque,
PriorityQueue,
OrderedSet,
OrderedMap,
HashSet,
HashMap
} = sdsl;
const myOrderedMap = new OrderedMap();
myOrderedMap.setElement(1, 2);
console.log(myOrderedMap.getElementByKey(1)); // 2
</script>
```
### For npm
```javascript
// esModule
import { OrderedMap } from 'js-sdsl';
// commonJs
const { OrderedMap } = require('js-sdsl');
const myOrderedMap = new OrderedMap();
myOrderedMap.setElement(1, 2);
console.log(myOrderedMap.getElementByKey(1)); // 2
```
## Build by source code
You can pull this repository and run `yarn build` to rebuild this library.
## Test
### Unit test
We use jest library to write unit tests, you can see test coverage on [coveralls](https://coveralls.io/github/js-sdsl/js-sdsl). You can run `yarn test:unit` command to reproduce it.
### For performance
We tested most of the functions for efficiency. You can go to [`gh-pages/performance.md`](https://github.com/js-sdsl/js-sdsl/blob/gh-pages/performance.md) to see our running results or reproduce it with `yarn test:performance` command.
You can also visit [here](https://js-sdsl.github.io/#/test/performance-test) to get the result.
## Maintainers
[@ZLY201](https://github.com/ZLY201)
## Contributing
Feel free to dive in! Open an issue or submit PRs. It may be helpful to read the [Contributor Guide](https://github.com/js-sdsl/js-sdsl/blob/main/.github/CONTRIBUTING.md).
### Contributors
Thanks goes to these wonderful people:
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<table>
<tr>
<td align="center"><a href="https://www.linkedin.com/in/takatoshi-kondo-02a91410/"><img src="https://avatars.githubusercontent.com/u/275959?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Takatoshi Kondo</b></sub></a><br /><a href="https://github.com/js-sdsl/js-sdsl/commits?author=redboltz" title="Code">💻</a> <a href="https://github.com/js-sdsl/js-sdsl/commits?author=redboltz" title="Tests">⚠️</a></td>
</tr>
</table>
<!-- markdownlint-restore -->
<!-- prettier-ignore-end -->
<!-- ALL-CONTRIBUTORS-LIST:END -->
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
## License
[MIT](https://github.com/js-sdsl/js-sdsl/blob/main/LICENSE) © ZLY201

148
WebUI/node_modules/js-sdsl/README.zh-CN.md generated vendored Normal file
View File

@@ -0,0 +1,148 @@
<p align="center">
<a href="https://js-sdsl.github.io/" target="_blank" rel="noopener noreferrer">
<img src="https://js-sdsl.github.io/assets/logo-removebg.png" alt="js-sdsl logo" width="120" />
</a>
</p>
<h3><p align="center">一个参考 C++ STL 实现的 JavaScript 标准数据结构库</p></h3>
<p align="center">
<a href="https://www.npmjs.com/package/js-sdsl"><img src="https://img.shields.io/npm/v/js-sdsl.svg" alt="NPM Version" /></a>
<a href="https://github.com/js-sdsl/js-sdsl/actions/workflows/build.yml"><img src="https://img.shields.io/github/workflow/status/js-sdsl/js-sdsl/js-sdsl%20CI" alt="Build Status" /></a>
<a href='https://coveralls.io/github/js-sdsl/js-sdsl?branch=main'><img src='https://coveralls.io/repos/github/js-sdsl/js-sdsl/badge.svg?branch=main' alt='Coverage Status' /></a>
<a href="https://github.com/js-sdsl/js-sdsl"><img src="https://img.shields.io/github/stars/js-sdsl/js-sdsl.svg" alt="GITHUB Star" /></a>
<a href="https://npmcharts.com/compare/js-sdsl?minimal=true"><img src="https://img.shields.io/npm/dm/js-sdsl.svg" alt="NPM Downloads" /></a>
<a href="https://unpkg.com/js-sdsl/dist/umd/js-sdsl.min.js"><img src="https://img.badgesize.io/https://unpkg.com/js-sdsl/dist/umd/js-sdsl.min.js?compression=gzip&style=flat-square/" alt="Gzip Size"></a>
<a href="https://openbase.com/js/js-sdsl?utm_source=embedded&amp;utm_medium=badge&amp;utm_campaign=rate-badge"><img src="https://badges.openbase.com/js/rating/js-sdsl.svg?token=fh3LMNOV+JSWykSjtg1rA8kouSYkJoIDzGbvaByq5X0=" alt="Rate this package"/></a>
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/npm/l/js-sdsl.svg" alt="MIT-license" /></a>
<a href="https://github.com/js-sdsl/js-sdsl/"><img src="https://img.shields.io/github/languages/top/js-sdsl/js-sdsl.svg" alt="GITHUB-language" /></a>
</p>
<p align="center"><a href="https://github.com/js-sdsl/js-sdsl/blob/main/README.md">English</a> | 简体中文</p>
## 包含的数据结构
- Vector
- Stack
- Queue
- LinkList
- Deque
- PriorityQueue
- OrderedSet (using RBTree)
- OrderedMap (using RBTree)
- HashSet
- HashMap
## Benchmark
我们和其他数据结构库进行了基准测试,在某些场景我们甚至超过了当前最流行的库
查看 [benchmark](https://js-sdsl.github.io/#/zh-cn/test/benchmark-analyze) 以获取更多信息
## 支持的平台
- node.js (using commonjs)
- react/vue (using es5)
- browser (support most browsers)
## 下载
使用 cdn 直接引入
- [js-sdsl.js](https://unpkg.com/js-sdsl/dist/umd/js-sdsl.js) (for development)
- [js-sdsl.min.js](https://unpkg.com/js-sdsl/dist/umd/js-sdsl.min.js) (for production)
使用 npm 下载
```bash
npm install js-sdsl
```
## 使用说明
您可以[访问我们的主页](https://js-sdsl.github.io/)获取更多信息
并且我们提供了完整的 [API 文档](https://js-sdsl.github.io/js-sdsl/index.html)供您参考
### 在浏览器中使用
```html
<!-- you can download the file locally and import it or import it dynamically by using url. -->
<script src="https://unpkg.com/js-sdsl/dist/umd/js-sdsl.min.js"></script>
<script>
const {
Vector,
Stack,
Queue,
LinkList,
Deque,
PriorityQueue,
OrderedSet,
OrderedMap,
HashSet,
HashMap
} = sdsl;
const myOrderedMap = new OrderedMap();
myOrderedMap.setElement(1, 2);
console.log(myOrderedMap.getElementByKey(1)); // 2
</script>
```
### npm 引入
```javascript
// esModule
import { OrderedMap } from 'js-sdsl';
// commonJs
const { OrderedMap } = require('js-sdsl');
const myOrderedMap = new OrderedMap();
myOrderedMap.setElement(1, 2);
console.log(myOrderedMap.getElementByKey(1)); // 2
```
## 从源码构建
您可以克隆此仓库后运行 `yarn build` 命令重新构建这个库
## 测试
### 单元测试
我们使用 `jest` 库来编写我们的单元测试,并将结果同步到了 [coveralls](https://coveralls.io/github/js-sdsl/js-sdsl) 上,你可以使用 `yarn test:unit` 命令来重建它
### 对于性能的校验
我们对于编写的所有 API 进行了性能测试,并将结果同步到了 [`gh-pages/performance.md`](https://github.com/js-sdsl/js-sdsl/blob/gh-pages/performance.md) 中,你可以通过 `yarn test:performance` 命令来重现它
您也可以访问[我们的网站](https://js-sdsl.github.io/#/zh-cn/test/performance-test)来获取结果
## 维护者
[@ZLY201](https://github.com/ZLY201)
## 贡献
我们欢迎所有的开发人员提交 issue 或 pull request阅读[贡献者指南](https://github.com/js-sdsl/js-sdsl/blob/main/.github/CONTRIBUTING.md)可能会有所帮助
### 贡献者
感谢对本项目做出贡献的开发者们:
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<table>
<tr>
<td align="center"><a href="https://www.linkedin.com/in/takatoshi-kondo-02a91410/"><img src="https://avatars.githubusercontent.com/u/275959?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Takatoshi Kondo</b></sub></a><br /><a href="https://github.com/js-sdsl/js-sdsl/commits?author=redboltz" title="Code">💻</a> <a href="https://github.com/js-sdsl/js-sdsl/commits?author=redboltz" title="Tests">⚠️</a></td>
</tr>
</table>
<!-- markdownlint-restore -->
<!-- prettier-ignore-end -->
<!-- ALL-CONTRIBUTORS-LIST:END -->
本项目遵循 [all-contributors](https://github.com/all-contributors/all-contributors) 规范。 欢迎任何形式的贡献!
## 许可证
[MIT](https://github.com/js-sdsl/js-sdsl/blob/main/LICENSE) © ZLY201

View File

@@ -0,0 +1,124 @@
export declare abstract class ContainerIterator<T> {
static readonly NORMAL = false;
static readonly REVERSE = true;
/**
* @description Iterator's type.
*/
readonly iteratorType: boolean;
protected node: unknown;
protected constructor(iteratorType?: boolean);
/**
* @description Pointers to element.
* @return The value of the pointer's element.
*/
abstract get pointer(): T;
/**
* @description Set pointer's value (some containers are unavailable).
* @param newValue The new value you want to set.
*/
abstract set pointer(newValue: T);
/**
* @description Move `this` iterator to pre.
*/
abstract pre(): this;
/**
* @description Move `this` iterator to next.
*/
abstract next(): this;
/**
* @param obj The other iterator you want to compare.
* @return Boolean about if this equals to obj.
* @example container.find(1).equals(container.end());
*/
abstract equals(obj: ContainerIterator<T>): boolean;
/**
* @description Get a copy of itself.<br/>
* We do not guarantee the safety of this function.<br/>
* Please ensure that the iterator will not fail.
* @return The copy of self.
*/
abstract copy(): ContainerIterator<T>;
}
export declare abstract class Base {
/**
* @description Container's size.
* @protected
*/
protected length: number;
/**
* @return The size of the container.
*/
size(): number;
/**
* @return Boolean about if the container is empty.
*/
empty(): boolean;
/**
* @description Clear the container.
*/
abstract clear(): void;
}
export declare abstract class Container<T> extends Base {
/**
* @return Iterator pointing to the beginning element.
*/
abstract begin(): ContainerIterator<T>;
/**
* @return Iterator pointing to the super end like c++.
*/
abstract end(): ContainerIterator<T>;
/**
* @return Iterator pointing to the end element.
*/
abstract rBegin(): ContainerIterator<T>;
/**
* @return Iterator pointing to the super begin like c++.
*/
abstract rEnd(): ContainerIterator<T>;
/**
* @return The first element of the container.
*/
abstract front(): T | undefined;
/**
* @return The last element of the container.
*/
abstract back(): T | undefined;
/**
* @description Iterate over all elements in the container.
* @param callback Callback function like Array.forEach.
*/
abstract forEach(callback: (element: T, index: number) => void): void;
/**
* @param element The element you want to find.
* @return An iterator pointing to the element if found, or super end if not found.
*/
abstract find(element: T): ContainerIterator<T>;
/**
* @description Gets the value of the element at the specified position.
*/
abstract getElementByPos(pos: number): T;
/**
* @description Removes the element at the specified position.
* @param pos The element's position you want to remove.
*/
abstract eraseElementByPos(pos: number): void;
/**
* @description Removes element by iterator and move `iter` to next.
* @param iter The iterator you want to erase.
* @example container.eraseElementByIterator(container.begin());
*/
abstract eraseElementByIterator(iter: ContainerIterator<T>): ContainerIterator<T>;
/**
* @description Using for 'for...of' syntax like Array.
*/
abstract [Symbol.iterator](): Generator<T, void, undefined>;
}
export declare type initContainer<T> = ({
size: number;
} | {
length: number;
} | {
size(): number;
}) & {
forEach(callback: (element: T) => void): void;
};

View File

@@ -0,0 +1,36 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Container = exports.Base = exports.ContainerIterator = void 0;
class ContainerIterator {
constructor(iteratorType = ContainerIterator.NORMAL) {
this.iteratorType = iteratorType;
}
}
exports.ContainerIterator = ContainerIterator;
ContainerIterator.NORMAL = false;
ContainerIterator.REVERSE = true;
class Base {
constructor() {
/**
* @description Container's size.
* @protected
*/
this.length = 0;
}
/**
* @return The size of the container.
*/
size() {
return this.length;
}
/**
* @return Boolean about if the container is empty.
*/
empty() {
return this.length === 0;
}
}
exports.Base = Base;
class Container extends Base {
}
exports.Container = Container;

View File

@@ -0,0 +1,32 @@
import { Base, Container } from "../../ContainerBase/index";
declare abstract class HashContainer<K> extends Base {
protected static readonly sigma = 0.75;
protected static readonly treeifyThreshold = 8;
protected static readonly untreeifyThreshold = 6;
protected static readonly minTreeifySize = 64;
protected static readonly maxBucketNum: number;
protected bucketNum: number;
protected initBucketNum: number;
protected hashFunc: (x: K) => number;
protected abstract hashTable: Container<unknown>[];
protected constructor(initBucketNum?: number, hashFunc?: (x: K) => number);
clear(): void;
/**
* @description Growth the hash table.
* @protected
*/
protected abstract reAllocate(): void;
abstract forEach(callback: (element: unknown, index: number) => void): void;
/**
* @description Remove the elements of the specified value.
* @param key The element you want to remove.
*/
abstract eraseElementByKey(key: K): void;
/**
* @param key The element you want to find.
* @return Boolean about if the specified element in the hash set.
*/
abstract find(key: K): void;
abstract [Symbol.iterator](): Generator<unknown, void, undefined>;
}
export default HashContainer;

View File

@@ -0,0 +1,39 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const index_1 = require("../../ContainerBase/index");
class HashContainer extends index_1.Base {
constructor(initBucketNum = 16, hashFunc = (x) => {
let str;
if (typeof x !== 'string') {
str = JSON.stringify(x);
}
else
str = x;
let hashCode = 0;
const strLength = str.length;
for (let i = 0; i < strLength; i++) {
const ch = str.charCodeAt(i);
hashCode = ((hashCode << 5) - hashCode) + ch;
hashCode |= 0;
}
return hashCode >>> 0;
}) {
super();
if (initBucketNum < 16 || (initBucketNum & (initBucketNum - 1)) !== 0) {
throw new RangeError('InitBucketNum range error');
}
this.bucketNum = this.initBucketNum = initBucketNum;
this.hashFunc = hashFunc;
}
clear() {
this.length = 0;
this.bucketNum = this.initBucketNum;
this.hashTable = [];
}
}
HashContainer.sigma = 0.75;
HashContainer.treeifyThreshold = 8;
HashContainer.untreeifyThreshold = 6;
HashContainer.minTreeifySize = 64;
HashContainer.maxBucketNum = (1 << 30);
exports.default = HashContainer;

View File

@@ -0,0 +1,26 @@
import HashContainer from './Base/index';
import Vector from '../SequentialContainer/Vector';
import OrderedMap from '../TreeContainer/OrderedMap';
import { initContainer } from "../ContainerBase/index";
declare class HashMap<K, V> extends HashContainer<K> {
protected hashTable: (Vector<[K, V]> | OrderedMap<K, V>)[];
constructor(container?: initContainer<[K, V]>, initBucketNum?: number, hashFunc?: (x: K) => number);
protected reAllocate(): void;
forEach(callback: (element: [K, V], index: number) => void): void;
/**
* @description Insert a new key-value pair to hash map or set value by key.
* @param key The key you want to insert.
* @param value The value you want to insert.
* @example HashMap.setElement(1, 2); // insert a key-value pair [1, 2]
*/
setElement(key: K, value: V): void;
/**
* @description Get the value of the element which has the specified key.
* @param key The key you want to get.
*/
getElementByKey(key: K): V | undefined;
eraseElementByKey(key: K): void;
find(key: K): boolean;
[Symbol.iterator](): Generator<[K, V], void, unknown>;
}
export default HashMap;

View File

@@ -0,0 +1,200 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const index_1 = __importDefault(require("./Base/index"));
const Vector_1 = __importDefault(require("../SequentialContainer/Vector"));
const OrderedMap_1 = __importDefault(require("../TreeContainer/OrderedMap"));
class HashMap extends index_1.default {
constructor(container = [], initBucketNum, hashFunc) {
super(initBucketNum, hashFunc);
this.hashTable = [];
container.forEach(element => this.setElement(element[0], element[1]));
}
reAllocate() {
if (this.bucketNum >= index_1.default.maxBucketNum)
return;
const newHashTable = [];
const originalBucketNum = this.bucketNum;
this.bucketNum <<= 1;
const keys = Object.keys(this.hashTable);
const keyNums = keys.length;
for (let i = 0; i < keyNums; ++i) {
const index = parseInt(keys[i]);
const container = this.hashTable[index];
const size = container.size();
if (size === 0)
continue;
if (size === 1) {
const element = container.front();
newHashTable[this.hashFunc(element[0]) & (this.bucketNum - 1)] = new Vector_1.default([element], false);
continue;
}
const lowList = [];
const highList = [];
container.forEach(element => {
const hashCode = this.hashFunc(element[0]);
if ((hashCode & originalBucketNum) === 0) {
lowList.push(element);
}
else
highList.push(element);
});
if (container instanceof OrderedMap_1.default) {
if (lowList.length > index_1.default.untreeifyThreshold) {
newHashTable[index] = new OrderedMap_1.default(lowList);
}
else if (lowList.length) {
newHashTable[index] = new Vector_1.default(lowList, false);
}
if (highList.length > index_1.default.untreeifyThreshold) {
newHashTable[index + originalBucketNum] = new OrderedMap_1.default(highList);
}
else if (highList.length) {
newHashTable[index + originalBucketNum] = new Vector_1.default(highList, false);
}
}
else {
if (lowList.length >= index_1.default.treeifyThreshold) {
newHashTable[index] = new OrderedMap_1.default(lowList);
}
else if (lowList.length) {
newHashTable[index] = new Vector_1.default(lowList, false);
}
if (highList.length >= index_1.default.treeifyThreshold) {
newHashTable[index + originalBucketNum] = new OrderedMap_1.default(highList);
}
else if (highList.length) {
newHashTable[index + originalBucketNum] = new Vector_1.default(highList, false);
}
}
}
this.hashTable = newHashTable;
}
forEach(callback) {
const containers = Object.values(this.hashTable);
const containersNum = containers.length;
let index = 0;
for (let i = 0; i < containersNum; ++i) {
containers[i].forEach(element => callback(element, index++));
}
}
/**
* @description Insert a new key-value pair to hash map or set value by key.
* @param key The key you want to insert.
* @param value The value you want to insert.
* @example HashMap.setElement(1, 2); // insert a key-value pair [1, 2]
*/
setElement(key, value) {
const index = this.hashFunc(key) & (this.bucketNum - 1);
const container = this.hashTable[index];
if (!container) {
this.length += 1;
this.hashTable[index] = new Vector_1.default([[key, value]], false);
}
else {
const preSize = container.size();
if (container instanceof Vector_1.default) {
for (const pair of container) {
if (pair[0] === key) {
pair[1] = value;
return;
}
}
container.pushBack([key, value]);
if (preSize + 1 >= HashMap.treeifyThreshold) {
if (this.bucketNum <= HashMap.minTreeifySize) {
this.length += 1;
this.reAllocate();
return;
}
this.hashTable[index] = new OrderedMap_1.default(this.hashTable[index]);
}
this.length += 1;
}
else {
container.setElement(key, value);
const curSize = container.size();
this.length += curSize - preSize;
}
}
if (this.length > this.bucketNum * HashMap.sigma) {
this.reAllocate();
}
}
/**
* @description Get the value of the element which has the specified key.
* @param key The key you want to get.
*/
getElementByKey(key) {
const index = this.hashFunc(key) & (this.bucketNum - 1);
const container = this.hashTable[index];
if (!container)
return undefined;
if (container instanceof OrderedMap_1.default) {
return container.getElementByKey(key);
}
else {
for (const pair of container) {
if (pair[0] === key)
return pair[1];
}
return undefined;
}
}
eraseElementByKey(key) {
const index = this.hashFunc(key) & (this.bucketNum - 1);
const container = this.hashTable[index];
if (!container)
return;
if (container instanceof Vector_1.default) {
let pos = 0;
for (const pair of container) {
if (pair[0] === key) {
container.eraseElementByPos(pos);
this.length -= 1;
return;
}
pos += 1;
}
}
else {
const preSize = container.size();
container.eraseElementByKey(key);
const curSize = container.size();
this.length += curSize - preSize;
if (curSize <= index_1.default.untreeifyThreshold) {
this.hashTable[index] = new Vector_1.default(container);
}
}
}
find(key) {
const index = this.hashFunc(key) & (this.bucketNum - 1);
const container = this.hashTable[index];
if (!container)
return false;
if (container instanceof OrderedMap_1.default) {
return !container.find(key)
.equals(container.end());
}
for (const pair of container) {
if (pair[0] === key)
return true;
}
return false;
}
[Symbol.iterator]() {
return function* () {
const containers = Object.values(this.hashTable);
const containersNum = containers.length;
for (let i = 0; i < containersNum; ++i) {
const container = containers[i];
for (const element of container) {
yield element;
}
}
}.bind(this)();
}
}
exports.default = HashMap;

View File

@@ -0,0 +1,19 @@
import HashContainer from './Base/index';
import Vector from '../SequentialContainer/Vector';
import OrderedSet from '../TreeContainer/OrderedSet';
import { initContainer } from "../ContainerBase/index";
declare class HashSet<K> extends HashContainer<K> {
protected hashTable: (Vector<K> | OrderedSet<K>)[];
constructor(container?: initContainer<K>, initBucketNum?: number, hashFunc?: (x: K) => number);
protected reAllocate(): void;
forEach(callback: (element: K, index: number) => void): void;
/**
* @description Insert element to hash set.
* @param element The element you want to insert.
*/
insert(element: K): void;
eraseElementByKey(key: K): void;
find(element: K): boolean;
[Symbol.iterator](): Generator<K, void, unknown>;
}
export default HashSet;

View File

@@ -0,0 +1,164 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const index_1 = __importDefault(require("./Base/index"));
const Vector_1 = __importDefault(require("../SequentialContainer/Vector"));
const OrderedSet_1 = __importDefault(require("../TreeContainer/OrderedSet"));
class HashSet extends index_1.default {
constructor(container = [], initBucketNum, hashFunc) {
super(initBucketNum, hashFunc);
this.hashTable = [];
container.forEach(element => this.insert(element));
}
reAllocate() {
if (this.bucketNum >= index_1.default.maxBucketNum)
return;
const newHashTable = [];
const originalBucketNum = this.bucketNum;
this.bucketNum <<= 1;
const keys = Object.keys(this.hashTable);
const keyNums = keys.length;
for (let i = 0; i < keyNums; ++i) {
const index = parseInt(keys[i]);
const container = this.hashTable[index];
const size = container.size();
if (size === 0)
continue;
if (size === 1) {
const element = container.front();
newHashTable[this.hashFunc(element) & (this.bucketNum - 1)] = new Vector_1.default([element], false);
continue;
}
const lowList = [];
const highList = [];
container.forEach(element => {
const hashCode = this.hashFunc(element);
if ((hashCode & originalBucketNum) === 0) {
lowList.push(element);
}
else
highList.push(element);
});
if (container instanceof OrderedSet_1.default) {
if (lowList.length > index_1.default.untreeifyThreshold) {
newHashTable[index] = new OrderedSet_1.default(lowList);
}
else if (lowList.length) {
newHashTable[index] = new Vector_1.default(lowList, false);
}
if (highList.length > index_1.default.untreeifyThreshold) {
newHashTable[index + originalBucketNum] = new OrderedSet_1.default(highList);
}
else if (highList.length) {
newHashTable[index + originalBucketNum] = new Vector_1.default(highList, false);
}
}
else {
if (lowList.length >= index_1.default.treeifyThreshold) {
newHashTable[index] = new OrderedSet_1.default(lowList);
}
else if (lowList.length) {
newHashTable[index] = new Vector_1.default(lowList, false);
}
if (highList.length >= index_1.default.treeifyThreshold) {
newHashTable[index + originalBucketNum] = new OrderedSet_1.default(highList);
}
else if (highList.length) {
newHashTable[index + originalBucketNum] = new Vector_1.default(highList, false);
}
}
}
this.hashTable = newHashTable;
}
forEach(callback) {
const containers = Object.values(this.hashTable);
const containersNum = containers.length;
let index = 0;
for (let i = 0; i < containersNum; ++i) {
containers[i].forEach(element => callback(element, index++));
}
}
/**
* @description Insert element to hash set.
* @param element The element you want to insert.
*/
insert(element) {
const index = this.hashFunc(element) & (this.bucketNum - 1);
const container = this.hashTable[index];
if (!container) {
this.hashTable[index] = new Vector_1.default([element], false);
this.length += 1;
}
else {
const preSize = container.size();
if (container instanceof Vector_1.default) {
if (!container.find(element)
.equals(container.end()))
return;
container.pushBack(element);
if (preSize + 1 >= index_1.default.treeifyThreshold) {
if (this.bucketNum <= index_1.default.minTreeifySize) {
this.length += 1;
this.reAllocate();
return;
}
this.hashTable[index] = new OrderedSet_1.default(container);
}
this.length += 1;
}
else {
container.insert(element);
const curSize = container.size();
this.length += curSize - preSize;
}
}
if (this.length > this.bucketNum * index_1.default.sigma) {
this.reAllocate();
}
}
eraseElementByKey(key) {
const index = this.hashFunc(key) & (this.bucketNum - 1);
const container = this.hashTable[index];
if (!container)
return;
const preSize = container.size();
if (preSize === 0)
return;
if (container instanceof Vector_1.default) {
container.eraseElementByValue(key);
const curSize = container.size();
this.length += curSize - preSize;
}
else {
container.eraseElementByKey(key);
const curSize = container.size();
this.length += curSize - preSize;
if (curSize <= index_1.default.untreeifyThreshold) {
this.hashTable[index] = new Vector_1.default(container);
}
}
}
find(element) {
const index = this.hashFunc(element) & (this.bucketNum - 1);
const container = this.hashTable[index];
if (!container)
return false;
return !container.find(element)
.equals(container.end());
}
[Symbol.iterator]() {
return function* () {
const containers = Object.values(this.hashTable);
const containersNum = containers.length;
for (let i = 0; i < containersNum; ++i) {
const container = containers[i];
for (const element of container) {
yield element;
}
}
}.bind(this)();
}
}
exports.default = HashSet;

View File

@@ -0,0 +1,34 @@
import { Base, initContainer } from "../ContainerBase/index";
declare class PriorityQueue<T> extends Base {
private readonly priorityQueue;
private readonly cmp;
/**
* @description PriorityQueue's constructor.
* @param container Initialize container, must have a forEach function.
* @param cmp Compare function.
* @param copy When the container is an array, you can choose to directly operate on the original object of
* the array or perform a shallow copy. The default is shallow copy.
*/
constructor(container?: initContainer<T>, cmp?: (x: T, y: T) => number, copy?: boolean);
/**
* @description Adjusting parent's children to suit the nature of the heap.
* @param parent Parent's index.
* @private
*/
private adjust;
clear(): void;
/**
* @description Push element into a container in order.
* @param element The element you want to push.
*/
push(element: T): void;
/**
* @description Removes the top element.
*/
pop(): void;
/**
* @description Accesses the top element.
*/
top(): T | undefined;
}
export default PriorityQueue;

View File

@@ -0,0 +1,124 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const index_1 = require("../ContainerBase/index");
class PriorityQueue extends index_1.Base {
/**
* @description PriorityQueue's constructor.
* @param container Initialize container, must have a forEach function.
* @param cmp Compare function.
* @param copy When the container is an array, you can choose to directly operate on the original object of
* the array or perform a shallow copy. The default is shallow copy.
*/
constructor(container = [], cmp = (x, y) => {
if (x > y)
return -1;
if (x < y)
return 1;
return 0;
}, copy = true) {
super();
this.cmp = cmp;
if (Array.isArray(container)) {
this.priorityQueue = copy ? [...container] : container;
}
else {
this.priorityQueue = [];
container.forEach(element => this.priorityQueue.push(element));
}
this.length = this.priorityQueue.length;
for (let parent = (this.length - 1) >> 1; parent >= 0; --parent) {
let curParent = parent;
let curChild = (curParent << 1) | 1;
while (curChild < this.length) {
const left = curChild;
const right = left + 1;
let minChild = left;
if (right < this.length &&
this.cmp(this.priorityQueue[left], this.priorityQueue[right]) > 0) {
minChild = right;
}
if (this.cmp(this.priorityQueue[curParent], this.priorityQueue[minChild]) <= 0)
break;
[this.priorityQueue[curParent], this.priorityQueue[minChild]] =
[this.priorityQueue[minChild], this.priorityQueue[curParent]];
curParent = minChild;
curChild = (curParent << 1) | 1;
}
}
}
/**
* @description Adjusting parent's children to suit the nature of the heap.
* @param parent Parent's index.
* @private
*/
adjust(parent) {
const left = (parent << 1) | 1;
const right = (parent << 1) + 2;
if (left < this.length &&
this.cmp(this.priorityQueue[parent], this.priorityQueue[left]) > 0) {
[this.priorityQueue[parent], this.priorityQueue[left]] =
[this.priorityQueue[left], this.priorityQueue[parent]];
}
if (right < this.length &&
this.cmp(this.priorityQueue[parent], this.priorityQueue[right]) > 0) {
[this.priorityQueue[parent], this.priorityQueue[right]] =
[this.priorityQueue[right], this.priorityQueue[parent]];
}
}
clear() {
this.length = 0;
this.priorityQueue.length = 0;
}
/**
* @description Push element into a container in order.
* @param element The element you want to push.
*/
push(element) {
this.priorityQueue.push(element);
this.length += 1;
if (this.length === 1)
return;
let curNode = this.length - 1;
while (curNode > 0) {
const parent = (curNode - 1) >> 1;
if (this.cmp(this.priorityQueue[parent], element) <= 0)
break;
this.adjust(parent);
curNode = parent;
}
}
/**
* @description Removes the top element.
*/
pop() {
if (!this.length)
return;
const last = this.priorityQueue[this.length - 1];
this.length -= 1;
let parent = 0;
while (parent < this.length) {
const left = (parent << 1) | 1;
const right = (parent << 1) + 2;
if (left >= this.length)
break;
let minChild = left;
if (right < this.length &&
this.cmp(this.priorityQueue[left], this.priorityQueue[right]) > 0) {
minChild = right;
}
if (this.cmp(this.priorityQueue[minChild], last) >= 0)
break;
this.priorityQueue[parent] = this.priorityQueue[minChild];
parent = minChild;
}
this.priorityQueue[parent] = last;
this.priorityQueue.pop();
}
/**
* @description Accesses the top element.
*/
top() {
return this.priorityQueue[0];
}
}
exports.default = PriorityQueue;

View File

@@ -0,0 +1,19 @@
import { Base, initContainer } from "../ContainerBase/index";
declare class Queue<T> extends Base {
private queue;
constructor(container?: initContainer<T>);
clear(): void;
/**
* @description Inserts element to queue's end.
*/
push(element: T): void;
/**
* @description Removes the first element.
*/
pop(): void;
/**
* @description Access the first element.
*/
front(): T | undefined;
}
export default Queue;

View File

@@ -0,0 +1,40 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const Deque_1 = __importDefault(require("../SequentialContainer/Deque"));
const index_1 = require("../ContainerBase/index");
class Queue extends index_1.Base {
constructor(container = []) {
super();
this.queue = new Deque_1.default(container);
this.length = this.queue.size();
}
clear() {
this.queue.clear();
this.length = 0;
}
/**
* @description Inserts element to queue's end.
*/
push(element) {
this.queue.pushBack(element);
this.length += 1;
}
/**
* @description Removes the first element.
*/
pop() {
this.queue.popFront();
if (this.length)
this.length -= 1;
}
/**
* @description Access the first element.
*/
front() {
return this.queue.front();
}
}
exports.default = Queue;

View File

@@ -0,0 +1,19 @@
import { Base, initContainer } from "../ContainerBase/index";
declare class Stack<T> extends Base {
private stack;
constructor(container?: initContainer<T>);
clear(): void;
/**
* @description Insert element to stack's end.
*/
push(element: T): void;
/**
* @description Removes the end element.
*/
pop(): void;
/**
* @description Accesses the end element.
*/
top(): T | undefined;
}
export default Stack;

View File

@@ -0,0 +1,36 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const index_1 = require("../ContainerBase/index");
class Stack extends index_1.Base {
constructor(container = []) {
super();
this.stack = [];
container.forEach(element => this.push(element));
}
clear() {
this.length = 0;
this.stack.length = 0;
}
/**
* @description Insert element to stack's end.
*/
push(element) {
this.stack.push(element);
this.length += 1;
}
/**
* @description Removes the end element.
*/
pop() {
this.stack.pop();
if (this.length > 0)
this.length -= 1;
}
/**
* @description Accesses the end element.
*/
top() {
return this.stack[this.length - 1];
}
}
exports.default = Stack;

View File

@@ -0,0 +1,13 @@
import { ContainerIterator } from "../../ContainerBase/index";
export declare abstract class RandomIterator<T> extends ContainerIterator<T> {
protected node: number;
protected readonly size: () => number;
protected readonly getElementByPos: (pos: number) => T;
protected readonly setElementByPos: (pos: number, element: T) => void;
pre: () => this;
next: () => this;
constructor(index: number, size: () => number, getElementByPos: (pos: number) => T, setElementByPos: (pos: number, element: T) => void, iteratorType?: boolean);
get pointer(): T;
set pointer(newValue: T);
equals(obj: RandomIterator<T>): boolean;
}

View File

@@ -0,0 +1,58 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RandomIterator = void 0;
const checkParams_1 = require("../../../utils/checkParams");
const index_1 = require("../../ContainerBase/index");
class RandomIterator extends index_1.ContainerIterator {
constructor(index, size, getElementByPos, setElementByPos, iteratorType) {
super(iteratorType);
this.node = index;
this.size = size;
this.getElementByPos = getElementByPos;
this.setElementByPos = setElementByPos;
if (this.iteratorType === index_1.ContainerIterator.NORMAL) {
this.pre = function () {
if (this.node === 0) {
throw new RangeError('Deque iterator access denied!');
}
this.node -= 1;
return this;
};
this.next = function () {
if (this.node === this.size()) {
throw new RangeError('Deque Iterator access denied!');
}
this.node += 1;
return this;
};
}
else {
this.pre = function () {
if (this.node === this.size() - 1) {
throw new RangeError('Deque iterator access denied!');
}
this.node += 1;
return this;
};
this.next = function () {
if (this.node === -1) {
throw new RangeError('Deque iterator access denied!');
}
this.node -= 1;
return this;
};
}
}
get pointer() {
(0, checkParams_1.checkWithinAccessParams)(this.node, 0, this.size() - 1);
return this.getElementByPos(this.node);
}
set pointer(newValue) {
(0, checkParams_1.checkWithinAccessParams)(this.node, 0, this.size() - 1);
this.setElementByPos(this.node, newValue);
}
equals(obj) {
return this.node === obj.node;
}
}
exports.RandomIterator = RandomIterator;

View File

@@ -0,0 +1,44 @@
import { Container } from "../../ContainerBase/index";
declare abstract class SequentialContainer<T> extends Container<T> {
/**
* @description Push the element to the back.
* @param element The element you want to push.
*/
abstract pushBack(element: T): void;
/**
* @description Removes the last element.
*/
abstract popBack(): void;
/**
* @description Sets element by position.
* @param pos The position you want to change.
* @param element The element's value you want to update.
*/
abstract setElementByPos(pos: number, element: T): void;
/**
* @description Removes the elements of the specified value.
* @param value The value you want to remove.
*/
abstract eraseElementByValue(value: T): void;
/**
* @description Insert several elements after the specified position.
* @param pos The position you want to insert.
* @param element The element you want to insert.
* @param num The number of elements you want to insert (default 1).
*/
abstract insert(pos: number, element: T, num?: number): void;
/**
* @description Reverses the container.
*/
abstract reverse(): void;
/**
* @description Removes the duplication of elements in the container.
*/
abstract unique(): void;
/**
* @description Sort the container.
* @param cmp Comparison function.
*/
abstract sort(cmp?: (x: T, y: T) => number): void;
}
export default SequentialContainer;

View File

@@ -0,0 +1,6 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const index_1 = require("../../ContainerBase/index");
class SequentialContainer extends index_1.Container {
}
exports.default = SequentialContainer;

View File

@@ -0,0 +1,68 @@
import SequentialContainer from './Base/index';
import { initContainer } from "../ContainerBase/index";
import { RandomIterator } from "./Base/RandomIterator";
export declare class DequeIterator<T> extends RandomIterator<T> {
copy(): DequeIterator<T>;
}
declare class Deque<T> extends SequentialContainer<T> {
private first;
private curFirst;
private last;
private curLast;
private bucketNum;
private readonly bucketSize;
private map;
constructor(container?: initContainer<T>, bucketSize?: number);
/**
* @description Growth the Deque.
* @private
*/
private reAllocate;
/**
* @description Get the bucket position of the element and the pointer position by index.
* @param pos The element's index.
* @private
*/
private getElementIndex;
clear(): void;
front(): T | undefined;
back(): T | undefined;
begin(): DequeIterator<T>;
end(): DequeIterator<T>;
rBegin(): DequeIterator<T>;
rEnd(): DequeIterator<T>;
pushBack(element: T): void;
popBack(): void;
/**
* @description Push the element to the front.
* @param element The element you want to push.
*/
pushFront(element: T): void;
/**
* @description Remove the first element.
*/
popFront(): void;
forEach(callback: (element: T, index: number) => void): void;
getElementByPos(pos: number): T;
setElementByPos(pos: number, element: T): void;
insert(pos: number, element: T, num?: number): void;
/**
* @description Remove all elements after the specified position (excluding the specified position).
* @param pos The previous position of the first removed element.
* @example deque.cut(1); // Then deque's size will be 2. deque -> [0, 1]
*/
cut(pos: number): void;
eraseElementByPos(pos: number): void;
eraseElementByValue(value: T): void;
eraseElementByIterator(iter: DequeIterator<T>): DequeIterator<T>;
find(element: T): DequeIterator<T>;
reverse(): void;
unique(): void;
sort(cmp?: (x: T, y: T) => number): void;
/**
* @description Remove as much useless space as possible.
*/
shrinkToFit(): void;
[Symbol.iterator](): Generator<T, void, unknown>;
}
export default Deque;

View File

@@ -0,0 +1,362 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DequeIterator = void 0;
const index_1 = __importDefault(require("./Base/index"));
const checkParams_1 = require("../../utils/checkParams");
const index_2 = require("../ContainerBase/index");
const RandomIterator_1 = require("./Base/RandomIterator");
class DequeIterator extends RandomIterator_1.RandomIterator {
copy() {
return new DequeIterator(this.node, this.size, this.getElementByPos, this.setElementByPos, this.iteratorType);
}
}
exports.DequeIterator = DequeIterator;
class Deque extends index_1.default {
constructor(container = [], bucketSize = (1 << 12)) {
super();
this.first = 0;
this.curFirst = 0;
this.last = 0;
this.curLast = 0;
this.bucketNum = 0;
this.map = [];
let _length;
if ('size' in container) {
if (typeof container.size === 'number') {
_length = container.size;
}
else {
_length = container.size();
}
}
else if ('length' in container) {
_length = container.length;
}
else {
throw new RangeError('Can\'t get container\'s size!');
}
this.bucketSize = bucketSize;
this.bucketNum = Math.max(Math.ceil(_length / this.bucketSize), 1);
for (let i = 0; i < this.bucketNum; ++i) {
this.map.push(new Array(this.bucketSize));
}
const needBucketNum = Math.ceil(_length / this.bucketSize);
this.first = this.last = (this.bucketNum >> 1) - (needBucketNum >> 1);
this.curFirst = this.curLast = (this.bucketSize - _length % this.bucketSize) >> 1;
container.forEach(element => this.pushBack(element));
this.size = this.size.bind(this);
this.getElementByPos = this.getElementByPos.bind(this);
this.setElementByPos = this.setElementByPos.bind(this);
}
/**
* @description Growth the Deque.
* @private
*/
reAllocate() {
const newMap = [];
const addBucketNum = Math.max(this.bucketNum >> 1, 1);
for (let i = 0; i < addBucketNum; ++i) {
newMap[i] = new Array(this.bucketSize);
}
for (let i = this.first; i < this.bucketNum; ++i) {
newMap[newMap.length] = this.map[i];
}
for (let i = 0; i < this.last; ++i) {
newMap[newMap.length] = this.map[i];
}
newMap[newMap.length] = [...this.map[this.last]];
this.first = addBucketNum;
this.last = newMap.length - 1;
for (let i = 0; i < addBucketNum; ++i) {
newMap[newMap.length] = new Array(this.bucketSize);
}
this.map = newMap;
this.bucketNum = newMap.length;
}
/**
* @description Get the bucket position of the element and the pointer position by index.
* @param pos The element's index.
* @private
*/
getElementIndex(pos) {
const offset = this.curFirst + pos + 1;
const offsetRemainder = offset % this.bucketSize;
let curNodePointerIndex = offsetRemainder - 1;
let curNodeBucketIndex = this.first + (offset - offsetRemainder) / this.bucketSize;
if (offsetRemainder === 0)
curNodeBucketIndex -= 1;
curNodeBucketIndex %= this.bucketNum;
if (curNodePointerIndex < 0)
curNodePointerIndex += this.bucketSize;
return { curNodeBucketIndex, curNodePointerIndex };
}
clear() {
this.map = [[]];
this.bucketNum = 1;
this.first = this.last = this.length = 0;
this.curFirst = this.curLast = this.bucketSize >> 1;
}
front() {
return this.map[this.first][this.curFirst];
}
back() {
return this.map[this.last][this.curLast];
}
begin() {
return new DequeIterator(0, this.size, this.getElementByPos, this.setElementByPos);
}
end() {
return new DequeIterator(this.length, this.size, this.getElementByPos, this.setElementByPos);
}
rBegin() {
return new DequeIterator(this.length - 1, this.size, this.getElementByPos, this.setElementByPos, index_2.ContainerIterator.REVERSE);
}
rEnd() {
return new DequeIterator(-1, this.size, this.getElementByPos, this.setElementByPos, index_2.ContainerIterator.REVERSE);
}
pushBack(element) {
if (this.length) {
if (this.curLast < this.bucketSize - 1) {
this.curLast += 1;
}
else if (this.last < this.bucketNum - 1) {
this.last += 1;
this.curLast = 0;
}
else {
this.last = 0;
this.curLast = 0;
}
if (this.last === this.first &&
this.curLast === this.curFirst)
this.reAllocate();
}
this.length += 1;
this.map[this.last][this.curLast] = element;
}
popBack() {
if (!this.length)
return;
this.map[this.last][this.curLast] = undefined;
if (this.length !== 1) {
if (this.curLast > 0) {
this.curLast -= 1;
}
else if (this.last > 0) {
this.last -= 1;
this.curLast = this.bucketSize - 1;
}
else {
this.last = this.bucketNum - 1;
this.curLast = this.bucketSize - 1;
}
}
this.length -= 1;
}
/**
* @description Push the element to the front.
* @param element The element you want to push.
*/
pushFront(element) {
if (this.length) {
if (this.curFirst > 0) {
this.curFirst -= 1;
}
else if (this.first > 0) {
this.first -= 1;
this.curFirst = this.bucketSize - 1;
}
else {
this.first = this.bucketNum - 1;
this.curFirst = this.bucketSize - 1;
}
if (this.first === this.last &&
this.curFirst === this.curLast)
this.reAllocate();
}
this.length += 1;
this.map[this.first][this.curFirst] = element;
}
/**
* @description Remove the first element.
*/
popFront() {
if (!this.length)
return;
this.map[this.first][this.curFirst] = undefined;
if (this.length !== 1) {
if (this.curFirst < this.bucketSize - 1) {
this.curFirst += 1;
}
else if (this.first < this.bucketNum - 1) {
this.first += 1;
this.curFirst = 0;
}
else {
this.first = 0;
this.curFirst = 0;
}
}
this.length -= 1;
}
forEach(callback) {
for (let i = 0; i < this.length; ++i) {
callback(this.getElementByPos(i), i);
}
}
getElementByPos(pos) {
(0, checkParams_1.checkWithinAccessParams)(pos, 0, this.length - 1);
const { curNodeBucketIndex, curNodePointerIndex } = this.getElementIndex(pos);
return this.map[curNodeBucketIndex][curNodePointerIndex];
}
setElementByPos(pos, element) {
(0, checkParams_1.checkWithinAccessParams)(pos, 0, this.length - 1);
const { curNodeBucketIndex, curNodePointerIndex } = this.getElementIndex(pos);
this.map[curNodeBucketIndex][curNodePointerIndex] = element;
}
insert(pos, element, num = 1) {
(0, checkParams_1.checkWithinAccessParams)(pos, 0, this.length);
if (pos === 0) {
while (num--)
this.pushFront(element);
}
else if (pos === this.length) {
while (num--)
this.pushBack(element);
}
else {
const arr = [];
for (let i = pos; i < this.length; ++i) {
arr.push(this.getElementByPos(i));
}
this.cut(pos - 1);
for (let i = 0; i < num; ++i)
this.pushBack(element);
for (let i = 0; i < arr.length; ++i)
this.pushBack(arr[i]);
}
}
/**
* @description Remove all elements after the specified position (excluding the specified position).
* @param pos The previous position of the first removed element.
* @example deque.cut(1); // Then deque's size will be 2. deque -> [0, 1]
*/
cut(pos) {
if (pos < 0) {
this.clear();
return;
}
const { curNodeBucketIndex, curNodePointerIndex } = this.getElementIndex(pos);
this.last = curNodeBucketIndex;
this.curLast = curNodePointerIndex;
this.length = pos + 1;
}
eraseElementByPos(pos) {
(0, checkParams_1.checkWithinAccessParams)(pos, 0, this.length - 1);
if (pos === 0)
this.popFront();
else if (pos === this.length - 1)
this.popBack();
else {
const arr = [];
for (let i = pos + 1; i < this.length; ++i) {
arr.push(this.getElementByPos(i));
}
this.cut(pos);
this.popBack();
arr.forEach(element => this.pushBack(element));
}
}
eraseElementByValue(value) {
if (!this.length)
return;
const arr = [];
for (let i = 0; i < this.length; ++i) {
const element = this.getElementByPos(i);
if (element !== value)
arr.push(element);
}
const _length = arr.length;
for (let i = 0; i < _length; ++i)
this.setElementByPos(i, arr[i]);
this.cut(_length - 1);
}
eraseElementByIterator(iter) {
// @ts-ignore
const node = iter.node;
this.eraseElementByPos(node);
iter = iter.next();
return iter;
}
find(element) {
for (let i = 0; i < this.length; ++i) {
if (this.getElementByPos(i) === element) {
return new DequeIterator(i, this.size, this.getElementByPos, this.setElementByPos);
}
}
return this.end();
}
reverse() {
let l = 0;
let r = this.length - 1;
while (l < r) {
const tmp = this.getElementByPos(l);
this.setElementByPos(l, this.getElementByPos(r));
this.setElementByPos(r, tmp);
l += 1;
r -= 1;
}
}
unique() {
if (this.length <= 1)
return;
let index = 1;
let pre = this.getElementByPos(0);
for (let i = 1; i < this.length; ++i) {
const cur = this.getElementByPos(i);
if (cur !== pre) {
pre = cur;
this.setElementByPos(index++, cur);
}
}
while (this.length > index)
this.popBack();
}
sort(cmp) {
const arr = [];
for (let i = 0; i < this.length; ++i) {
arr.push(this.getElementByPos(i));
}
arr.sort(cmp);
for (let i = 0; i < this.length; ++i)
this.setElementByPos(i, arr[i]);
}
/**
* @description Remove as much useless space as possible.
*/
shrinkToFit() {
if (!this.length)
return;
const arr = [];
this.forEach(element => arr.push(element));
this.bucketNum = Math.max(Math.ceil(this.length / this.bucketSize), 1);
this.length = this.first = this.last = this.curFirst = this.curLast = 0;
this.map = [];
for (let i = 0; i < this.bucketNum; ++i) {
this.map.push(new Array(this.bucketSize));
}
for (let i = 0; i < arr.length; ++i)
this.pushBack(arr[i]);
}
[Symbol.iterator]() {
return function* () {
for (let i = 0; i < this.length; ++i) {
yield this.getElementByPos(i);
}
}.bind(this)();
}
}
exports.default = Deque;

View File

@@ -0,0 +1,61 @@
import SequentialContainer from './Base/index';
import { ContainerIterator, initContainer } from "../ContainerBase/index";
export declare class LinkNode<T> {
value: T | undefined;
pre: LinkNode<T> | undefined;
next: LinkNode<T> | undefined;
constructor(element?: T);
}
export declare class LinkListIterator<T> extends ContainerIterator<T> {
protected node: LinkNode<T>;
private readonly header;
pre: () => this;
next: () => this;
constructor(node: LinkNode<T>, header: LinkNode<T>, iteratorType?: boolean);
get pointer(): T;
set pointer(newValue: T);
equals(obj: LinkListIterator<T>): boolean;
copy(): LinkListIterator<T>;
}
declare class LinkList<T> extends SequentialContainer<T> {
private header;
private head;
private tail;
constructor(container?: initContainer<T>);
clear(): void;
begin(): LinkListIterator<T>;
end(): LinkListIterator<T>;
rBegin(): LinkListIterator<T>;
rEnd(): LinkListIterator<T>;
front(): T | undefined;
back(): T | undefined;
forEach(callback: (element: T, index: number) => void): void;
getElementByPos(pos: number): T;
eraseElementByPos(pos: number): void;
eraseElementByValue(value: T): void;
eraseElementByIterator(iter: LinkListIterator<T>): LinkListIterator<T>;
pushBack(element: T): void;
popBack(): void;
setElementByPos(pos: number, element: T): void;
insert(pos: number, element: T, num?: number): void;
find(element: T): LinkListIterator<T>;
reverse(): void;
unique(): void;
sort(cmp?: (x: T, y: T) => number): void;
/**
* @description Push an element to the front.
* @param element The element you want to push.
*/
pushFront(element: T): void;
/**
* @description Removes the first element.
*/
popFront(): void;
/**
* @description Merges two sorted lists.
* @param list The other list you want to merge (must be sorted).
*/
merge(list: LinkList<T>): void;
[Symbol.iterator](): Generator<T, void, unknown>;
}
export default LinkList;

View File

@@ -0,0 +1,397 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.LinkListIterator = exports.LinkNode = void 0;
const index_1 = __importDefault(require("./Base/index"));
const checkParams_1 = require("../../utils/checkParams");
const index_2 = require("../ContainerBase/index");
class LinkNode {
constructor(element) {
this.value = undefined;
this.pre = undefined;
this.next = undefined;
this.value = element;
}
}
exports.LinkNode = LinkNode;
class LinkListIterator extends index_2.ContainerIterator {
constructor(node, header, iteratorType) {
super(iteratorType);
this.node = node;
this.header = header;
if (this.iteratorType === index_2.ContainerIterator.NORMAL) {
this.pre = function () {
if (this.node.pre === this.header) {
throw new RangeError('LinkList iterator access denied!');
}
this.node = this.node.pre;
return this;
};
this.next = function () {
if (this.node === this.header) {
throw new RangeError('LinkList iterator access denied!');
}
this.node = this.node.next;
return this;
};
}
else {
this.pre = function () {
if (this.node.next === this.header) {
throw new RangeError('LinkList iterator access denied!');
}
this.node = this.node.next;
return this;
};
this.next = function () {
if (this.node === this.header) {
throw new RangeError('LinkList iterator access denied!');
}
this.node = this.node.pre;
return this;
};
}
}
get pointer() {
if (this.node === this.header) {
throw new RangeError('LinkList iterator access denied!');
}
return this.node.value;
}
set pointer(newValue) {
if (this.node === this.header) {
throw new RangeError('LinkList iterator access denied!');
}
this.node.value = newValue;
}
equals(obj) {
return this.node === obj.node;
}
copy() {
return new LinkListIterator(this.node, this.header, this.iteratorType);
}
}
exports.LinkListIterator = LinkListIterator;
class LinkList extends index_1.default {
constructor(container = []) {
super();
this.header = new LinkNode();
this.head = undefined;
this.tail = undefined;
container.forEach(element => this.pushBack(element));
}
clear() {
this.length = 0;
this.head = this.tail = undefined;
this.header.pre = this.header.next = undefined;
}
begin() {
return new LinkListIterator(this.head || this.header, this.header);
}
end() {
return new LinkListIterator(this.header, this.header);
}
rBegin() {
return new LinkListIterator(this.tail || this.header, this.header, index_2.ContainerIterator.REVERSE);
}
rEnd() {
return new LinkListIterator(this.header, this.header, index_2.ContainerIterator.REVERSE);
}
front() {
return this.head ? this.head.value : undefined;
}
back() {
return this.tail ? this.tail.value : undefined;
}
forEach(callback) {
if (!this.length)
return;
let curNode = this.head;
let index = 0;
while (curNode !== this.header) {
callback(curNode.value, index++);
curNode = curNode.next;
}
}
getElementByPos(pos) {
(0, checkParams_1.checkWithinAccessParams)(pos, 0, this.length - 1);
let curNode = this.head;
while (pos--) {
curNode = curNode.next;
}
return curNode.value;
}
eraseElementByPos(pos) {
(0, checkParams_1.checkWithinAccessParams)(pos, 0, this.length - 1);
if (pos === 0)
this.popFront();
else if (pos === this.length - 1)
this.popBack();
else {
let curNode = this.head;
while (pos--) {
curNode = curNode.next;
}
curNode = curNode;
const pre = curNode.pre;
const next = curNode.next;
next.pre = pre;
pre.next = next;
this.length -= 1;
}
}
eraseElementByValue(value) {
while (this.head && this.head.value === value)
this.popFront();
while (this.tail && this.tail.value === value)
this.popBack();
if (!this.head)
return;
let curNode = this.head;
while (curNode !== this.header) {
if (curNode.value === value) {
const pre = curNode.pre;
const next = curNode.next;
if (next)
next.pre = pre;
if (pre)
pre.next = next;
this.length -= 1;
}
curNode = curNode.next;
}
}
eraseElementByIterator(iter) {
// @ts-ignore
const node = iter.node;
if (node === this.header) {
throw new RangeError('Invalid iterator');
}
iter = iter.next();
if (this.head === node)
this.popFront();
else if (this.tail === node)
this.popBack();
else {
const pre = node.pre;
const next = node.next;
if (next)
next.pre = pre;
if (pre)
pre.next = next;
this.length -= 1;
}
return iter;
}
pushBack(element) {
this.length += 1;
const newTail = new LinkNode(element);
if (!this.tail) {
this.head = this.tail = newTail;
this.header.next = this.head;
this.head.pre = this.header;
}
else {
this.tail.next = newTail;
newTail.pre = this.tail;
this.tail = newTail;
}
this.tail.next = this.header;
this.header.pre = this.tail;
}
popBack() {
if (!this.tail)
return;
this.length -= 1;
if (this.head === this.tail) {
this.head = this.tail = undefined;
this.header.next = undefined;
}
else {
this.tail = this.tail.pre;
if (this.tail)
this.tail.next = undefined;
}
this.header.pre = this.tail;
if (this.tail)
this.tail.next = this.header;
}
setElementByPos(pos, element) {
(0, checkParams_1.checkWithinAccessParams)(pos, 0, this.length - 1);
let curNode = this.head;
while (pos--) {
curNode = curNode.next;
}
curNode.value = element;
}
insert(pos, element, num = 1) {
(0, checkParams_1.checkWithinAccessParams)(pos, 0, this.length);
if (num <= 0)
return;
if (pos === 0) {
while (num--)
this.pushFront(element);
}
else if (pos === this.length) {
while (num--)
this.pushBack(element);
}
else {
let curNode = this.head;
for (let i = 1; i < pos; ++i) {
curNode = curNode.next;
}
const next = curNode.next;
this.length += num;
while (num--) {
curNode.next = new LinkNode(element);
curNode.next.pre = curNode;
curNode = curNode.next;
}
curNode.next = next;
if (next)
next.pre = curNode;
}
}
find(element) {
if (!this.head)
return this.end();
let curNode = this.head;
while (curNode !== this.header) {
if (curNode.value === element) {
return new LinkListIterator(curNode, this.header);
}
curNode = curNode.next;
}
return this.end();
}
reverse() {
if (this.length <= 1)
return;
let pHead = this.head;
let pTail = this.tail;
let cnt = 0;
while ((cnt << 1) < this.length) {
const tmp = pHead.value;
pHead.value = pTail.value;
pTail.value = tmp;
pHead = pHead.next;
pTail = pTail.pre;
cnt += 1;
}
}
unique() {
if (this.length <= 1)
return;
let curNode = this.head;
while (curNode !== this.header) {
let tmpNode = curNode;
while (tmpNode.next && tmpNode.value === tmpNode.next.value) {
tmpNode = tmpNode.next;
this.length -= 1;
}
curNode.next = tmpNode.next;
if (curNode.next)
curNode.next.pre = curNode;
curNode = curNode.next;
}
}
sort(cmp) {
if (this.length <= 1)
return;
const arr = [];
this.forEach(element => arr.push(element));
arr.sort(cmp);
let curNode = this.head;
arr.forEach((element) => {
curNode.value = element;
curNode = curNode.next;
});
}
/**
* @description Push an element to the front.
* @param element The element you want to push.
*/
pushFront(element) {
this.length += 1;
const newHead = new LinkNode(element);
if (!this.head) {
this.head = this.tail = newHead;
this.tail.next = this.header;
this.header.pre = this.tail;
}
else {
newHead.next = this.head;
this.head.pre = newHead;
this.head = newHead;
}
this.header.next = this.head;
this.head.pre = this.header;
}
/**
* @description Removes the first element.
*/
popFront() {
if (!this.head)
return;
this.length -= 1;
if (this.head === this.tail) {
this.head = this.tail = undefined;
this.header.pre = this.tail;
}
else {
this.head = this.head.next;
if (this.head)
this.head.pre = this.header;
}
this.header.next = this.head;
}
/**
* @description Merges two sorted lists.
* @param list The other list you want to merge (must be sorted).
*/
merge(list) {
if (!this.head) {
list.forEach(element => this.pushBack(element));
return;
}
let curNode = this.head;
list.forEach(element => {
while (curNode &&
curNode !== this.header &&
curNode.value <= element) {
curNode = curNode.next;
}
if (curNode === this.header) {
this.pushBack(element);
curNode = this.tail;
}
else if (curNode === this.head) {
this.pushFront(element);
curNode = this.head;
}
else {
this.length += 1;
const pre = curNode.pre;
pre.next = new LinkNode(element);
pre.next.pre = pre;
pre.next.next = curNode;
curNode.pre = pre.next;
}
});
}
[Symbol.iterator]() {
return function* () {
if (!this.head)
return;
let curNode = this.head;
while (curNode !== this.header) {
yield curNode.value;
curNode = curNode.next;
}
}.bind(this)();
}
}
exports.default = LinkList;

View File

@@ -0,0 +1,38 @@
import SequentialContainer from './Base/index';
import { initContainer } from "../ContainerBase/index";
import { RandomIterator } from "./Base/RandomIterator";
export declare class VectorIterator<T> extends RandomIterator<T> {
copy(): VectorIterator<T>;
}
declare class Vector<T> extends SequentialContainer<T> {
private readonly vector;
/**
* @description Vector's constructor.
* @param container Initialize container, must have a forEach function.
* @param copy When the container is an array, you can choose to directly operate on the original object of
* the array or perform a shallow copy. The default is shallow copy.
*/
constructor(container?: initContainer<T>, copy?: boolean);
clear(): void;
begin(): VectorIterator<T>;
end(): VectorIterator<T>;
rBegin(): VectorIterator<T>;
rEnd(): VectorIterator<T>;
front(): T | undefined;
back(): T | undefined;
forEach(callback: (element: T, index: number) => void): void;
getElementByPos(pos: number): T;
eraseElementByPos(pos: number): void;
eraseElementByValue(value: T): void;
eraseElementByIterator(iter: VectorIterator<T>): VectorIterator<T>;
pushBack(element: T): void;
popBack(): void;
setElementByPos(pos: number, element: T): void;
insert(pos: number, element: T, num?: number): void;
find(element: T): VectorIterator<T>;
reverse(): void;
unique(): void;
sort(cmp?: (x: T, y: T) => number): void;
[Symbol.iterator](): Generator<T, any, undefined>;
}
export default Vector;

View File

@@ -0,0 +1,138 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.VectorIterator = void 0;
const index_1 = __importDefault(require("./Base/index"));
const checkParams_1 = require("../../utils/checkParams");
const index_2 = require("../ContainerBase/index");
const RandomIterator_1 = require("./Base/RandomIterator");
class VectorIterator extends RandomIterator_1.RandomIterator {
copy() {
return new VectorIterator(this.node, this.size, this.getElementByPos, this.setElementByPos, this.iteratorType);
}
}
exports.VectorIterator = VectorIterator;
class Vector extends index_1.default {
/**
* @description Vector's constructor.
* @param container Initialize container, must have a forEach function.
* @param copy When the container is an array, you can choose to directly operate on the original object of
* the array or perform a shallow copy. The default is shallow copy.
*/
constructor(container = [], copy = true) {
super();
if (Array.isArray(container)) {
this.vector = copy ? [...container] : container;
this.length = container.length;
}
else {
this.vector = [];
container.forEach(element => this.pushBack(element));
}
this.size = this.size.bind(this);
this.getElementByPos = this.getElementByPos.bind(this);
this.setElementByPos = this.setElementByPos.bind(this);
}
clear() {
this.length = 0;
this.vector.length = 0;
}
begin() {
return new VectorIterator(0, this.size, this.getElementByPos, this.setElementByPos);
}
end() {
return new VectorIterator(this.length, this.size, this.getElementByPos, this.setElementByPos);
}
rBegin() {
return new VectorIterator(this.length - 1, this.size, this.getElementByPos, this.setElementByPos, index_2.ContainerIterator.REVERSE);
}
rEnd() {
return new VectorIterator(-1, this.size, this.getElementByPos, this.setElementByPos, index_2.ContainerIterator.REVERSE);
}
front() {
return this.vector[0];
}
back() {
return this.vector[this.length - 1];
}
forEach(callback) {
for (let i = 0; i < this.length; ++i) {
callback(this.vector[i], i);
}
}
getElementByPos(pos) {
(0, checkParams_1.checkWithinAccessParams)(pos, 0, this.length - 1);
return this.vector[pos];
}
eraseElementByPos(pos) {
(0, checkParams_1.checkWithinAccessParams)(pos, 0, this.length - 1);
this.vector.splice(pos, 1);
this.length -= 1;
}
eraseElementByValue(value) {
let index = 0;
for (let i = 0; i < this.length; ++i) {
if (this.vector[i] !== value) {
this.vector[index++] = this.vector[i];
}
}
this.length = this.vector.length = index;
}
eraseElementByIterator(iter) {
// @ts-ignore
const node = iter.node;
iter = iter.next();
this.eraseElementByPos(node);
return iter;
}
pushBack(element) {
this.vector.push(element);
this.length += 1;
}
popBack() {
if (!this.length)
return;
this.vector.pop();
this.length -= 1;
}
setElementByPos(pos, element) {
(0, checkParams_1.checkWithinAccessParams)(pos, 0, this.length - 1);
this.vector[pos] = element;
}
insert(pos, element, num = 1) {
(0, checkParams_1.checkWithinAccessParams)(pos, 0, this.length);
this.vector.splice(pos, 0, ...new Array(num).fill(element));
this.length += num;
}
find(element) {
for (let i = 0; i < this.length; ++i) {
if (this.vector[i] === element) {
return new VectorIterator(i, this.size, this.getElementByPos, this.getElementByPos);
}
}
return this.end();
}
reverse() {
this.vector.reverse();
}
unique() {
let index = 1;
for (let i = 1; i < this.length; ++i) {
if (this.vector[i] !== this.vector[i - 1]) {
this.vector[index++] = this.vector[i];
}
}
this.length = this.vector.length = index;
}
sort(cmp) {
this.vector.sort(cmp);
}
[Symbol.iterator]() {
return function* () {
return yield* this.vector;
}.bind(this)();
}
}
exports.default = Vector;

View File

@@ -0,0 +1,11 @@
import TreeNode from './TreeNode';
import { ContainerIterator } from "../../ContainerBase/index";
declare abstract class TreeIterator<K, V> extends ContainerIterator<K | [K, V]> {
protected node: TreeNode<K, V>;
protected header: TreeNode<K, V>;
pre: () => this;
next: () => this;
constructor(node: TreeNode<K, V>, header: TreeNode<K, V>, iteratorType?: boolean);
equals(obj: TreeIterator<K, V>): boolean;
}
export default TreeIterator;

View File

@@ -0,0 +1,46 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const index_1 = require("../../ContainerBase/index");
class TreeIterator extends index_1.ContainerIterator {
constructor(node, header, iteratorType) {
super(iteratorType);
this.node = node;
this.header = header;
if (this.iteratorType === index_1.ContainerIterator.NORMAL) {
this.pre = function () {
if (this.node === this.header.left) {
throw new RangeError('LinkList iterator access denied!');
}
this.node = this.node.pre();
return this;
};
this.next = function () {
if (this.node === this.header) {
throw new RangeError('LinkList iterator access denied!');
}
this.node = this.node.next();
return this;
};
}
else {
this.pre = function () {
if (this.node === this.header.right) {
throw new RangeError('LinkList iterator access denied!');
}
this.node = this.node.next();
return this;
};
this.next = function () {
if (this.node === this.header) {
throw new RangeError('LinkList iterator access denied!');
}
this.node = this.node.pre();
return this;
};
}
}
equals(obj) {
return this.node === obj.node;
}
}
exports.default = TreeIterator;

View File

@@ -0,0 +1,36 @@
declare class TreeNode<K, V> {
static readonly RED = true;
static readonly BLACK = false;
color: boolean;
key: K | undefined;
value: V | undefined;
left: TreeNode<K, V> | undefined;
right: TreeNode<K, V> | undefined;
parent: TreeNode<K, V> | undefined;
constructor(key?: K, value?: V);
/**
* @description Get the pre node.
* @return TreeNode about the pre node.
*/
pre(): TreeNode<K, V>;
/**
* @description Get the next node.
* @return TreeNode about the next node.
*/
next(): TreeNode<K, V>;
/**
* @description Rotate left.
* @return TreeNode about moved to original position after rotation.
*/
rotateLeft(): TreeNode<K, V>;
/**
* @description Rotate left.
* @return TreeNode about moved to original position after rotation.
*/
rotateRight(): TreeNode<K, V>;
/**
* @description Remove this.
*/
remove(): void;
}
export default TreeNode;

View File

@@ -0,0 +1,122 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class TreeNode {
constructor(key, value) {
this.color = true;
this.key = undefined;
this.value = undefined;
this.left = undefined;
this.right = undefined;
this.parent = undefined;
this.key = key;
this.value = value;
}
/**
* @description Get the pre node.
* @return TreeNode about the pre node.
*/
pre() {
let preNode = this;
if (preNode.color === TreeNode.RED &&
preNode.parent.parent === preNode) {
preNode = preNode.right;
}
else if (preNode.left) {
preNode = preNode.left;
while (preNode.right) {
preNode = preNode.right;
}
}
else {
let pre = preNode.parent;
while (pre.left === preNode) {
preNode = pre;
pre = preNode.parent;
}
preNode = pre;
}
return preNode;
}
/**
* @description Get the next node.
* @return TreeNode about the next node.
*/
next() {
let nextNode = this;
if (nextNode.right) {
nextNode = nextNode.right;
while (nextNode.left) {
nextNode = nextNode.left;
}
}
else {
let pre = nextNode.parent;
while (pre.right === nextNode) {
nextNode = pre;
pre = nextNode.parent;
}
if (nextNode.right !== pre) {
nextNode = pre;
}
}
return nextNode;
}
/**
* @description Rotate left.
* @return TreeNode about moved to original position after rotation.
*/
rotateLeft() {
const PP = this.parent;
const V = this.right;
const R = V.left;
if (PP.parent === this)
PP.parent = V;
else if (PP.left === this)
PP.left = V;
else
PP.right = V;
V.parent = PP;
V.left = this;
this.parent = V;
this.right = R;
if (R)
R.parent = this;
return V;
}
/**
* @description Rotate left.
* @return TreeNode about moved to original position after rotation.
*/
rotateRight() {
const PP = this.parent;
const F = this.left;
const K = F.right;
if (PP.parent === this)
PP.parent = F;
else if (PP.left === this)
PP.left = F;
else
PP.right = F;
F.parent = PP;
F.right = this;
this.parent = F;
this.left = K;
if (K)
K.parent = this;
return F;
}
/**
* @description Remove this.
*/
remove() {
const parent = this.parent;
if (this === parent.left) {
parent.left = undefined;
}
else
parent.right = undefined;
}
}
TreeNode.RED = true;
TreeNode.BLACK = false;
exports.default = TreeNode;

View File

@@ -0,0 +1,127 @@
import TreeNode from './TreeNode';
import TreeIterator from './TreeIterator';
import { Container } from "../../ContainerBase/index";
declare abstract class TreeContainer<K, V> extends Container<K | [K, V]> {
protected root: TreeNode<K, V> | undefined;
protected header: TreeNode<K, V>;
protected cmp: (x: K, y: K) => number;
protected constructor(cmp?: (x: K, y: K) => number);
/**
* @param curNode The starting node of the search.
* @param key The key you want to search.
* @return TreeNode which key is greater than or equals to the given key.
* @protected
*/
protected _lowerBound(curNode: TreeNode<K, V> | undefined, key: K): TreeNode<K, V>;
/**
* @param key The given key you want to compare.
* @return An iterator to the first element not less than the given key.
*/
abstract lowerBound(key: K): TreeIterator<K, V>;
/**
* @param curNode The starting node of the search.
* @param key The key you want to search.
* @return TreeNode which key is greater than the given key.
* @protected
*/
protected _upperBound(curNode: TreeNode<K, V> | undefined, key: K): TreeNode<K, V>;
/**
* @param key The given key you want to compare.
* @return An iterator to the first element greater than the given key.
*/
abstract upperBound(key: K): TreeIterator<K, V>;
/**
* @param curNode The starting node of the search.
* @param key The key you want to search.
* @return TreeNode which key is less than or equals to the given key.
* @protected
*/
protected _reverseLowerBound(curNode: TreeNode<K, V> | undefined, key: K): TreeNode<K, V>;
/**
* @param key The given key you want to compare.
* @return An iterator to the first element not greater than the given key.
*/
abstract reverseLowerBound(key: K): TreeIterator<K, V>;
/**
* @param curNode The starting node of the search.
* @param key The key you want to search.
* @return TreeNode which key is less than the given key.
* @protected
*/
protected _reverseUpperBound(curNode: TreeNode<K, V> | undefined, key: K): TreeNode<K, V>;
/**
* @param key The given key you want to compare.
* @return An iterator to the first element less than the given key.
*/
abstract reverseUpperBound(key: K): TreeIterator<K, V>;
/**
* @description Union the other tree to self.
* <br/>
* Waiting for optimization, this is O(mlog(n+m)) algorithm now,
* but we expect it to be O(mlog(n/m+1)).<br/>
* More information =>
* https://en.wikipedia.org/wiki/Red_black_tree
* <br/>
* @param other The other tree container you want to merge.
*/
abstract union(other: TreeContainer<K, V>): void;
/**
* @description Make self balance after erase a node.
* @param curNode The node want to remove.
* @protected
*/
protected eraseNodeSelfBalance(curNode: TreeNode<K, V>): void;
/**
* @description Remove a node.
* @param curNode The node you want to remove.
* @protected
*/
protected eraseNode(curNode: TreeNode<K, V>): void;
/**
* @description InOrder traversal the tree.
* @protected
*/
protected inOrderTraversal: (curNode: TreeNode<K, V> | undefined, callback: (curNode: TreeNode<K, V>) => boolean) => boolean;
/**
* @description Make self balance after insert a node.
* @param curNode The node want to insert.
* @protected
*/
protected insertNodeSelfBalance(curNode: TreeNode<K, V>): void;
/**
* @description Find node which key is equals to the given key.
* @param curNode The starting node of the search.
* @param key The key you want to search.
* @protected
*/
protected findElementNode(curNode: TreeNode<K, V> | undefined, key: K): TreeNode<K, V> | undefined;
/**
* @description Insert a key-value pair or set value by the given key.
* @param key The key want to insert.
* @param value The value want to set.
* @param hint You can give an iterator hint to improve insertion efficiency.
* @protected
*/
protected set(key: K, value?: V, hint?: TreeIterator<K, V>): void;
clear(): void;
/**
* @description Update node's key by iterator.
* @param iter The iterator you want to change.
* @param key The key you want to update.
* @return Boolean about if the modification is successful.
*/
updateKeyByIterator(iter: TreeIterator<K, V>, key: K): boolean;
eraseElementByPos(pos: number): void;
/**
* @description Remove the element of the specified key.
* @param key The key you want to remove.
*/
eraseElementByKey(key: K): void;
eraseElementByIterator(iter: TreeIterator<K, V>): TreeIterator<K, V>;
/**
* @description Get the height of the tree.
* @return Number about the height of the RB-tree.
*/
getHeight(): number;
}
export default TreeContainer;

View File

@@ -0,0 +1,569 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const TreeNode_1 = __importDefault(require("./TreeNode"));
const index_1 = require("../../ContainerBase/index");
const checkParams_1 = require("../../../utils/checkParams");
class TreeContainer extends index_1.Container {
constructor(cmp = (x, y) => {
if (x < y)
return -1;
if (x > y)
return 1;
return 0;
}) {
super();
this.root = undefined;
this.header = new TreeNode_1.default();
/**
* @description InOrder traversal the tree.
* @protected
*/
this.inOrderTraversal = (curNode, callback) => {
if (curNode === undefined)
return false;
const ifReturn = this.inOrderTraversal(curNode.left, callback);
if (ifReturn)
return true;
if (callback(curNode))
return true;
return this.inOrderTraversal(curNode.right, callback);
};
this.cmp = cmp;
}
/**
* @param curNode The starting node of the search.
* @param key The key you want to search.
* @return TreeNode which key is greater than or equals to the given key.
* @protected
*/
_lowerBound(curNode, key) {
let resNode;
while (curNode) {
const cmpResult = this.cmp(curNode.key, key);
if (cmpResult < 0) {
curNode = curNode.right;
}
else if (cmpResult > 0) {
resNode = curNode;
curNode = curNode.left;
}
else
return curNode;
}
return resNode === undefined ? this.header : resNode;
}
/**
* @param curNode The starting node of the search.
* @param key The key you want to search.
* @return TreeNode which key is greater than the given key.
* @protected
*/
_upperBound(curNode, key) {
let resNode;
while (curNode) {
const cmpResult = this.cmp(curNode.key, key);
if (cmpResult <= 0) {
curNode = curNode.right;
}
else if (cmpResult > 0) {
resNode = curNode;
curNode = curNode.left;
}
}
return resNode === undefined ? this.header : resNode;
}
/**
* @param curNode The starting node of the search.
* @param key The key you want to search.
* @return TreeNode which key is less than or equals to the given key.
* @protected
*/
_reverseLowerBound(curNode, key) {
let resNode;
while (curNode) {
const cmpResult = this.cmp(curNode.key, key);
if (cmpResult < 0) {
resNode = curNode;
curNode = curNode.right;
}
else if (cmpResult > 0) {
curNode = curNode.left;
}
else
return curNode;
}
return resNode === undefined ? this.header : resNode;
}
/**
* @param curNode The starting node of the search.
* @param key The key you want to search.
* @return TreeNode which key is less than the given key.
* @protected
*/
_reverseUpperBound(curNode, key) {
let resNode;
while (curNode) {
const cmpResult = this.cmp(curNode.key, key);
if (cmpResult < 0) {
resNode = curNode;
curNode = curNode.right;
}
else if (cmpResult >= 0) {
curNode = curNode.left;
}
}
return resNode === undefined ? this.header : resNode;
}
/**
* @description Make self balance after erase a node.
* @param curNode The node want to remove.
* @protected
*/
eraseNodeSelfBalance(curNode) {
while (true) {
const parentNode = curNode.parent;
if (parentNode === this.header)
return;
if (curNode.color === TreeNode_1.default.RED) {
curNode.color = TreeNode_1.default.BLACK;
return;
}
if (curNode === parentNode.left) {
const brother = parentNode.right;
if (brother.color === TreeNode_1.default.RED) {
brother.color = TreeNode_1.default.BLACK;
parentNode.color = TreeNode_1.default.RED;
if (parentNode === this.root) {
this.root = parentNode.rotateLeft();
}
else
parentNode.rotateLeft();
}
else if (brother.color === TreeNode_1.default.BLACK) {
if (brother.right && brother.right.color === TreeNode_1.default.RED) {
brother.color = parentNode.color;
parentNode.color = TreeNode_1.default.BLACK;
brother.right.color = TreeNode_1.default.BLACK;
if (parentNode === this.root) {
this.root = parentNode.rotateLeft();
}
else
parentNode.rotateLeft();
return;
}
else if (brother.left && brother.left.color === TreeNode_1.default.RED) {
brother.color = TreeNode_1.default.RED;
brother.left.color = TreeNode_1.default.BLACK;
brother.rotateRight();
}
else {
brother.color = TreeNode_1.default.RED;
curNode = parentNode;
}
}
}
else {
const brother = parentNode.left;
if (brother.color === TreeNode_1.default.RED) {
brother.color = TreeNode_1.default.BLACK;
parentNode.color = TreeNode_1.default.RED;
if (parentNode === this.root) {
this.root = parentNode.rotateRight();
}
else
parentNode.rotateRight();
}
else {
if (brother.left && brother.left.color === TreeNode_1.default.RED) {
brother.color = parentNode.color;
parentNode.color = TreeNode_1.default.BLACK;
brother.left.color = TreeNode_1.default.BLACK;
if (parentNode === this.root) {
this.root = parentNode.rotateRight();
}
else
parentNode.rotateRight();
return;
}
else if (brother.right && brother.right.color === TreeNode_1.default.RED) {
brother.color = TreeNode_1.default.RED;
brother.right.color = TreeNode_1.default.BLACK;
brother.rotateLeft();
}
else {
brother.color = TreeNode_1.default.RED;
curNode = parentNode;
}
}
}
}
}
/**
* @description Remove a node.
* @param curNode The node you want to remove.
* @protected
*/
eraseNode(curNode) {
if (this.length === 1) {
this.clear();
return;
}
let swapNode = curNode;
while (swapNode.left || swapNode.right) {
if (swapNode.right) {
swapNode = swapNode.right;
while (swapNode.left)
swapNode = swapNode.left;
}
else if (swapNode.left) {
swapNode = swapNode.left;
}
[curNode.key, swapNode.key] = [swapNode.key, curNode.key];
[curNode.value, swapNode.value] = [swapNode.value, curNode.value];
curNode = swapNode;
}
if (this.header.left === swapNode) {
this.header.left = swapNode.parent;
}
else if (this.header.right === swapNode) {
this.header.right = swapNode.parent;
}
this.eraseNodeSelfBalance(swapNode);
swapNode.remove();
this.length -= 1;
this.root.color = TreeNode_1.default.BLACK;
}
/**
* @description Make self balance after insert a node.
* @param curNode The node want to insert.
* @protected
*/
insertNodeSelfBalance(curNode) {
while (true) {
const parentNode = curNode.parent;
if (parentNode.color === TreeNode_1.default.BLACK)
return;
const grandParent = parentNode.parent;
if (parentNode === grandParent.left) {
const uncle = grandParent.right;
if (uncle && uncle.color === TreeNode_1.default.RED) {
uncle.color = parentNode.color = TreeNode_1.default.BLACK;
if (grandParent === this.root)
return;
grandParent.color = TreeNode_1.default.RED;
curNode = grandParent;
continue;
}
else if (curNode === parentNode.right) {
curNode.color = TreeNode_1.default.BLACK;
if (curNode.left)
curNode.left.parent = parentNode;
if (curNode.right)
curNode.right.parent = grandParent;
parentNode.right = curNode.left;
grandParent.left = curNode.right;
curNode.left = parentNode;
curNode.right = grandParent;
if (grandParent === this.root) {
this.root = curNode;
this.header.parent = curNode;
}
else {
const GP = grandParent.parent;
if (GP.left === grandParent) {
GP.left = curNode;
}
else
GP.right = curNode;
}
curNode.parent = grandParent.parent;
parentNode.parent = curNode;
grandParent.parent = curNode;
}
else {
parentNode.color = TreeNode_1.default.BLACK;
if (grandParent === this.root) {
this.root = grandParent.rotateRight();
}
else
grandParent.rotateRight();
}
grandParent.color = TreeNode_1.default.RED;
}
else {
const uncle = grandParent.left;
if (uncle && uncle.color === TreeNode_1.default.RED) {
uncle.color = parentNode.color = TreeNode_1.default.BLACK;
if (grandParent === this.root)
return;
grandParent.color = TreeNode_1.default.RED;
curNode = grandParent;
continue;
}
else if (curNode === parentNode.left) {
curNode.color = TreeNode_1.default.BLACK;
if (curNode.left)
curNode.left.parent = grandParent;
if (curNode.right)
curNode.right.parent = parentNode;
grandParent.right = curNode.left;
parentNode.left = curNode.right;
curNode.left = grandParent;
curNode.right = parentNode;
if (grandParent === this.root) {
this.root = curNode;
this.header.parent = curNode;
}
else {
const GP = grandParent.parent;
if (GP.left === grandParent) {
GP.left = curNode;
}
else
GP.right = curNode;
}
curNode.parent = grandParent.parent;
parentNode.parent = curNode;
grandParent.parent = curNode;
}
else {
parentNode.color = TreeNode_1.default.BLACK;
if (grandParent === this.root) {
this.root = grandParent.rotateLeft();
}
else
grandParent.rotateLeft();
}
grandParent.color = TreeNode_1.default.RED;
}
return;
}
}
/**
* @description Find node which key is equals to the given key.
* @param curNode The starting node of the search.
* @param key The key you want to search.
* @protected
*/
findElementNode(curNode, key) {
while (curNode) {
const cmpResult = this.cmp(curNode.key, key);
if (cmpResult < 0) {
curNode = curNode.right;
}
else if (cmpResult > 0) {
curNode = curNode.left;
}
else
return curNode;
}
return curNode;
}
/**
* @description Insert a key-value pair or set value by the given key.
* @param key The key want to insert.
* @param value The value want to set.
* @param hint You can give an iterator hint to improve insertion efficiency.
* @protected
*/
set(key, value, hint) {
if (this.root === undefined) {
this.length += 1;
this.root = new TreeNode_1.default(key, value);
this.root.color = TreeNode_1.default.BLACK;
this.root.parent = this.header;
this.header.parent = this.root;
this.header.left = this.root;
this.header.right = this.root;
return;
}
let curNode;
const minNode = this.header.left;
const compareToMin = this.cmp(minNode.key, key);
if (compareToMin === 0) {
minNode.value = value;
return;
}
else if (compareToMin > 0) {
minNode.left = new TreeNode_1.default(key, value);
minNode.left.parent = minNode;
curNode = minNode.left;
this.header.left = curNode;
}
else {
const maxNode = this.header.right;
const compareToMax = this.cmp(maxNode.key, key);
if (compareToMax === 0) {
maxNode.value = value;
return;
}
else if (compareToMax < 0) {
maxNode.right = new TreeNode_1.default(key, value);
maxNode.right.parent = maxNode;
curNode = maxNode.right;
this.header.right = curNode;
}
else {
if (hint !== undefined) {
// @ts-ignore
const iterNode = hint.node;
if (iterNode !== this.header) {
const iterCmpRes = this.cmp(iterNode.key, key);
if (iterCmpRes === 0) {
iterNode.value = value;
return;
}
else if (iterCmpRes > 0) {
const preNode = iterNode.pre();
const preCmpRes = this.cmp(preNode.key, key);
if (preCmpRes === 0) {
preNode.value = value;
return;
}
else if (preCmpRes < 0) {
curNode = new TreeNode_1.default(key, value);
if (preNode.right === undefined) {
preNode.right = curNode;
curNode.parent = preNode;
}
else {
iterNode.left = curNode;
curNode.parent = iterNode;
}
}
}
}
}
if (curNode === undefined) {
curNode = this.root;
while (true) {
const cmpResult = this.cmp(curNode.key, key);
if (cmpResult > 0) {
if (curNode.left === undefined) {
curNode.left = new TreeNode_1.default(key, value);
curNode.left.parent = curNode;
curNode = curNode.left;
break;
}
curNode = curNode.left;
}
else if (cmpResult < 0) {
if (curNode.right === undefined) {
curNode.right = new TreeNode_1.default(key, value);
curNode.right.parent = curNode;
curNode = curNode.right;
break;
}
curNode = curNode.right;
}
else {
curNode.value = value;
return;
}
}
}
}
}
this.length += 1;
this.insertNodeSelfBalance(curNode);
}
clear() {
this.length = 0;
this.root = undefined;
this.header.parent = undefined;
this.header.left = this.header.right = undefined;
}
/**
* @description Update node's key by iterator.
* @param iter The iterator you want to change.
* @param key The key you want to update.
* @return Boolean about if the modification is successful.
*/
updateKeyByIterator(iter, key) {
// @ts-ignore
const node = iter.node;
if (node === this.header) {
throw new TypeError('Invalid iterator!');
}
if (this.length === 1) {
node.key = key;
return true;
}
if (node === this.header.left) {
if (this.cmp(node.next().key, key) > 0) {
node.key = key;
return true;
}
return false;
}
if (node === this.header.right) {
if (this.cmp(node.pre().key, key) < 0) {
node.key = key;
return true;
}
return false;
}
const preKey = node.pre().key;
if (this.cmp(preKey, key) >= 0)
return false;
const nextKey = node.next().key;
if (this.cmp(nextKey, key) <= 0)
return false;
node.key = key;
return true;
}
eraseElementByPos(pos) {
(0, checkParams_1.checkWithinAccessParams)(pos, 0, this.length - 1);
let index = 0;
this.inOrderTraversal(this.root, curNode => {
if (pos === index) {
this.eraseNode(curNode);
return true;
}
index += 1;
return false;
});
}
/**
* @description Remove the element of the specified key.
* @param key The key you want to remove.
*/
eraseElementByKey(key) {
if (!this.length)
return;
const curNode = this.findElementNode(this.root, key);
if (curNode === undefined)
return;
this.eraseNode(curNode);
}
eraseElementByIterator(iter) {
// @ts-ignore
const node = iter.node;
if (node === this.header) {
throw new RangeError('Invalid iterator');
}
if (node.right === undefined) {
iter = iter.next();
}
this.eraseNode(node);
return iter;
}
/**
* @description Get the height of the tree.
* @return Number about the height of the RB-tree.
*/
getHeight() {
if (!this.length)
return 0;
const traversal = (curNode) => {
if (!curNode)
return 0;
return Math.max(traversal(curNode.left), traversal(curNode.right)) + 1;
};
return traversal(this.root);
}
}
exports.default = TreeContainer;

View File

@@ -0,0 +1,38 @@
import { initContainer } from "../ContainerBase/index";
import TreeContainer from './Base/index';
import TreeIterator from './Base/TreeIterator';
export declare class OrderedMapIterator<K, V> extends TreeIterator<K, V> {
get pointer(): [K, V];
copy(): OrderedMapIterator<K, V>;
}
declare class OrderedMap<K, V> extends TreeContainer<K, V> {
constructor(container?: initContainer<[K, V]>, cmp?: (x: K, y: K) => number);
private readonly iterationFunc;
begin(): OrderedMapIterator<K, V>;
end(): OrderedMapIterator<K, V>;
rBegin(): OrderedMapIterator<K, V>;
rEnd(): OrderedMapIterator<K, V>;
front(): [K, V] | undefined;
back(): [K, V] | undefined;
forEach(callback: (element: [K, V], index: number) => void): void;
lowerBound(key: K): OrderedMapIterator<K, V>;
upperBound(key: K): OrderedMapIterator<K, V>;
reverseLowerBound(key: K): OrderedMapIterator<K, V>;
reverseUpperBound(key: K): OrderedMapIterator<K, V>;
/**
* @description Insert a key-value pair or set value by the given key.
* @param key The key want to insert.
* @param value The value want to set.
* @param hint You can give an iterator hint to improve insertion efficiency.
*/
setElement(key: K, value: V, hint?: OrderedMapIterator<K, V>): void;
find(key: K): OrderedMapIterator<K, V>;
/**
* @description Get the value of the element of the specified key.
*/
getElementByKey(key: K): V | undefined;
getElementByPos(pos: number): [K, V];
union(other: OrderedMap<K, V>): void;
[Symbol.iterator](): Generator<[K, V], void, undefined>;
}
export default OrderedMap;

View File

@@ -0,0 +1,138 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.OrderedMapIterator = void 0;
const index_1 = require("../ContainerBase/index");
const checkParams_1 = require("../../utils/checkParams");
const index_2 = __importDefault(require("./Base/index"));
const TreeIterator_1 = __importDefault(require("./Base/TreeIterator"));
class OrderedMapIterator extends TreeIterator_1.default {
get pointer() {
if (this.node === this.header) {
throw new RangeError('OrderedMap iterator access denied');
}
return new Proxy([], {
get: (_, props) => {
if (props === '0')
return this.node.key;
else if (props === '1')
return this.node.value;
},
set: (_, props, newValue) => {
if (props !== '1') {
throw new TypeError('props must be 1');
}
this.node.value = newValue;
return true;
}
});
}
copy() {
return new OrderedMapIterator(this.node, this.header, this.iteratorType);
}
}
exports.OrderedMapIterator = OrderedMapIterator;
class OrderedMap extends index_2.default {
constructor(container = [], cmp) {
super(cmp);
this.iterationFunc = function* (curNode) {
if (curNode === undefined)
return;
yield* this.iterationFunc(curNode.left);
yield [curNode.key, curNode.value];
yield* this.iterationFunc(curNode.right);
};
this.iterationFunc = this.iterationFunc.bind(this);
container.forEach(([key, value]) => this.setElement(key, value));
}
begin() {
return new OrderedMapIterator(this.header.left || this.header, this.header);
}
end() {
return new OrderedMapIterator(this.header, this.header);
}
rBegin() {
return new OrderedMapIterator(this.header.right || this.header, this.header, index_1.ContainerIterator.REVERSE);
}
rEnd() {
return new OrderedMapIterator(this.header, this.header, index_1.ContainerIterator.REVERSE);
}
front() {
if (!this.length)
return undefined;
const minNode = this.header.left;
return [minNode.key, minNode.value];
}
back() {
if (!this.length)
return undefined;
const maxNode = this.header.right;
return [maxNode.key, maxNode.value];
}
forEach(callback) {
let index = 0;
for (const pair of this)
callback(pair, index++);
}
lowerBound(key) {
const resNode = this._lowerBound(this.root, key);
return new OrderedMapIterator(resNode, this.header);
}
upperBound(key) {
const resNode = this._upperBound(this.root, key);
return new OrderedMapIterator(resNode, this.header);
}
reverseLowerBound(key) {
const resNode = this._reverseLowerBound(this.root, key);
return new OrderedMapIterator(resNode, this.header);
}
reverseUpperBound(key) {
const resNode = this._reverseUpperBound(this.root, key);
return new OrderedMapIterator(resNode, this.header);
}
/**
* @description Insert a key-value pair or set value by the given key.
* @param key The key want to insert.
* @param value The value want to set.
* @param hint You can give an iterator hint to improve insertion efficiency.
*/
setElement(key, value, hint) {
this.set(key, value, hint);
}
find(key) {
const curNode = this.findElementNode(this.root, key);
if (curNode !== undefined) {
return new OrderedMapIterator(curNode, this.header);
}
return this.end();
}
/**
* @description Get the value of the element of the specified key.
*/
getElementByKey(key) {
const curNode = this.findElementNode(this.root, key);
return curNode ? curNode.value : undefined;
}
getElementByPos(pos) {
(0, checkParams_1.checkWithinAccessParams)(pos, 0, this.length - 1);
let res;
let index = 0;
for (const pair of this) {
if (index === pos) {
res = pair;
break;
}
index += 1;
}
return res;
}
union(other) {
other.forEach(([key, value]) => this.setElement(key, value));
}
[Symbol.iterator]() {
return this.iterationFunc(this.root);
}
}
exports.default = OrderedMap;

View File

@@ -0,0 +1,33 @@
import TreeContainer from './Base/index';
import { initContainer } from "../ContainerBase/index";
import TreeIterator from './Base/TreeIterator';
export declare class OrderedSetIterator<K> extends TreeIterator<K, undefined> {
get pointer(): K;
copy(): OrderedSetIterator<K>;
}
declare class OrderedSet<K> extends TreeContainer<K, undefined> {
constructor(container?: initContainer<K>, cmp?: (x: K, y: K) => number);
private readonly iterationFunc;
begin(): OrderedSetIterator<K>;
end(): OrderedSetIterator<K>;
rBegin(): OrderedSetIterator<K>;
rEnd(): OrderedSetIterator<K>;
front(): K | undefined;
back(): K | undefined;
forEach(callback: (element: K, index: number) => void): void;
getElementByPos(pos: number): K;
/**
* @description Insert element to set.
* @param key The key want to insert.
* @param hint You can give an iterator hint to improve insertion efficiency.
*/
insert(key: K, hint?: OrderedSetIterator<K>): void;
find(element: K): OrderedSetIterator<K>;
lowerBound(key: K): OrderedSetIterator<K>;
upperBound(key: K): OrderedSetIterator<K>;
reverseLowerBound(key: K): OrderedSetIterator<K>;
reverseUpperBound(key: K): OrderedSetIterator<K>;
union(other: OrderedSet<K>): void;
[Symbol.iterator](): Generator<K, void, undefined>;
}
export default OrderedSet;

View File

@@ -0,0 +1,109 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.OrderedSetIterator = void 0;
const index_1 = __importDefault(require("./Base/index"));
const index_2 = require("../ContainerBase/index");
const checkParams_1 = require("../../utils/checkParams");
const TreeIterator_1 = __importDefault(require("./Base/TreeIterator"));
class OrderedSetIterator extends TreeIterator_1.default {
get pointer() {
if (this.node === this.header) {
throw new RangeError('OrderedSet iterator access denied!');
}
return this.node.key;
}
copy() {
return new OrderedSetIterator(this.node, this.header, this.iteratorType);
}
}
exports.OrderedSetIterator = OrderedSetIterator;
class OrderedSet extends index_1.default {
constructor(container = [], cmp) {
super(cmp);
this.iterationFunc = function* (curNode) {
if (curNode === undefined)
return;
yield* this.iterationFunc(curNode.left);
yield curNode.key;
yield* this.iterationFunc(curNode.right);
};
container.forEach((element) => this.insert(element));
this.iterationFunc = this.iterationFunc.bind(this);
}
begin() {
return new OrderedSetIterator(this.header.left || this.header, this.header);
}
end() {
return new OrderedSetIterator(this.header, this.header);
}
rBegin() {
return new OrderedSetIterator(this.header.right || this.header, this.header, index_2.ContainerIterator.REVERSE);
}
rEnd() {
return new OrderedSetIterator(this.header, this.header, index_2.ContainerIterator.REVERSE);
}
front() {
return this.header.left ? this.header.left.key : undefined;
}
back() {
return this.header.right ? this.header.right.key : undefined;
}
forEach(callback) {
let index = 0;
for (const element of this)
callback(element, index++);
}
getElementByPos(pos) {
(0, checkParams_1.checkWithinAccessParams)(pos, 0, this.length - 1);
let res;
let index = 0;
for (const element of this) {
if (index === pos) {
res = element;
}
index += 1;
}
return res;
}
/**
* @description Insert element to set.
* @param key The key want to insert.
* @param hint You can give an iterator hint to improve insertion efficiency.
*/
insert(key, hint) {
this.set(key, undefined, hint);
}
find(element) {
const curNode = this.findElementNode(this.root, element);
if (curNode !== undefined) {
return new OrderedSetIterator(curNode, this.header);
}
return this.end();
}
lowerBound(key) {
const resNode = this._lowerBound(this.root, key);
return new OrderedSetIterator(resNode, this.header);
}
upperBound(key) {
const resNode = this._upperBound(this.root, key);
return new OrderedSetIterator(resNode, this.header);
}
reverseLowerBound(key) {
const resNode = this._reverseLowerBound(this.root, key);
return new OrderedSetIterator(resNode, this.header);
}
reverseUpperBound(key) {
const resNode = this._reverseUpperBound(this.root, key);
return new OrderedSetIterator(resNode, this.header);
}
union(other) {
other.forEach((element) => this.insert(element));
}
[Symbol.iterator]() {
return this.iterationFunc(this.root);
}
}
exports.default = OrderedSet;

14
WebUI/node_modules/js-sdsl/dist/cjs/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,14 @@
export { default as Stack } from "./container/OtherContainer/Stack";
export { default as Queue } from "./container/OtherContainer/Queue";
export { default as PriorityQueue } from "./container/OtherContainer/PriorityQueue";
export { default as Vector, VectorIterator } from "./container/SequentialContainer/Vector";
export { default as LinkList, LinkListIterator } from "./container/SequentialContainer/LinkList";
export { default as Deque, DequeIterator } from "./container/SequentialContainer/Deque";
export { default as OrderedSet, OrderedSetIterator } from "./container/TreeContainer/OrderedSet";
export { default as OrderedMap, OrderedMapIterator } from "./container/TreeContainer/OrderedMap";
export { default as HashSet } from "./container/HashContainer/HashSet";
export { default as HashMap } from "./container/HashContainer/HashMap";
export { Container, ContainerIterator } from "./container/ContainerBase/index";
export { default as SequentialContainer } from "./container/SequentialContainer/Base/index";
export { default as TreeContainer } from "./container/TreeContainer/Base/index";
export { default as HashContainer } from "./container/HashContainer/Base/index";

40
WebUI/node_modules/js-sdsl/dist/cjs/index.js generated vendored Normal file
View File

@@ -0,0 +1,40 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.HashContainer = exports.TreeContainer = exports.SequentialContainer = exports.ContainerIterator = exports.Container = exports.HashMap = exports.HashSet = exports.OrderedMapIterator = exports.OrderedMap = exports.OrderedSetIterator = exports.OrderedSet = exports.DequeIterator = exports.Deque = exports.LinkListIterator = exports.LinkList = exports.VectorIterator = exports.Vector = exports.PriorityQueue = exports.Queue = exports.Stack = void 0;
var Stack_1 = require("./container/OtherContainer/Stack");
Object.defineProperty(exports, "Stack", { enumerable: true, get: function () { return __importDefault(Stack_1).default; } });
var Queue_1 = require("./container/OtherContainer/Queue");
Object.defineProperty(exports, "Queue", { enumerable: true, get: function () { return __importDefault(Queue_1).default; } });
var PriorityQueue_1 = require("./container/OtherContainer/PriorityQueue");
Object.defineProperty(exports, "PriorityQueue", { enumerable: true, get: function () { return __importDefault(PriorityQueue_1).default; } });
var Vector_1 = require("./container/SequentialContainer/Vector");
Object.defineProperty(exports, "Vector", { enumerable: true, get: function () { return __importDefault(Vector_1).default; } });
Object.defineProperty(exports, "VectorIterator", { enumerable: true, get: function () { return Vector_1.VectorIterator; } });
var LinkList_1 = require("./container/SequentialContainer/LinkList");
Object.defineProperty(exports, "LinkList", { enumerable: true, get: function () { return __importDefault(LinkList_1).default; } });
Object.defineProperty(exports, "LinkListIterator", { enumerable: true, get: function () { return LinkList_1.LinkListIterator; } });
var Deque_1 = require("./container/SequentialContainer/Deque");
Object.defineProperty(exports, "Deque", { enumerable: true, get: function () { return __importDefault(Deque_1).default; } });
Object.defineProperty(exports, "DequeIterator", { enumerable: true, get: function () { return Deque_1.DequeIterator; } });
var OrderedSet_1 = require("./container/TreeContainer/OrderedSet");
Object.defineProperty(exports, "OrderedSet", { enumerable: true, get: function () { return __importDefault(OrderedSet_1).default; } });
Object.defineProperty(exports, "OrderedSetIterator", { enumerable: true, get: function () { return OrderedSet_1.OrderedSetIterator; } });
var OrderedMap_1 = require("./container/TreeContainer/OrderedMap");
Object.defineProperty(exports, "OrderedMap", { enumerable: true, get: function () { return __importDefault(OrderedMap_1).default; } });
Object.defineProperty(exports, "OrderedMapIterator", { enumerable: true, get: function () { return OrderedMap_1.OrderedMapIterator; } });
var HashSet_1 = require("./container/HashContainer/HashSet");
Object.defineProperty(exports, "HashSet", { enumerable: true, get: function () { return __importDefault(HashSet_1).default; } });
var HashMap_1 = require("./container/HashContainer/HashMap");
Object.defineProperty(exports, "HashMap", { enumerable: true, get: function () { return __importDefault(HashMap_1).default; } });
var index_1 = require("./container/ContainerBase/index");
Object.defineProperty(exports, "Container", { enumerable: true, get: function () { return index_1.Container; } });
Object.defineProperty(exports, "ContainerIterator", { enumerable: true, get: function () { return index_1.ContainerIterator; } });
var index_2 = require("./container/SequentialContainer/Base/index");
Object.defineProperty(exports, "SequentialContainer", { enumerable: true, get: function () { return __importDefault(index_2).default; } });
var index_3 = require("./container/TreeContainer/Base/index");
Object.defineProperty(exports, "TreeContainer", { enumerable: true, get: function () { return __importDefault(index_3).default; } });
var index_4 = require("./container/HashContainer/Base/index");
Object.defineProperty(exports, "HashContainer", { enumerable: true, get: function () { return __importDefault(index_4).default; } });

View File

@@ -0,0 +1,8 @@
/**
* @description Check if access is out of bounds.
* @param pos The position want to access.
* @param lower The lower bound.
* @param upper The upper bound.
* @return Boolean about if access is out of bounds.
*/
export declare function checkWithinAccessParams(pos: number, lower: number, upper: number): void;

View File

@@ -0,0 +1,16 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.checkWithinAccessParams = void 0;
/**
* @description Check if access is out of bounds.
* @param pos The position want to access.
* @param lower The lower bound.
* @param upper The upper bound.
* @return Boolean about if access is out of bounds.
*/
function checkWithinAccessParams(pos, lower, upper) {
if (pos < lower || pos > upper) {
throw new RangeError();
}
}
exports.checkWithinAccessParams = checkWithinAccessParams;

View File

@@ -0,0 +1,124 @@
export declare abstract class ContainerIterator<T> {
static readonly NORMAL = false;
static readonly REVERSE = true;
/**
* @description Iterator's type.
*/
readonly iteratorType: boolean;
protected node: unknown;
protected constructor(iteratorType?: boolean);
/**
* @description Pointers to element.
* @return The value of the pointer's element.
*/
abstract get pointer(): T;
/**
* @description Set pointer's value (some containers are unavailable).
* @param newValue The new value you want to set.
*/
abstract set pointer(newValue: T);
/**
* @description Move `this` iterator to pre.
*/
abstract pre(): this;
/**
* @description Move `this` iterator to next.
*/
abstract next(): this;
/**
* @param obj The other iterator you want to compare.
* @return Boolean about if this equals to obj.
* @example container.find(1).equals(container.end());
*/
abstract equals(obj: ContainerIterator<T>): boolean;
/**
* @description Get a copy of itself.<br/>
* We do not guarantee the safety of this function.<br/>
* Please ensure that the iterator will not fail.
* @return The copy of self.
*/
abstract copy(): ContainerIterator<T>;
}
export declare abstract class Base {
/**
* @description Container's size.
* @protected
*/
protected length: number;
/**
* @return The size of the container.
*/
size(): number;
/**
* @return Boolean about if the container is empty.
*/
empty(): boolean;
/**
* @description Clear the container.
*/
abstract clear(): void;
}
export declare abstract class Container<T> extends Base {
/**
* @return Iterator pointing to the beginning element.
*/
abstract begin(): ContainerIterator<T>;
/**
* @return Iterator pointing to the super end like c++.
*/
abstract end(): ContainerIterator<T>;
/**
* @return Iterator pointing to the end element.
*/
abstract rBegin(): ContainerIterator<T>;
/**
* @return Iterator pointing to the super begin like c++.
*/
abstract rEnd(): ContainerIterator<T>;
/**
* @return The first element of the container.
*/
abstract front(): T | undefined;
/**
* @return The last element of the container.
*/
abstract back(): T | undefined;
/**
* @description Iterate over all elements in the container.
* @param callback Callback function like Array.forEach.
*/
abstract forEach(callback: (element: T, index: number) => void): void;
/**
* @param element The element you want to find.
* @return An iterator pointing to the element if found, or super end if not found.
*/
abstract find(element: T): ContainerIterator<T>;
/**
* @description Gets the value of the element at the specified position.
*/
abstract getElementByPos(pos: number): T;
/**
* @description Removes the element at the specified position.
* @param pos The element's position you want to remove.
*/
abstract eraseElementByPos(pos: number): void;
/**
* @description Removes element by iterator and move `iter` to next.
* @param iter The iterator you want to erase.
* @example container.eraseElementByIterator(container.begin());
*/
abstract eraseElementByIterator(iter: ContainerIterator<T>): ContainerIterator<T>;
/**
* @description Using for 'for...of' syntax like Array.
*/
abstract [Symbol.iterator](): Generator<T, void, undefined>;
}
export declare type initContainer<T> = ({
size: number;
} | {
length: number;
} | {
size(): number;
}) & {
forEach(callback: (element: T) => void): void;
};

View File

@@ -0,0 +1,56 @@
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var ContainerIterator = /** @class */ (function () {
function ContainerIterator(iteratorType) {
if (iteratorType === void 0) { iteratorType = ContainerIterator.NORMAL; }
this.iteratorType = iteratorType;
}
ContainerIterator.NORMAL = false;
ContainerIterator.REVERSE = true;
return ContainerIterator;
}());
export { ContainerIterator };
var Base = /** @class */ (function () {
function Base() {
/**
* @description Container's size.
* @protected
*/
this.length = 0;
}
/**
* @return The size of the container.
*/
Base.prototype.size = function () {
return this.length;
};
/**
* @return Boolean about if the container is empty.
*/
Base.prototype.empty = function () {
return this.length === 0;
};
return Base;
}());
export { Base };
var Container = /** @class */ (function (_super) {
__extends(Container, _super);
function Container() {
return _super !== null && _super.apply(this, arguments) || this;
}
return Container;
}(Base));
export { Container };

View File

@@ -0,0 +1,32 @@
import { Base, Container } from "../../ContainerBase/index";
declare abstract class HashContainer<K> extends Base {
protected static readonly sigma = 0.75;
protected static readonly treeifyThreshold = 8;
protected static readonly untreeifyThreshold = 6;
protected static readonly minTreeifySize = 64;
protected static readonly maxBucketNum: number;
protected bucketNum: number;
protected initBucketNum: number;
protected hashFunc: (x: K) => number;
protected abstract hashTable: Container<unknown>[];
protected constructor(initBucketNum?: number, hashFunc?: (x: K) => number);
clear(): void;
/**
* @description Growth the hash table.
* @protected
*/
protected abstract reAllocate(): void;
abstract forEach(callback: (element: unknown, index: number) => void): void;
/**
* @description Remove the elements of the specified value.
* @param key The element you want to remove.
*/
abstract eraseElementByKey(key: K): void;
/**
* @param key The element you want to find.
* @return Boolean about if the specified element in the hash set.
*/
abstract find(key: K): void;
abstract [Symbol.iterator](): Generator<unknown, void, undefined>;
}
export default HashContainer;

View File

@@ -0,0 +1,57 @@
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
import { Base } from "../../ContainerBase/index";
var HashContainer = /** @class */ (function (_super) {
__extends(HashContainer, _super);
function HashContainer(initBucketNum, hashFunc) {
if (initBucketNum === void 0) { initBucketNum = 16; }
if (hashFunc === void 0) { hashFunc = function (x) {
var str;
if (typeof x !== 'string') {
str = JSON.stringify(x);
}
else
str = x;
var hashCode = 0;
var strLength = str.length;
for (var i = 0; i < strLength; i++) {
var ch = str.charCodeAt(i);
hashCode = ((hashCode << 5) - hashCode) + ch;
hashCode |= 0;
}
return hashCode >>> 0;
}; }
var _this = _super.call(this) || this;
if (initBucketNum < 16 || (initBucketNum & (initBucketNum - 1)) !== 0) {
throw new RangeError('InitBucketNum range error');
}
_this.bucketNum = _this.initBucketNum = initBucketNum;
_this.hashFunc = hashFunc;
return _this;
}
HashContainer.prototype.clear = function () {
this.length = 0;
this.bucketNum = this.initBucketNum;
this.hashTable = [];
};
HashContainer.sigma = 0.75;
HashContainer.treeifyThreshold = 8;
HashContainer.untreeifyThreshold = 6;
HashContainer.minTreeifySize = 64;
HashContainer.maxBucketNum = (1 << 30);
return HashContainer;
}(Base));
export default HashContainer;

View File

@@ -0,0 +1,26 @@
import HashContainer from './Base/index';
import Vector from '../SequentialContainer/Vector';
import OrderedMap from '../TreeContainer/OrderedMap';
import { initContainer } from "../ContainerBase/index";
declare class HashMap<K, V> extends HashContainer<K> {
protected hashTable: (Vector<[K, V]> | OrderedMap<K, V>)[];
constructor(container?: initContainer<[K, V]>, initBucketNum?: number, hashFunc?: (x: K) => number);
protected reAllocate(): void;
forEach(callback: (element: [K, V], index: number) => void): void;
/**
* @description Insert a new key-value pair to hash map or set value by key.
* @param key The key you want to insert.
* @param value The value you want to insert.
* @example HashMap.setElement(1, 2); // insert a key-value pair [1, 2]
*/
setElement(key: K, value: V): void;
/**
* @description Get the value of the element which has the specified key.
* @param key The key you want to get.
*/
getElementByKey(key: K): V | undefined;
eraseElementByKey(key: K): void;
find(key: K): boolean;
[Symbol.iterator](): Generator<[K, V], void, unknown>;
}
export default HashMap;

View File

@@ -0,0 +1,337 @@
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __values = (this && this.__values) || function(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
import HashContainer from './Base/index';
import Vector from '../SequentialContainer/Vector';
import OrderedMap from '../TreeContainer/OrderedMap';
var HashMap = /** @class */ (function (_super) {
__extends(HashMap, _super);
function HashMap(container, initBucketNum, hashFunc) {
if (container === void 0) { container = []; }
var _this = _super.call(this, initBucketNum, hashFunc) || this;
_this.hashTable = [];
container.forEach(function (element) { return _this.setElement(element[0], element[1]); });
return _this;
}
HashMap.prototype.reAllocate = function () {
var _this = this;
if (this.bucketNum >= HashContainer.maxBucketNum)
return;
var newHashTable = [];
var originalBucketNum = this.bucketNum;
this.bucketNum <<= 1;
var keys = Object.keys(this.hashTable);
var keyNums = keys.length;
var _loop_1 = function (i) {
var index = parseInt(keys[i]);
var container = this_1.hashTable[index];
var size = container.size();
if (size === 0)
return "continue";
if (size === 1) {
var element = container.front();
newHashTable[this_1.hashFunc(element[0]) & (this_1.bucketNum - 1)] = new Vector([element], false);
return "continue";
}
var lowList = [];
var highList = [];
container.forEach(function (element) {
var hashCode = _this.hashFunc(element[0]);
if ((hashCode & originalBucketNum) === 0) {
lowList.push(element);
}
else
highList.push(element);
});
if (container instanceof OrderedMap) {
if (lowList.length > HashContainer.untreeifyThreshold) {
newHashTable[index] = new OrderedMap(lowList);
}
else if (lowList.length) {
newHashTable[index] = new Vector(lowList, false);
}
if (highList.length > HashContainer.untreeifyThreshold) {
newHashTable[index + originalBucketNum] = new OrderedMap(highList);
}
else if (highList.length) {
newHashTable[index + originalBucketNum] = new Vector(highList, false);
}
}
else {
if (lowList.length >= HashContainer.treeifyThreshold) {
newHashTable[index] = new OrderedMap(lowList);
}
else if (lowList.length) {
newHashTable[index] = new Vector(lowList, false);
}
if (highList.length >= HashContainer.treeifyThreshold) {
newHashTable[index + originalBucketNum] = new OrderedMap(highList);
}
else if (highList.length) {
newHashTable[index + originalBucketNum] = new Vector(highList, false);
}
}
};
var this_1 = this;
for (var i = 0; i < keyNums; ++i) {
_loop_1(i);
}
this.hashTable = newHashTable;
};
HashMap.prototype.forEach = function (callback) {
var containers = Object.values(this.hashTable);
var containersNum = containers.length;
var index = 0;
for (var i = 0; i < containersNum; ++i) {
containers[i].forEach(function (element) { return callback(element, index++); });
}
};
/**
* @description Insert a new key-value pair to hash map or set value by key.
* @param key The key you want to insert.
* @param value The value you want to insert.
* @example HashMap.setElement(1, 2); // insert a key-value pair [1, 2]
*/
HashMap.prototype.setElement = function (key, value) {
var e_1, _a;
var index = this.hashFunc(key) & (this.bucketNum - 1);
var container = this.hashTable[index];
if (!container) {
this.length += 1;
this.hashTable[index] = new Vector([[key, value]], false);
}
else {
var preSize = container.size();
if (container instanceof Vector) {
try {
for (var container_1 = __values(container), container_1_1 = container_1.next(); !container_1_1.done; container_1_1 = container_1.next()) {
var pair = container_1_1.value;
if (pair[0] === key) {
pair[1] = value;
return;
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (container_1_1 && !container_1_1.done && (_a = container_1.return)) _a.call(container_1);
}
finally { if (e_1) throw e_1.error; }
}
container.pushBack([key, value]);
if (preSize + 1 >= HashMap.treeifyThreshold) {
if (this.bucketNum <= HashMap.minTreeifySize) {
this.length += 1;
this.reAllocate();
return;
}
this.hashTable[index] = new OrderedMap(this.hashTable[index]);
}
this.length += 1;
}
else {
container.setElement(key, value);
var curSize = container.size();
this.length += curSize - preSize;
}
}
if (this.length > this.bucketNum * HashMap.sigma) {
this.reAllocate();
}
};
/**
* @description Get the value of the element which has the specified key.
* @param key The key you want to get.
*/
HashMap.prototype.getElementByKey = function (key) {
var e_2, _a;
var index = this.hashFunc(key) & (this.bucketNum - 1);
var container = this.hashTable[index];
if (!container)
return undefined;
if (container instanceof OrderedMap) {
return container.getElementByKey(key);
}
else {
try {
for (var container_2 = __values(container), container_2_1 = container_2.next(); !container_2_1.done; container_2_1 = container_2.next()) {
var pair = container_2_1.value;
if (pair[0] === key)
return pair[1];
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (container_2_1 && !container_2_1.done && (_a = container_2.return)) _a.call(container_2);
}
finally { if (e_2) throw e_2.error; }
}
return undefined;
}
};
HashMap.prototype.eraseElementByKey = function (key) {
var e_3, _a;
var index = this.hashFunc(key) & (this.bucketNum - 1);
var container = this.hashTable[index];
if (!container)
return;
if (container instanceof Vector) {
var pos = 0;
try {
for (var container_3 = __values(container), container_3_1 = container_3.next(); !container_3_1.done; container_3_1 = container_3.next()) {
var pair = container_3_1.value;
if (pair[0] === key) {
container.eraseElementByPos(pos);
this.length -= 1;
return;
}
pos += 1;
}
}
catch (e_3_1) { e_3 = { error: e_3_1 }; }
finally {
try {
if (container_3_1 && !container_3_1.done && (_a = container_3.return)) _a.call(container_3);
}
finally { if (e_3) throw e_3.error; }
}
}
else {
var preSize = container.size();
container.eraseElementByKey(key);
var curSize = container.size();
this.length += curSize - preSize;
if (curSize <= HashContainer.untreeifyThreshold) {
this.hashTable[index] = new Vector(container);
}
}
};
HashMap.prototype.find = function (key) {
var e_4, _a;
var index = this.hashFunc(key) & (this.bucketNum - 1);
var container = this.hashTable[index];
if (!container)
return false;
if (container instanceof OrderedMap) {
return !container.find(key)
.equals(container.end());
}
try {
for (var container_4 = __values(container), container_4_1 = container_4.next(); !container_4_1.done; container_4_1 = container_4.next()) {
var pair = container_4_1.value;
if (pair[0] === key)
return true;
}
}
catch (e_4_1) { e_4 = { error: e_4_1 }; }
finally {
try {
if (container_4_1 && !container_4_1.done && (_a = container_4.return)) _a.call(container_4);
}
finally { if (e_4) throw e_4.error; }
}
return false;
};
HashMap.prototype[Symbol.iterator] = function () {
return function () {
var containers, containersNum, i, container, container_5, container_5_1, element, e_5_1;
var e_5, _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
containers = Object.values(this.hashTable);
containersNum = containers.length;
i = 0;
_b.label = 1;
case 1:
if (!(i < containersNum)) return [3 /*break*/, 10];
container = containers[i];
_b.label = 2;
case 2:
_b.trys.push([2, 7, 8, 9]);
container_5 = (e_5 = void 0, __values(container)), container_5_1 = container_5.next();
_b.label = 3;
case 3:
if (!!container_5_1.done) return [3 /*break*/, 6];
element = container_5_1.value;
return [4 /*yield*/, element];
case 4:
_b.sent();
_b.label = 5;
case 5:
container_5_1 = container_5.next();
return [3 /*break*/, 3];
case 6: return [3 /*break*/, 9];
case 7:
e_5_1 = _b.sent();
e_5 = { error: e_5_1 };
return [3 /*break*/, 9];
case 8:
try {
if (container_5_1 && !container_5_1.done && (_a = container_5.return)) _a.call(container_5);
}
finally { if (e_5) throw e_5.error; }
return [7 /*endfinally*/];
case 9:
++i;
return [3 /*break*/, 1];
case 10: return [2 /*return*/];
}
});
}.bind(this)();
};
return HashMap;
}(HashContainer));
export default HashMap;

View File

@@ -0,0 +1,19 @@
import HashContainer from './Base/index';
import Vector from '../SequentialContainer/Vector';
import OrderedSet from '../TreeContainer/OrderedSet';
import { initContainer } from "../ContainerBase/index";
declare class HashSet<K> extends HashContainer<K> {
protected hashTable: (Vector<K> | OrderedSet<K>)[];
constructor(container?: initContainer<K>, initBucketNum?: number, hashFunc?: (x: K) => number);
protected reAllocate(): void;
forEach(callback: (element: K, index: number) => void): void;
/**
* @description Insert element to hash set.
* @param element The element you want to insert.
*/
insert(element: K): void;
eraseElementByKey(key: K): void;
find(element: K): boolean;
[Symbol.iterator](): Generator<K, void, unknown>;
}
export default HashSet;

View File

@@ -0,0 +1,257 @@
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __values = (this && this.__values) || function(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
import HashContainer from './Base/index';
import Vector from '../SequentialContainer/Vector';
import OrderedSet from '../TreeContainer/OrderedSet';
var HashSet = /** @class */ (function (_super) {
__extends(HashSet, _super);
function HashSet(container, initBucketNum, hashFunc) {
if (container === void 0) { container = []; }
var _this = _super.call(this, initBucketNum, hashFunc) || this;
_this.hashTable = [];
container.forEach(function (element) { return _this.insert(element); });
return _this;
}
HashSet.prototype.reAllocate = function () {
var _this = this;
if (this.bucketNum >= HashContainer.maxBucketNum)
return;
var newHashTable = [];
var originalBucketNum = this.bucketNum;
this.bucketNum <<= 1;
var keys = Object.keys(this.hashTable);
var keyNums = keys.length;
var _loop_1 = function (i) {
var index = parseInt(keys[i]);
var container = this_1.hashTable[index];
var size = container.size();
if (size === 0)
return "continue";
if (size === 1) {
var element = container.front();
newHashTable[this_1.hashFunc(element) & (this_1.bucketNum - 1)] = new Vector([element], false);
return "continue";
}
var lowList = [];
var highList = [];
container.forEach(function (element) {
var hashCode = _this.hashFunc(element);
if ((hashCode & originalBucketNum) === 0) {
lowList.push(element);
}
else
highList.push(element);
});
if (container instanceof OrderedSet) {
if (lowList.length > HashContainer.untreeifyThreshold) {
newHashTable[index] = new OrderedSet(lowList);
}
else if (lowList.length) {
newHashTable[index] = new Vector(lowList, false);
}
if (highList.length > HashContainer.untreeifyThreshold) {
newHashTable[index + originalBucketNum] = new OrderedSet(highList);
}
else if (highList.length) {
newHashTable[index + originalBucketNum] = new Vector(highList, false);
}
}
else {
if (lowList.length >= HashContainer.treeifyThreshold) {
newHashTable[index] = new OrderedSet(lowList);
}
else if (lowList.length) {
newHashTable[index] = new Vector(lowList, false);
}
if (highList.length >= HashContainer.treeifyThreshold) {
newHashTable[index + originalBucketNum] = new OrderedSet(highList);
}
else if (highList.length) {
newHashTable[index + originalBucketNum] = new Vector(highList, false);
}
}
};
var this_1 = this;
for (var i = 0; i < keyNums; ++i) {
_loop_1(i);
}
this.hashTable = newHashTable;
};
HashSet.prototype.forEach = function (callback) {
var containers = Object.values(this.hashTable);
var containersNum = containers.length;
var index = 0;
for (var i = 0; i < containersNum; ++i) {
containers[i].forEach(function (element) { return callback(element, index++); });
}
};
/**
* @description Insert element to hash set.
* @param element The element you want to insert.
*/
HashSet.prototype.insert = function (element) {
var index = this.hashFunc(element) & (this.bucketNum - 1);
var container = this.hashTable[index];
if (!container) {
this.hashTable[index] = new Vector([element], false);
this.length += 1;
}
else {
var preSize = container.size();
if (container instanceof Vector) {
if (!container.find(element)
.equals(container.end()))
return;
container.pushBack(element);
if (preSize + 1 >= HashContainer.treeifyThreshold) {
if (this.bucketNum <= HashContainer.minTreeifySize) {
this.length += 1;
this.reAllocate();
return;
}
this.hashTable[index] = new OrderedSet(container);
}
this.length += 1;
}
else {
container.insert(element);
var curSize = container.size();
this.length += curSize - preSize;
}
}
if (this.length > this.bucketNum * HashContainer.sigma) {
this.reAllocate();
}
};
HashSet.prototype.eraseElementByKey = function (key) {
var index = this.hashFunc(key) & (this.bucketNum - 1);
var container = this.hashTable[index];
if (!container)
return;
var preSize = container.size();
if (preSize === 0)
return;
if (container instanceof Vector) {
container.eraseElementByValue(key);
var curSize = container.size();
this.length += curSize - preSize;
}
else {
container.eraseElementByKey(key);
var curSize = container.size();
this.length += curSize - preSize;
if (curSize <= HashContainer.untreeifyThreshold) {
this.hashTable[index] = new Vector(container);
}
}
};
HashSet.prototype.find = function (element) {
var index = this.hashFunc(element) & (this.bucketNum - 1);
var container = this.hashTable[index];
if (!container)
return false;
return !container.find(element)
.equals(container.end());
};
HashSet.prototype[Symbol.iterator] = function () {
return function () {
var containers, containersNum, i, container, container_1, container_1_1, element, e_1_1;
var e_1, _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
containers = Object.values(this.hashTable);
containersNum = containers.length;
i = 0;
_b.label = 1;
case 1:
if (!(i < containersNum)) return [3 /*break*/, 10];
container = containers[i];
_b.label = 2;
case 2:
_b.trys.push([2, 7, 8, 9]);
container_1 = (e_1 = void 0, __values(container)), container_1_1 = container_1.next();
_b.label = 3;
case 3:
if (!!container_1_1.done) return [3 /*break*/, 6];
element = container_1_1.value;
return [4 /*yield*/, element];
case 4:
_b.sent();
_b.label = 5;
case 5:
container_1_1 = container_1.next();
return [3 /*break*/, 3];
case 6: return [3 /*break*/, 9];
case 7:
e_1_1 = _b.sent();
e_1 = { error: e_1_1 };
return [3 /*break*/, 9];
case 8:
try {
if (container_1_1 && !container_1_1.done && (_a = container_1.return)) _a.call(container_1);
}
finally { if (e_1) throw e_1.error; }
return [7 /*endfinally*/];
case 9:
++i;
return [3 /*break*/, 1];
case 10: return [2 /*return*/];
}
});
}.bind(this)();
};
return HashSet;
}(HashContainer));
export default HashSet;

View File

@@ -0,0 +1,34 @@
import { Base, initContainer } from "../ContainerBase/index";
declare class PriorityQueue<T> extends Base {
private readonly priorityQueue;
private readonly cmp;
/**
* @description PriorityQueue's constructor.
* @param container Initialize container, must have a forEach function.
* @param cmp Compare function.
* @param copy When the container is an array, you can choose to directly operate on the original object of
* the array or perform a shallow copy. The default is shallow copy.
*/
constructor(container?: initContainer<T>, cmp?: (x: T, y: T) => number, copy?: boolean);
/**
* @description Adjusting parent's children to suit the nature of the heap.
* @param parent Parent's index.
* @private
*/
private adjust;
clear(): void;
/**
* @description Push element into a container in order.
* @param element The element you want to push.
*/
push(element: T): void;
/**
* @description Removes the top element.
*/
pop(): void;
/**
* @description Accesses the top element.
*/
top(): T | undefined;
}
export default PriorityQueue;

View File

@@ -0,0 +1,167 @@
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
import { Base } from "../ContainerBase/index";
var PriorityQueue = /** @class */ (function (_super) {
__extends(PriorityQueue, _super);
/**
* @description PriorityQueue's constructor.
* @param container Initialize container, must have a forEach function.
* @param cmp Compare function.
* @param copy When the container is an array, you can choose to directly operate on the original object of
* the array or perform a shallow copy. The default is shallow copy.
*/
function PriorityQueue(container, cmp, copy) {
var _a;
if (container === void 0) { container = []; }
if (cmp === void 0) { cmp = function (x, y) {
if (x > y)
return -1;
if (x < y)
return 1;
return 0;
}; }
if (copy === void 0) { copy = true; }
var _this = _super.call(this) || this;
_this.cmp = cmp;
if (Array.isArray(container)) {
_this.priorityQueue = copy ? __spreadArray([], __read(container), false) : container;
}
else {
_this.priorityQueue = [];
container.forEach(function (element) { return _this.priorityQueue.push(element); });
}
_this.length = _this.priorityQueue.length;
for (var parent_1 = (_this.length - 1) >> 1; parent_1 >= 0; --parent_1) {
var curParent = parent_1;
var curChild = (curParent << 1) | 1;
while (curChild < _this.length) {
var left = curChild;
var right = left + 1;
var minChild = left;
if (right < _this.length &&
_this.cmp(_this.priorityQueue[left], _this.priorityQueue[right]) > 0) {
minChild = right;
}
if (_this.cmp(_this.priorityQueue[curParent], _this.priorityQueue[minChild]) <= 0)
break;
_a = __read([_this.priorityQueue[minChild], _this.priorityQueue[curParent]], 2), _this.priorityQueue[curParent] = _a[0], _this.priorityQueue[minChild] = _a[1];
curParent = minChild;
curChild = (curParent << 1) | 1;
}
}
return _this;
}
/**
* @description Adjusting parent's children to suit the nature of the heap.
* @param parent Parent's index.
* @private
*/
PriorityQueue.prototype.adjust = function (parent) {
var _a, _b;
var left = (parent << 1) | 1;
var right = (parent << 1) + 2;
if (left < this.length &&
this.cmp(this.priorityQueue[parent], this.priorityQueue[left]) > 0) {
_a = __read([this.priorityQueue[left], this.priorityQueue[parent]], 2), this.priorityQueue[parent] = _a[0], this.priorityQueue[left] = _a[1];
}
if (right < this.length &&
this.cmp(this.priorityQueue[parent], this.priorityQueue[right]) > 0) {
_b = __read([this.priorityQueue[right], this.priorityQueue[parent]], 2), this.priorityQueue[parent] = _b[0], this.priorityQueue[right] = _b[1];
}
};
PriorityQueue.prototype.clear = function () {
this.length = 0;
this.priorityQueue.length = 0;
};
/**
* @description Push element into a container in order.
* @param element The element you want to push.
*/
PriorityQueue.prototype.push = function (element) {
this.priorityQueue.push(element);
this.length += 1;
if (this.length === 1)
return;
var curNode = this.length - 1;
while (curNode > 0) {
var parent_2 = (curNode - 1) >> 1;
if (this.cmp(this.priorityQueue[parent_2], element) <= 0)
break;
this.adjust(parent_2);
curNode = parent_2;
}
};
/**
* @description Removes the top element.
*/
PriorityQueue.prototype.pop = function () {
if (!this.length)
return;
var last = this.priorityQueue[this.length - 1];
this.length -= 1;
var parent = 0;
while (parent < this.length) {
var left = (parent << 1) | 1;
var right = (parent << 1) + 2;
if (left >= this.length)
break;
var minChild = left;
if (right < this.length &&
this.cmp(this.priorityQueue[left], this.priorityQueue[right]) > 0) {
minChild = right;
}
if (this.cmp(this.priorityQueue[minChild], last) >= 0)
break;
this.priorityQueue[parent] = this.priorityQueue[minChild];
parent = minChild;
}
this.priorityQueue[parent] = last;
this.priorityQueue.pop();
};
/**
* @description Accesses the top element.
*/
PriorityQueue.prototype.top = function () {
return this.priorityQueue[0];
};
return PriorityQueue;
}(Base));
export default PriorityQueue;

View File

@@ -0,0 +1,19 @@
import { Base, initContainer } from "../ContainerBase/index";
declare class Queue<T> extends Base {
private queue;
constructor(container?: initContainer<T>);
clear(): void;
/**
* @description Inserts element to queue's end.
*/
push(element: T): void;
/**
* @description Removes the first element.
*/
pop(): void;
/**
* @description Access the first element.
*/
front(): T | undefined;
}
export default Queue;

View File

@@ -0,0 +1,54 @@
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
import Deque from '../SequentialContainer/Deque';
import { Base } from "../ContainerBase/index";
var Queue = /** @class */ (function (_super) {
__extends(Queue, _super);
function Queue(container) {
if (container === void 0) { container = []; }
var _this = _super.call(this) || this;
_this.queue = new Deque(container);
_this.length = _this.queue.size();
return _this;
}
Queue.prototype.clear = function () {
this.queue.clear();
this.length = 0;
};
/**
* @description Inserts element to queue's end.
*/
Queue.prototype.push = function (element) {
this.queue.pushBack(element);
this.length += 1;
};
/**
* @description Removes the first element.
*/
Queue.prototype.pop = function () {
this.queue.popFront();
if (this.length)
this.length -= 1;
};
/**
* @description Access the first element.
*/
Queue.prototype.front = function () {
return this.queue.front();
};
return Queue;
}(Base));
export default Queue;

View File

@@ -0,0 +1,19 @@
import { Base, initContainer } from "../ContainerBase/index";
declare class Stack<T> extends Base {
private stack;
constructor(container?: initContainer<T>);
clear(): void;
/**
* @description Insert element to stack's end.
*/
push(element: T): void;
/**
* @description Removes the end element.
*/
pop(): void;
/**
* @description Accesses the end element.
*/
top(): T | undefined;
}
export default Stack;

View File

@@ -0,0 +1,53 @@
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
import { Base } from "../ContainerBase/index";
var Stack = /** @class */ (function (_super) {
__extends(Stack, _super);
function Stack(container) {
if (container === void 0) { container = []; }
var _this = _super.call(this) || this;
_this.stack = [];
container.forEach(function (element) { return _this.push(element); });
return _this;
}
Stack.prototype.clear = function () {
this.length = 0;
this.stack.length = 0;
};
/**
* @description Insert element to stack's end.
*/
Stack.prototype.push = function (element) {
this.stack.push(element);
this.length += 1;
};
/**
* @description Removes the end element.
*/
Stack.prototype.pop = function () {
this.stack.pop();
if (this.length > 0)
this.length -= 1;
};
/**
* @description Accesses the end element.
*/
Stack.prototype.top = function () {
return this.stack[this.length - 1];
};
return Stack;
}(Base));
export default Stack;

View File

@@ -0,0 +1,13 @@
import { ContainerIterator } from "../../ContainerBase/index";
export declare abstract class RandomIterator<T> extends ContainerIterator<T> {
protected node: number;
protected readonly size: () => number;
protected readonly getElementByPos: (pos: number) => T;
protected readonly setElementByPos: (pos: number, element: T) => void;
pre: () => this;
next: () => this;
constructor(index: number, size: () => number, getElementByPos: (pos: number) => T, setElementByPos: (pos: number, element: T) => void, iteratorType?: boolean);
get pointer(): T;
set pointer(newValue: T);
equals(obj: RandomIterator<T>): boolean;
}

View File

@@ -0,0 +1,77 @@
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
import { checkWithinAccessParams } from "../../../utils/checkParams";
import { ContainerIterator } from "../../ContainerBase/index";
var RandomIterator = /** @class */ (function (_super) {
__extends(RandomIterator, _super);
function RandomIterator(index, size, getElementByPos, setElementByPos, iteratorType) {
var _this = _super.call(this, iteratorType) || this;
_this.node = index;
_this.size = size;
_this.getElementByPos = getElementByPos;
_this.setElementByPos = setElementByPos;
if (_this.iteratorType === ContainerIterator.NORMAL) {
_this.pre = function () {
if (this.node === 0) {
throw new RangeError('Deque iterator access denied!');
}
this.node -= 1;
return this;
};
_this.next = function () {
if (this.node === this.size()) {
throw new RangeError('Deque Iterator access denied!');
}
this.node += 1;
return this;
};
}
else {
_this.pre = function () {
if (this.node === this.size() - 1) {
throw new RangeError('Deque iterator access denied!');
}
this.node += 1;
return this;
};
_this.next = function () {
if (this.node === -1) {
throw new RangeError('Deque iterator access denied!');
}
this.node -= 1;
return this;
};
}
return _this;
}
Object.defineProperty(RandomIterator.prototype, "pointer", {
get: function () {
checkWithinAccessParams(this.node, 0, this.size() - 1);
return this.getElementByPos(this.node);
},
set: function (newValue) {
checkWithinAccessParams(this.node, 0, this.size() - 1);
this.setElementByPos(this.node, newValue);
},
enumerable: false,
configurable: true
});
RandomIterator.prototype.equals = function (obj) {
return this.node === obj.node;
};
return RandomIterator;
}(ContainerIterator));
export { RandomIterator };

View File

@@ -0,0 +1,44 @@
import { Container } from "../../ContainerBase/index";
declare abstract class SequentialContainer<T> extends Container<T> {
/**
* @description Push the element to the back.
* @param element The element you want to push.
*/
abstract pushBack(element: T): void;
/**
* @description Removes the last element.
*/
abstract popBack(): void;
/**
* @description Sets element by position.
* @param pos The position you want to change.
* @param element The element's value you want to update.
*/
abstract setElementByPos(pos: number, element: T): void;
/**
* @description Removes the elements of the specified value.
* @param value The value you want to remove.
*/
abstract eraseElementByValue(value: T): void;
/**
* @description Insert several elements after the specified position.
* @param pos The position you want to insert.
* @param element The element you want to insert.
* @param num The number of elements you want to insert (default 1).
*/
abstract insert(pos: number, element: T, num?: number): void;
/**
* @description Reverses the container.
*/
abstract reverse(): void;
/**
* @description Removes the duplication of elements in the container.
*/
abstract unique(): void;
/**
* @description Sort the container.
* @param cmp Comparison function.
*/
abstract sort(cmp?: (x: T, y: T) => number): void;
}
export default SequentialContainer;

View File

@@ -0,0 +1,24 @@
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
import { Container } from "../../ContainerBase/index";
var SequentialContainer = /** @class */ (function (_super) {
__extends(SequentialContainer, _super);
function SequentialContainer() {
return _super !== null && _super.apply(this, arguments) || this;
}
return SequentialContainer;
}(Container));
export default SequentialContainer;

View File

@@ -0,0 +1,68 @@
import SequentialContainer from './Base/index';
import { initContainer } from "../ContainerBase/index";
import { RandomIterator } from "./Base/RandomIterator";
export declare class DequeIterator<T> extends RandomIterator<T> {
copy(): DequeIterator<T>;
}
declare class Deque<T> extends SequentialContainer<T> {
private first;
private curFirst;
private last;
private curLast;
private bucketNum;
private readonly bucketSize;
private map;
constructor(container?: initContainer<T>, bucketSize?: number);
/**
* @description Growth the Deque.
* @private
*/
private reAllocate;
/**
* @description Get the bucket position of the element and the pointer position by index.
* @param pos The element's index.
* @private
*/
private getElementIndex;
clear(): void;
front(): T | undefined;
back(): T | undefined;
begin(): DequeIterator<T>;
end(): DequeIterator<T>;
rBegin(): DequeIterator<T>;
rEnd(): DequeIterator<T>;
pushBack(element: T): void;
popBack(): void;
/**
* @description Push the element to the front.
* @param element The element you want to push.
*/
pushFront(element: T): void;
/**
* @description Remove the first element.
*/
popFront(): void;
forEach(callback: (element: T, index: number) => void): void;
getElementByPos(pos: number): T;
setElementByPos(pos: number, element: T): void;
insert(pos: number, element: T, num?: number): void;
/**
* @description Remove all elements after the specified position (excluding the specified position).
* @param pos The previous position of the first removed element.
* @example deque.cut(1); // Then deque's size will be 2. deque -> [0, 1]
*/
cut(pos: number): void;
eraseElementByPos(pos: number): void;
eraseElementByValue(value: T): void;
eraseElementByIterator(iter: DequeIterator<T>): DequeIterator<T>;
find(element: T): DequeIterator<T>;
reverse(): void;
unique(): void;
sort(cmp?: (x: T, y: T) => number): void;
/**
* @description Remove as much useless space as possible.
*/
shrinkToFit(): void;
[Symbol.iterator](): Generator<T, void, unknown>;
}
export default Deque;

View File

@@ -0,0 +1,450 @@
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
import SequentialContainer from './Base/index';
import { checkWithinAccessParams } from "../../utils/checkParams";
import { ContainerIterator } from "../ContainerBase/index";
import { RandomIterator } from "./Base/RandomIterator";
var DequeIterator = /** @class */ (function (_super) {
__extends(DequeIterator, _super);
function DequeIterator() {
return _super !== null && _super.apply(this, arguments) || this;
}
DequeIterator.prototype.copy = function () {
return new DequeIterator(this.node, this.size, this.getElementByPos, this.setElementByPos, this.iteratorType);
};
return DequeIterator;
}(RandomIterator));
export { DequeIterator };
var Deque = /** @class */ (function (_super) {
__extends(Deque, _super);
function Deque(container, bucketSize) {
if (container === void 0) { container = []; }
if (bucketSize === void 0) { bucketSize = (1 << 12); }
var _this = _super.call(this) || this;
_this.first = 0;
_this.curFirst = 0;
_this.last = 0;
_this.curLast = 0;
_this.bucketNum = 0;
_this.map = [];
var _length;
if ('size' in container) {
if (typeof container.size === 'number') {
_length = container.size;
}
else {
_length = container.size();
}
}
else if ('length' in container) {
_length = container.length;
}
else {
throw new RangeError('Can\'t get container\'s size!');
}
_this.bucketSize = bucketSize;
_this.bucketNum = Math.max(Math.ceil(_length / _this.bucketSize), 1);
for (var i = 0; i < _this.bucketNum; ++i) {
_this.map.push(new Array(_this.bucketSize));
}
var needBucketNum = Math.ceil(_length / _this.bucketSize);
_this.first = _this.last = (_this.bucketNum >> 1) - (needBucketNum >> 1);
_this.curFirst = _this.curLast = (_this.bucketSize - _length % _this.bucketSize) >> 1;
container.forEach(function (element) { return _this.pushBack(element); });
_this.size = _this.size.bind(_this);
_this.getElementByPos = _this.getElementByPos.bind(_this);
_this.setElementByPos = _this.setElementByPos.bind(_this);
return _this;
}
/**
* @description Growth the Deque.
* @private
*/
Deque.prototype.reAllocate = function () {
var newMap = [];
var addBucketNum = Math.max(this.bucketNum >> 1, 1);
for (var i = 0; i < addBucketNum; ++i) {
newMap[i] = new Array(this.bucketSize);
}
for (var i = this.first; i < this.bucketNum; ++i) {
newMap[newMap.length] = this.map[i];
}
for (var i = 0; i < this.last; ++i) {
newMap[newMap.length] = this.map[i];
}
newMap[newMap.length] = __spreadArray([], __read(this.map[this.last]), false);
this.first = addBucketNum;
this.last = newMap.length - 1;
for (var i = 0; i < addBucketNum; ++i) {
newMap[newMap.length] = new Array(this.bucketSize);
}
this.map = newMap;
this.bucketNum = newMap.length;
};
/**
* @description Get the bucket position of the element and the pointer position by index.
* @param pos The element's index.
* @private
*/
Deque.prototype.getElementIndex = function (pos) {
var offset = this.curFirst + pos + 1;
var offsetRemainder = offset % this.bucketSize;
var curNodePointerIndex = offsetRemainder - 1;
var curNodeBucketIndex = this.first + (offset - offsetRemainder) / this.bucketSize;
if (offsetRemainder === 0)
curNodeBucketIndex -= 1;
curNodeBucketIndex %= this.bucketNum;
if (curNodePointerIndex < 0)
curNodePointerIndex += this.bucketSize;
return { curNodeBucketIndex: curNodeBucketIndex, curNodePointerIndex: curNodePointerIndex };
};
Deque.prototype.clear = function () {
this.map = [[]];
this.bucketNum = 1;
this.first = this.last = this.length = 0;
this.curFirst = this.curLast = this.bucketSize >> 1;
};
Deque.prototype.front = function () {
return this.map[this.first][this.curFirst];
};
Deque.prototype.back = function () {
return this.map[this.last][this.curLast];
};
Deque.prototype.begin = function () {
return new DequeIterator(0, this.size, this.getElementByPos, this.setElementByPos);
};
Deque.prototype.end = function () {
return new DequeIterator(this.length, this.size, this.getElementByPos, this.setElementByPos);
};
Deque.prototype.rBegin = function () {
return new DequeIterator(this.length - 1, this.size, this.getElementByPos, this.setElementByPos, ContainerIterator.REVERSE);
};
Deque.prototype.rEnd = function () {
return new DequeIterator(-1, this.size, this.getElementByPos, this.setElementByPos, ContainerIterator.REVERSE);
};
Deque.prototype.pushBack = function (element) {
if (this.length) {
if (this.curLast < this.bucketSize - 1) {
this.curLast += 1;
}
else if (this.last < this.bucketNum - 1) {
this.last += 1;
this.curLast = 0;
}
else {
this.last = 0;
this.curLast = 0;
}
if (this.last === this.first &&
this.curLast === this.curFirst)
this.reAllocate();
}
this.length += 1;
this.map[this.last][this.curLast] = element;
};
Deque.prototype.popBack = function () {
if (!this.length)
return;
this.map[this.last][this.curLast] = undefined;
if (this.length !== 1) {
if (this.curLast > 0) {
this.curLast -= 1;
}
else if (this.last > 0) {
this.last -= 1;
this.curLast = this.bucketSize - 1;
}
else {
this.last = this.bucketNum - 1;
this.curLast = this.bucketSize - 1;
}
}
this.length -= 1;
};
/**
* @description Push the element to the front.
* @param element The element you want to push.
*/
Deque.prototype.pushFront = function (element) {
if (this.length) {
if (this.curFirst > 0) {
this.curFirst -= 1;
}
else if (this.first > 0) {
this.first -= 1;
this.curFirst = this.bucketSize - 1;
}
else {
this.first = this.bucketNum - 1;
this.curFirst = this.bucketSize - 1;
}
if (this.first === this.last &&
this.curFirst === this.curLast)
this.reAllocate();
}
this.length += 1;
this.map[this.first][this.curFirst] = element;
};
/**
* @description Remove the first element.
*/
Deque.prototype.popFront = function () {
if (!this.length)
return;
this.map[this.first][this.curFirst] = undefined;
if (this.length !== 1) {
if (this.curFirst < this.bucketSize - 1) {
this.curFirst += 1;
}
else if (this.first < this.bucketNum - 1) {
this.first += 1;
this.curFirst = 0;
}
else {
this.first = 0;
this.curFirst = 0;
}
}
this.length -= 1;
};
Deque.prototype.forEach = function (callback) {
for (var i = 0; i < this.length; ++i) {
callback(this.getElementByPos(i), i);
}
};
Deque.prototype.getElementByPos = function (pos) {
checkWithinAccessParams(pos, 0, this.length - 1);
var _a = this.getElementIndex(pos), curNodeBucketIndex = _a.curNodeBucketIndex, curNodePointerIndex = _a.curNodePointerIndex;
return this.map[curNodeBucketIndex][curNodePointerIndex];
};
Deque.prototype.setElementByPos = function (pos, element) {
checkWithinAccessParams(pos, 0, this.length - 1);
var _a = this.getElementIndex(pos), curNodeBucketIndex = _a.curNodeBucketIndex, curNodePointerIndex = _a.curNodePointerIndex;
this.map[curNodeBucketIndex][curNodePointerIndex] = element;
};
Deque.prototype.insert = function (pos, element, num) {
if (num === void 0) { num = 1; }
checkWithinAccessParams(pos, 0, this.length);
if (pos === 0) {
while (num--)
this.pushFront(element);
}
else if (pos === this.length) {
while (num--)
this.pushBack(element);
}
else {
var arr = [];
for (var i = pos; i < this.length; ++i) {
arr.push(this.getElementByPos(i));
}
this.cut(pos - 1);
for (var i = 0; i < num; ++i)
this.pushBack(element);
for (var i = 0; i < arr.length; ++i)
this.pushBack(arr[i]);
}
};
/**
* @description Remove all elements after the specified position (excluding the specified position).
* @param pos The previous position of the first removed element.
* @example deque.cut(1); // Then deque's size will be 2. deque -> [0, 1]
*/
Deque.prototype.cut = function (pos) {
if (pos < 0) {
this.clear();
return;
}
var _a = this.getElementIndex(pos), curNodeBucketIndex = _a.curNodeBucketIndex, curNodePointerIndex = _a.curNodePointerIndex;
this.last = curNodeBucketIndex;
this.curLast = curNodePointerIndex;
this.length = pos + 1;
};
Deque.prototype.eraseElementByPos = function (pos) {
var _this = this;
checkWithinAccessParams(pos, 0, this.length - 1);
if (pos === 0)
this.popFront();
else if (pos === this.length - 1)
this.popBack();
else {
var arr = [];
for (var i = pos + 1; i < this.length; ++i) {
arr.push(this.getElementByPos(i));
}
this.cut(pos);
this.popBack();
arr.forEach(function (element) { return _this.pushBack(element); });
}
};
Deque.prototype.eraseElementByValue = function (value) {
if (!this.length)
return;
var arr = [];
for (var i = 0; i < this.length; ++i) {
var element = this.getElementByPos(i);
if (element !== value)
arr.push(element);
}
var _length = arr.length;
for (var i = 0; i < _length; ++i)
this.setElementByPos(i, arr[i]);
this.cut(_length - 1);
};
Deque.prototype.eraseElementByIterator = function (iter) {
// @ts-ignore
var node = iter.node;
this.eraseElementByPos(node);
iter = iter.next();
return iter;
};
Deque.prototype.find = function (element) {
for (var i = 0; i < this.length; ++i) {
if (this.getElementByPos(i) === element) {
return new DequeIterator(i, this.size, this.getElementByPos, this.setElementByPos);
}
}
return this.end();
};
Deque.prototype.reverse = function () {
var l = 0;
var r = this.length - 1;
while (l < r) {
var tmp = this.getElementByPos(l);
this.setElementByPos(l, this.getElementByPos(r));
this.setElementByPos(r, tmp);
l += 1;
r -= 1;
}
};
Deque.prototype.unique = function () {
if (this.length <= 1)
return;
var index = 1;
var pre = this.getElementByPos(0);
for (var i = 1; i < this.length; ++i) {
var cur = this.getElementByPos(i);
if (cur !== pre) {
pre = cur;
this.setElementByPos(index++, cur);
}
}
while (this.length > index)
this.popBack();
};
Deque.prototype.sort = function (cmp) {
var arr = [];
for (var i = 0; i < this.length; ++i) {
arr.push(this.getElementByPos(i));
}
arr.sort(cmp);
for (var i = 0; i < this.length; ++i)
this.setElementByPos(i, arr[i]);
};
/**
* @description Remove as much useless space as possible.
*/
Deque.prototype.shrinkToFit = function () {
if (!this.length)
return;
var arr = [];
this.forEach(function (element) { return arr.push(element); });
this.bucketNum = Math.max(Math.ceil(this.length / this.bucketSize), 1);
this.length = this.first = this.last = this.curFirst = this.curLast = 0;
this.map = [];
for (var i = 0; i < this.bucketNum; ++i) {
this.map.push(new Array(this.bucketSize));
}
for (var i = 0; i < arr.length; ++i)
this.pushBack(arr[i]);
};
Deque.prototype[Symbol.iterator] = function () {
return function () {
var i;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
i = 0;
_a.label = 1;
case 1:
if (!(i < this.length)) return [3 /*break*/, 4];
return [4 /*yield*/, this.getElementByPos(i)];
case 2:
_a.sent();
_a.label = 3;
case 3:
++i;
return [3 /*break*/, 1];
case 4: return [2 /*return*/];
}
});
}.bind(this)();
};
return Deque;
}(SequentialContainer));
export default Deque;

View File

@@ -0,0 +1,61 @@
import SequentialContainer from './Base/index';
import { ContainerIterator, initContainer } from "../ContainerBase/index";
export declare class LinkNode<T> {
value: T | undefined;
pre: LinkNode<T> | undefined;
next: LinkNode<T> | undefined;
constructor(element?: T);
}
export declare class LinkListIterator<T> extends ContainerIterator<T> {
protected node: LinkNode<T>;
private readonly header;
pre: () => this;
next: () => this;
constructor(node: LinkNode<T>, header: LinkNode<T>, iteratorType?: boolean);
get pointer(): T;
set pointer(newValue: T);
equals(obj: LinkListIterator<T>): boolean;
copy(): LinkListIterator<T>;
}
declare class LinkList<T> extends SequentialContainer<T> {
private header;
private head;
private tail;
constructor(container?: initContainer<T>);
clear(): void;
begin(): LinkListIterator<T>;
end(): LinkListIterator<T>;
rBegin(): LinkListIterator<T>;
rEnd(): LinkListIterator<T>;
front(): T | undefined;
back(): T | undefined;
forEach(callback: (element: T, index: number) => void): void;
getElementByPos(pos: number): T;
eraseElementByPos(pos: number): void;
eraseElementByValue(value: T): void;
eraseElementByIterator(iter: LinkListIterator<T>): LinkListIterator<T>;
pushBack(element: T): void;
popBack(): void;
setElementByPos(pos: number, element: T): void;
insert(pos: number, element: T, num?: number): void;
find(element: T): LinkListIterator<T>;
reverse(): void;
unique(): void;
sort(cmp?: (x: T, y: T) => number): void;
/**
* @description Push an element to the front.
* @param element The element you want to push.
*/
pushFront(element: T): void;
/**
* @description Removes the first element.
*/
popFront(): void;
/**
* @description Merges two sorted lists.
* @param list The other list you want to merge (must be sorted).
*/
merge(list: LinkList<T>): void;
[Symbol.iterator](): Generator<T, void, unknown>;
}
export default LinkList;

View File

@@ -0,0 +1,458 @@
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
import SequentialContainer from './Base/index';
import { checkWithinAccessParams } from "../../utils/checkParams";
import { ContainerIterator } from "../ContainerBase/index";
var LinkNode = /** @class */ (function () {
function LinkNode(element) {
this.value = undefined;
this.pre = undefined;
this.next = undefined;
this.value = element;
}
return LinkNode;
}());
export { LinkNode };
var LinkListIterator = /** @class */ (function (_super) {
__extends(LinkListIterator, _super);
function LinkListIterator(node, header, iteratorType) {
var _this = _super.call(this, iteratorType) || this;
_this.node = node;
_this.header = header;
if (_this.iteratorType === ContainerIterator.NORMAL) {
_this.pre = function () {
if (this.node.pre === this.header) {
throw new RangeError('LinkList iterator access denied!');
}
this.node = this.node.pre;
return this;
};
_this.next = function () {
if (this.node === this.header) {
throw new RangeError('LinkList iterator access denied!');
}
this.node = this.node.next;
return this;
};
}
else {
_this.pre = function () {
if (this.node.next === this.header) {
throw new RangeError('LinkList iterator access denied!');
}
this.node = this.node.next;
return this;
};
_this.next = function () {
if (this.node === this.header) {
throw new RangeError('LinkList iterator access denied!');
}
this.node = this.node.pre;
return this;
};
}
return _this;
}
Object.defineProperty(LinkListIterator.prototype, "pointer", {
get: function () {
if (this.node === this.header) {
throw new RangeError('LinkList iterator access denied!');
}
return this.node.value;
},
set: function (newValue) {
if (this.node === this.header) {
throw new RangeError('LinkList iterator access denied!');
}
this.node.value = newValue;
},
enumerable: false,
configurable: true
});
LinkListIterator.prototype.equals = function (obj) {
return this.node === obj.node;
};
LinkListIterator.prototype.copy = function () {
return new LinkListIterator(this.node, this.header, this.iteratorType);
};
return LinkListIterator;
}(ContainerIterator));
export { LinkListIterator };
var LinkList = /** @class */ (function (_super) {
__extends(LinkList, _super);
function LinkList(container) {
if (container === void 0) { container = []; }
var _this = _super.call(this) || this;
_this.header = new LinkNode();
_this.head = undefined;
_this.tail = undefined;
container.forEach(function (element) { return _this.pushBack(element); });
return _this;
}
LinkList.prototype.clear = function () {
this.length = 0;
this.head = this.tail = undefined;
this.header.pre = this.header.next = undefined;
};
LinkList.prototype.begin = function () {
return new LinkListIterator(this.head || this.header, this.header);
};
LinkList.prototype.end = function () {
return new LinkListIterator(this.header, this.header);
};
LinkList.prototype.rBegin = function () {
return new LinkListIterator(this.tail || this.header, this.header, ContainerIterator.REVERSE);
};
LinkList.prototype.rEnd = function () {
return new LinkListIterator(this.header, this.header, ContainerIterator.REVERSE);
};
LinkList.prototype.front = function () {
return this.head ? this.head.value : undefined;
};
LinkList.prototype.back = function () {
return this.tail ? this.tail.value : undefined;
};
LinkList.prototype.forEach = function (callback) {
if (!this.length)
return;
var curNode = this.head;
var index = 0;
while (curNode !== this.header) {
callback(curNode.value, index++);
curNode = curNode.next;
}
};
LinkList.prototype.getElementByPos = function (pos) {
checkWithinAccessParams(pos, 0, this.length - 1);
var curNode = this.head;
while (pos--) {
curNode = curNode.next;
}
return curNode.value;
};
LinkList.prototype.eraseElementByPos = function (pos) {
checkWithinAccessParams(pos, 0, this.length - 1);
if (pos === 0)
this.popFront();
else if (pos === this.length - 1)
this.popBack();
else {
var curNode = this.head;
while (pos--) {
curNode = curNode.next;
}
curNode = curNode;
var pre = curNode.pre;
var next = curNode.next;
next.pre = pre;
pre.next = next;
this.length -= 1;
}
};
LinkList.prototype.eraseElementByValue = function (value) {
while (this.head && this.head.value === value)
this.popFront();
while (this.tail && this.tail.value === value)
this.popBack();
if (!this.head)
return;
var curNode = this.head;
while (curNode !== this.header) {
if (curNode.value === value) {
var pre = curNode.pre;
var next = curNode.next;
if (next)
next.pre = pre;
if (pre)
pre.next = next;
this.length -= 1;
}
curNode = curNode.next;
}
};
LinkList.prototype.eraseElementByIterator = function (iter) {
// @ts-ignore
var node = iter.node;
if (node === this.header) {
throw new RangeError('Invalid iterator');
}
iter = iter.next();
if (this.head === node)
this.popFront();
else if (this.tail === node)
this.popBack();
else {
var pre = node.pre;
var next = node.next;
if (next)
next.pre = pre;
if (pre)
pre.next = next;
this.length -= 1;
}
return iter;
};
LinkList.prototype.pushBack = function (element) {
this.length += 1;
var newTail = new LinkNode(element);
if (!this.tail) {
this.head = this.tail = newTail;
this.header.next = this.head;
this.head.pre = this.header;
}
else {
this.tail.next = newTail;
newTail.pre = this.tail;
this.tail = newTail;
}
this.tail.next = this.header;
this.header.pre = this.tail;
};
LinkList.prototype.popBack = function () {
if (!this.tail)
return;
this.length -= 1;
if (this.head === this.tail) {
this.head = this.tail = undefined;
this.header.next = undefined;
}
else {
this.tail = this.tail.pre;
if (this.tail)
this.tail.next = undefined;
}
this.header.pre = this.tail;
if (this.tail)
this.tail.next = this.header;
};
LinkList.prototype.setElementByPos = function (pos, element) {
checkWithinAccessParams(pos, 0, this.length - 1);
var curNode = this.head;
while (pos--) {
curNode = curNode.next;
}
curNode.value = element;
};
LinkList.prototype.insert = function (pos, element, num) {
if (num === void 0) { num = 1; }
checkWithinAccessParams(pos, 0, this.length);
if (num <= 0)
return;
if (pos === 0) {
while (num--)
this.pushFront(element);
}
else if (pos === this.length) {
while (num--)
this.pushBack(element);
}
else {
var curNode = this.head;
for (var i = 1; i < pos; ++i) {
curNode = curNode.next;
}
var next = curNode.next;
this.length += num;
while (num--) {
curNode.next = new LinkNode(element);
curNode.next.pre = curNode;
curNode = curNode.next;
}
curNode.next = next;
if (next)
next.pre = curNode;
}
};
LinkList.prototype.find = function (element) {
if (!this.head)
return this.end();
var curNode = this.head;
while (curNode !== this.header) {
if (curNode.value === element) {
return new LinkListIterator(curNode, this.header);
}
curNode = curNode.next;
}
return this.end();
};
LinkList.prototype.reverse = function () {
if (this.length <= 1)
return;
var pHead = this.head;
var pTail = this.tail;
var cnt = 0;
while ((cnt << 1) < this.length) {
var tmp = pHead.value;
pHead.value = pTail.value;
pTail.value = tmp;
pHead = pHead.next;
pTail = pTail.pre;
cnt += 1;
}
};
LinkList.prototype.unique = function () {
if (this.length <= 1)
return;
var curNode = this.head;
while (curNode !== this.header) {
var tmpNode = curNode;
while (tmpNode.next && tmpNode.value === tmpNode.next.value) {
tmpNode = tmpNode.next;
this.length -= 1;
}
curNode.next = tmpNode.next;
if (curNode.next)
curNode.next.pre = curNode;
curNode = curNode.next;
}
};
LinkList.prototype.sort = function (cmp) {
if (this.length <= 1)
return;
var arr = [];
this.forEach(function (element) { return arr.push(element); });
arr.sort(cmp);
var curNode = this.head;
arr.forEach(function (element) {
curNode.value = element;
curNode = curNode.next;
});
};
/**
* @description Push an element to the front.
* @param element The element you want to push.
*/
LinkList.prototype.pushFront = function (element) {
this.length += 1;
var newHead = new LinkNode(element);
if (!this.head) {
this.head = this.tail = newHead;
this.tail.next = this.header;
this.header.pre = this.tail;
}
else {
newHead.next = this.head;
this.head.pre = newHead;
this.head = newHead;
}
this.header.next = this.head;
this.head.pre = this.header;
};
/**
* @description Removes the first element.
*/
LinkList.prototype.popFront = function () {
if (!this.head)
return;
this.length -= 1;
if (this.head === this.tail) {
this.head = this.tail = undefined;
this.header.pre = this.tail;
}
else {
this.head = this.head.next;
if (this.head)
this.head.pre = this.header;
}
this.header.next = this.head;
};
/**
* @description Merges two sorted lists.
* @param list The other list you want to merge (must be sorted).
*/
LinkList.prototype.merge = function (list) {
var _this = this;
if (!this.head) {
list.forEach(function (element) { return _this.pushBack(element); });
return;
}
var curNode = this.head;
list.forEach(function (element) {
while (curNode &&
curNode !== _this.header &&
curNode.value <= element) {
curNode = curNode.next;
}
if (curNode === _this.header) {
_this.pushBack(element);
curNode = _this.tail;
}
else if (curNode === _this.head) {
_this.pushFront(element);
curNode = _this.head;
}
else {
_this.length += 1;
var pre = curNode.pre;
pre.next = new LinkNode(element);
pre.next.pre = pre;
pre.next.next = curNode;
curNode.pre = pre.next;
}
});
};
LinkList.prototype[Symbol.iterator] = function () {
return function () {
var curNode;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!this.head)
return [2 /*return*/];
curNode = this.head;
_a.label = 1;
case 1:
if (!(curNode !== this.header)) return [3 /*break*/, 3];
return [4 /*yield*/, curNode.value];
case 2:
_a.sent();
curNode = curNode.next;
return [3 /*break*/, 1];
case 3: return [2 /*return*/];
}
});
}.bind(this)();
};
return LinkList;
}(SequentialContainer));
export default LinkList;

View File

@@ -0,0 +1,38 @@
import SequentialContainer from './Base/index';
import { initContainer } from "../ContainerBase/index";
import { RandomIterator } from "./Base/RandomIterator";
export declare class VectorIterator<T> extends RandomIterator<T> {
copy(): VectorIterator<T>;
}
declare class Vector<T> extends SequentialContainer<T> {
private readonly vector;
/**
* @description Vector's constructor.
* @param container Initialize container, must have a forEach function.
* @param copy When the container is an array, you can choose to directly operate on the original object of
* the array or perform a shallow copy. The default is shallow copy.
*/
constructor(container?: initContainer<T>, copy?: boolean);
clear(): void;
begin(): VectorIterator<T>;
end(): VectorIterator<T>;
rBegin(): VectorIterator<T>;
rEnd(): VectorIterator<T>;
front(): T | undefined;
back(): T | undefined;
forEach(callback: (element: T, index: number) => void): void;
getElementByPos(pos: number): T;
eraseElementByPos(pos: number): void;
eraseElementByValue(value: T): void;
eraseElementByIterator(iter: VectorIterator<T>): VectorIterator<T>;
pushBack(element: T): void;
popBack(): void;
setElementByPos(pos: number, element: T): void;
insert(pos: number, element: T, num?: number): void;
find(element: T): VectorIterator<T>;
reverse(): void;
unique(): void;
sort(cmp?: (x: T, y: T) => number): void;
[Symbol.iterator](): Generator<T, any, undefined>;
}
export default Vector;

View File

@@ -0,0 +1,227 @@
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
var __values = (this && this.__values) || function(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
import SequentialContainer from './Base/index';
import { checkWithinAccessParams } from "../../utils/checkParams";
import { ContainerIterator } from "../ContainerBase/index";
import { RandomIterator } from "./Base/RandomIterator";
var VectorIterator = /** @class */ (function (_super) {
__extends(VectorIterator, _super);
function VectorIterator() {
return _super !== null && _super.apply(this, arguments) || this;
}
VectorIterator.prototype.copy = function () {
return new VectorIterator(this.node, this.size, this.getElementByPos, this.setElementByPos, this.iteratorType);
};
return VectorIterator;
}(RandomIterator));
export { VectorIterator };
var Vector = /** @class */ (function (_super) {
__extends(Vector, _super);
/**
* @description Vector's constructor.
* @param container Initialize container, must have a forEach function.
* @param copy When the container is an array, you can choose to directly operate on the original object of
* the array or perform a shallow copy. The default is shallow copy.
*/
function Vector(container, copy) {
if (container === void 0) { container = []; }
if (copy === void 0) { copy = true; }
var _this = _super.call(this) || this;
if (Array.isArray(container)) {
_this.vector = copy ? __spreadArray([], __read(container), false) : container;
_this.length = container.length;
}
else {
_this.vector = [];
container.forEach(function (element) { return _this.pushBack(element); });
}
_this.size = _this.size.bind(_this);
_this.getElementByPos = _this.getElementByPos.bind(_this);
_this.setElementByPos = _this.setElementByPos.bind(_this);
return _this;
}
Vector.prototype.clear = function () {
this.length = 0;
this.vector.length = 0;
};
Vector.prototype.begin = function () {
return new VectorIterator(0, this.size, this.getElementByPos, this.setElementByPos);
};
Vector.prototype.end = function () {
return new VectorIterator(this.length, this.size, this.getElementByPos, this.setElementByPos);
};
Vector.prototype.rBegin = function () {
return new VectorIterator(this.length - 1, this.size, this.getElementByPos, this.setElementByPos, ContainerIterator.REVERSE);
};
Vector.prototype.rEnd = function () {
return new VectorIterator(-1, this.size, this.getElementByPos, this.setElementByPos, ContainerIterator.REVERSE);
};
Vector.prototype.front = function () {
return this.vector[0];
};
Vector.prototype.back = function () {
return this.vector[this.length - 1];
};
Vector.prototype.forEach = function (callback) {
for (var i = 0; i < this.length; ++i) {
callback(this.vector[i], i);
}
};
Vector.prototype.getElementByPos = function (pos) {
checkWithinAccessParams(pos, 0, this.length - 1);
return this.vector[pos];
};
Vector.prototype.eraseElementByPos = function (pos) {
checkWithinAccessParams(pos, 0, this.length - 1);
this.vector.splice(pos, 1);
this.length -= 1;
};
Vector.prototype.eraseElementByValue = function (value) {
var index = 0;
for (var i = 0; i < this.length; ++i) {
if (this.vector[i] !== value) {
this.vector[index++] = this.vector[i];
}
}
this.length = this.vector.length = index;
};
Vector.prototype.eraseElementByIterator = function (iter) {
// @ts-ignore
var node = iter.node;
iter = iter.next();
this.eraseElementByPos(node);
return iter;
};
Vector.prototype.pushBack = function (element) {
this.vector.push(element);
this.length += 1;
};
Vector.prototype.popBack = function () {
if (!this.length)
return;
this.vector.pop();
this.length -= 1;
};
Vector.prototype.setElementByPos = function (pos, element) {
checkWithinAccessParams(pos, 0, this.length - 1);
this.vector[pos] = element;
};
Vector.prototype.insert = function (pos, element, num) {
var _a;
if (num === void 0) { num = 1; }
checkWithinAccessParams(pos, 0, this.length);
(_a = this.vector).splice.apply(_a, __spreadArray([pos, 0], __read(new Array(num).fill(element)), false));
this.length += num;
};
Vector.prototype.find = function (element) {
for (var i = 0; i < this.length; ++i) {
if (this.vector[i] === element) {
return new VectorIterator(i, this.size, this.getElementByPos, this.getElementByPos);
}
}
return this.end();
};
Vector.prototype.reverse = function () {
this.vector.reverse();
};
Vector.prototype.unique = function () {
var index = 1;
for (var i = 1; i < this.length; ++i) {
if (this.vector[i] !== this.vector[i - 1]) {
this.vector[index++] = this.vector[i];
}
}
this.length = this.vector.length = index;
};
Vector.prototype.sort = function (cmp) {
this.vector.sort(cmp);
};
Vector.prototype[Symbol.iterator] = function () {
return function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [5 /*yield**/, __values(this.vector)];
case 1: return [2 /*return*/, _a.sent()];
}
});
}.bind(this)();
};
return Vector;
}(SequentialContainer));
export default Vector;

View File

@@ -0,0 +1,11 @@
import TreeNode from './TreeNode';
import { ContainerIterator } from "../../ContainerBase/index";
declare abstract class TreeIterator<K, V> extends ContainerIterator<K | [K, V]> {
protected node: TreeNode<K, V>;
protected header: TreeNode<K, V>;
pre: () => this;
next: () => this;
constructor(node: TreeNode<K, V>, header: TreeNode<K, V>, iteratorType?: boolean);
equals(obj: TreeIterator<K, V>): boolean;
}
export default TreeIterator;

View File

@@ -0,0 +1,62 @@
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
import { ContainerIterator } from "../../ContainerBase/index";
var TreeIterator = /** @class */ (function (_super) {
__extends(TreeIterator, _super);
function TreeIterator(node, header, iteratorType) {
var _this = _super.call(this, iteratorType) || this;
_this.node = node;
_this.header = header;
if (_this.iteratorType === ContainerIterator.NORMAL) {
_this.pre = function () {
if (this.node === this.header.left) {
throw new RangeError('LinkList iterator access denied!');
}
this.node = this.node.pre();
return this;
};
_this.next = function () {
if (this.node === this.header) {
throw new RangeError('LinkList iterator access denied!');
}
this.node = this.node.next();
return this;
};
}
else {
_this.pre = function () {
if (this.node === this.header.right) {
throw new RangeError('LinkList iterator access denied!');
}
this.node = this.node.next();
return this;
};
_this.next = function () {
if (this.node === this.header) {
throw new RangeError('LinkList iterator access denied!');
}
this.node = this.node.pre();
return this;
};
}
return _this;
}
TreeIterator.prototype.equals = function (obj) {
return this.node === obj.node;
};
return TreeIterator;
}(ContainerIterator));
export default TreeIterator;

View File

@@ -0,0 +1,36 @@
declare class TreeNode<K, V> {
static readonly RED = true;
static readonly BLACK = false;
color: boolean;
key: K | undefined;
value: V | undefined;
left: TreeNode<K, V> | undefined;
right: TreeNode<K, V> | undefined;
parent: TreeNode<K, V> | undefined;
constructor(key?: K, value?: V);
/**
* @description Get the pre node.
* @return TreeNode about the pre node.
*/
pre(): TreeNode<K, V>;
/**
* @description Get the next node.
* @return TreeNode about the next node.
*/
next(): TreeNode<K, V>;
/**
* @description Rotate left.
* @return TreeNode about moved to original position after rotation.
*/
rotateLeft(): TreeNode<K, V>;
/**
* @description Rotate left.
* @return TreeNode about moved to original position after rotation.
*/
rotateRight(): TreeNode<K, V>;
/**
* @description Remove this.
*/
remove(): void;
}
export default TreeNode;

View File

@@ -0,0 +1,121 @@
var TreeNode = /** @class */ (function () {
function TreeNode(key, value) {
this.color = true;
this.key = undefined;
this.value = undefined;
this.left = undefined;
this.right = undefined;
this.parent = undefined;
this.key = key;
this.value = value;
}
/**
* @description Get the pre node.
* @return TreeNode about the pre node.
*/
TreeNode.prototype.pre = function () {
var preNode = this;
if (preNode.color === TreeNode.RED &&
preNode.parent.parent === preNode) {
preNode = preNode.right;
}
else if (preNode.left) {
preNode = preNode.left;
while (preNode.right) {
preNode = preNode.right;
}
}
else {
var pre = preNode.parent;
while (pre.left === preNode) {
preNode = pre;
pre = preNode.parent;
}
preNode = pre;
}
return preNode;
};
/**
* @description Get the next node.
* @return TreeNode about the next node.
*/
TreeNode.prototype.next = function () {
var nextNode = this;
if (nextNode.right) {
nextNode = nextNode.right;
while (nextNode.left) {
nextNode = nextNode.left;
}
}
else {
var pre = nextNode.parent;
while (pre.right === nextNode) {
nextNode = pre;
pre = nextNode.parent;
}
if (nextNode.right !== pre) {
nextNode = pre;
}
}
return nextNode;
};
/**
* @description Rotate left.
* @return TreeNode about moved to original position after rotation.
*/
TreeNode.prototype.rotateLeft = function () {
var PP = this.parent;
var V = this.right;
var R = V.left;
if (PP.parent === this)
PP.parent = V;
else if (PP.left === this)
PP.left = V;
else
PP.right = V;
V.parent = PP;
V.left = this;
this.parent = V;
this.right = R;
if (R)
R.parent = this;
return V;
};
/**
* @description Rotate left.
* @return TreeNode about moved to original position after rotation.
*/
TreeNode.prototype.rotateRight = function () {
var PP = this.parent;
var F = this.left;
var K = F.right;
if (PP.parent === this)
PP.parent = F;
else if (PP.left === this)
PP.left = F;
else
PP.right = F;
F.parent = PP;
F.right = this;
this.parent = F;
this.left = K;
if (K)
K.parent = this;
return F;
};
/**
* @description Remove this.
*/
TreeNode.prototype.remove = function () {
var parent = this.parent;
if (this === parent.left) {
parent.left = undefined;
}
else
parent.right = undefined;
};
TreeNode.RED = true;
TreeNode.BLACK = false;
return TreeNode;
}());
export default TreeNode;

View File

@@ -0,0 +1,127 @@
import TreeNode from './TreeNode';
import TreeIterator from './TreeIterator';
import { Container } from "../../ContainerBase/index";
declare abstract class TreeContainer<K, V> extends Container<K | [K, V]> {
protected root: TreeNode<K, V> | undefined;
protected header: TreeNode<K, V>;
protected cmp: (x: K, y: K) => number;
protected constructor(cmp?: (x: K, y: K) => number);
/**
* @param curNode The starting node of the search.
* @param key The key you want to search.
* @return TreeNode which key is greater than or equals to the given key.
* @protected
*/
protected _lowerBound(curNode: TreeNode<K, V> | undefined, key: K): TreeNode<K, V>;
/**
* @param key The given key you want to compare.
* @return An iterator to the first element not less than the given key.
*/
abstract lowerBound(key: K): TreeIterator<K, V>;
/**
* @param curNode The starting node of the search.
* @param key The key you want to search.
* @return TreeNode which key is greater than the given key.
* @protected
*/
protected _upperBound(curNode: TreeNode<K, V> | undefined, key: K): TreeNode<K, V>;
/**
* @param key The given key you want to compare.
* @return An iterator to the first element greater than the given key.
*/
abstract upperBound(key: K): TreeIterator<K, V>;
/**
* @param curNode The starting node of the search.
* @param key The key you want to search.
* @return TreeNode which key is less than or equals to the given key.
* @protected
*/
protected _reverseLowerBound(curNode: TreeNode<K, V> | undefined, key: K): TreeNode<K, V>;
/**
* @param key The given key you want to compare.
* @return An iterator to the first element not greater than the given key.
*/
abstract reverseLowerBound(key: K): TreeIterator<K, V>;
/**
* @param curNode The starting node of the search.
* @param key The key you want to search.
* @return TreeNode which key is less than the given key.
* @protected
*/
protected _reverseUpperBound(curNode: TreeNode<K, V> | undefined, key: K): TreeNode<K, V>;
/**
* @param key The given key you want to compare.
* @return An iterator to the first element less than the given key.
*/
abstract reverseUpperBound(key: K): TreeIterator<K, V>;
/**
* @description Union the other tree to self.
* <br/>
* Waiting for optimization, this is O(mlog(n+m)) algorithm now,
* but we expect it to be O(mlog(n/m+1)).<br/>
* More information =>
* https://en.wikipedia.org/wiki/Red_black_tree
* <br/>
* @param other The other tree container you want to merge.
*/
abstract union(other: TreeContainer<K, V>): void;
/**
* @description Make self balance after erase a node.
* @param curNode The node want to remove.
* @protected
*/
protected eraseNodeSelfBalance(curNode: TreeNode<K, V>): void;
/**
* @description Remove a node.
* @param curNode The node you want to remove.
* @protected
*/
protected eraseNode(curNode: TreeNode<K, V>): void;
/**
* @description InOrder traversal the tree.
* @protected
*/
protected inOrderTraversal: (curNode: TreeNode<K, V> | undefined, callback: (curNode: TreeNode<K, V>) => boolean) => boolean;
/**
* @description Make self balance after insert a node.
* @param curNode The node want to insert.
* @protected
*/
protected insertNodeSelfBalance(curNode: TreeNode<K, V>): void;
/**
* @description Find node which key is equals to the given key.
* @param curNode The starting node of the search.
* @param key The key you want to search.
* @protected
*/
protected findElementNode(curNode: TreeNode<K, V> | undefined, key: K): TreeNode<K, V> | undefined;
/**
* @description Insert a key-value pair or set value by the given key.
* @param key The key want to insert.
* @param value The value want to set.
* @param hint You can give an iterator hint to improve insertion efficiency.
* @protected
*/
protected set(key: K, value?: V, hint?: TreeIterator<K, V>): void;
clear(): void;
/**
* @description Update node's key by iterator.
* @param iter The iterator you want to change.
* @param key The key you want to update.
* @return Boolean about if the modification is successful.
*/
updateKeyByIterator(iter: TreeIterator<K, V>, key: K): boolean;
eraseElementByPos(pos: number): void;
/**
* @description Remove the element of the specified key.
* @param key The key you want to remove.
*/
eraseElementByKey(key: K): void;
eraseElementByIterator(iter: TreeIterator<K, V>): TreeIterator<K, V>;
/**
* @description Get the height of the tree.
* @return Number about the height of the RB-tree.
*/
getHeight(): number;
}
export default TreeContainer;

View File

@@ -0,0 +1,601 @@
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
import TreeNode from './TreeNode';
import { Container } from "../../ContainerBase/index";
import { checkWithinAccessParams } from "../../../utils/checkParams";
var TreeContainer = /** @class */ (function (_super) {
__extends(TreeContainer, _super);
function TreeContainer(cmp) {
if (cmp === void 0) { cmp = function (x, y) {
if (x < y)
return -1;
if (x > y)
return 1;
return 0;
}; }
var _this = _super.call(this) || this;
_this.root = undefined;
_this.header = new TreeNode();
/**
* @description InOrder traversal the tree.
* @protected
*/
_this.inOrderTraversal = function (curNode, callback) {
if (curNode === undefined)
return false;
var ifReturn = _this.inOrderTraversal(curNode.left, callback);
if (ifReturn)
return true;
if (callback(curNode))
return true;
return _this.inOrderTraversal(curNode.right, callback);
};
_this.cmp = cmp;
return _this;
}
/**
* @param curNode The starting node of the search.
* @param key The key you want to search.
* @return TreeNode which key is greater than or equals to the given key.
* @protected
*/
TreeContainer.prototype._lowerBound = function (curNode, key) {
var resNode;
while (curNode) {
var cmpResult = this.cmp(curNode.key, key);
if (cmpResult < 0) {
curNode = curNode.right;
}
else if (cmpResult > 0) {
resNode = curNode;
curNode = curNode.left;
}
else
return curNode;
}
return resNode === undefined ? this.header : resNode;
};
/**
* @param curNode The starting node of the search.
* @param key The key you want to search.
* @return TreeNode which key is greater than the given key.
* @protected
*/
TreeContainer.prototype._upperBound = function (curNode, key) {
var resNode;
while (curNode) {
var cmpResult = this.cmp(curNode.key, key);
if (cmpResult <= 0) {
curNode = curNode.right;
}
else if (cmpResult > 0) {
resNode = curNode;
curNode = curNode.left;
}
}
return resNode === undefined ? this.header : resNode;
};
/**
* @param curNode The starting node of the search.
* @param key The key you want to search.
* @return TreeNode which key is less than or equals to the given key.
* @protected
*/
TreeContainer.prototype._reverseLowerBound = function (curNode, key) {
var resNode;
while (curNode) {
var cmpResult = this.cmp(curNode.key, key);
if (cmpResult < 0) {
resNode = curNode;
curNode = curNode.right;
}
else if (cmpResult > 0) {
curNode = curNode.left;
}
else
return curNode;
}
return resNode === undefined ? this.header : resNode;
};
/**
* @param curNode The starting node of the search.
* @param key The key you want to search.
* @return TreeNode which key is less than the given key.
* @protected
*/
TreeContainer.prototype._reverseUpperBound = function (curNode, key) {
var resNode;
while (curNode) {
var cmpResult = this.cmp(curNode.key, key);
if (cmpResult < 0) {
resNode = curNode;
curNode = curNode.right;
}
else if (cmpResult >= 0) {
curNode = curNode.left;
}
}
return resNode === undefined ? this.header : resNode;
};
/**
* @description Make self balance after erase a node.
* @param curNode The node want to remove.
* @protected
*/
TreeContainer.prototype.eraseNodeSelfBalance = function (curNode) {
while (true) {
var parentNode = curNode.parent;
if (parentNode === this.header)
return;
if (curNode.color === TreeNode.RED) {
curNode.color = TreeNode.BLACK;
return;
}
if (curNode === parentNode.left) {
var brother = parentNode.right;
if (brother.color === TreeNode.RED) {
brother.color = TreeNode.BLACK;
parentNode.color = TreeNode.RED;
if (parentNode === this.root) {
this.root = parentNode.rotateLeft();
}
else
parentNode.rotateLeft();
}
else if (brother.color === TreeNode.BLACK) {
if (brother.right && brother.right.color === TreeNode.RED) {
brother.color = parentNode.color;
parentNode.color = TreeNode.BLACK;
brother.right.color = TreeNode.BLACK;
if (parentNode === this.root) {
this.root = parentNode.rotateLeft();
}
else
parentNode.rotateLeft();
return;
}
else if (brother.left && brother.left.color === TreeNode.RED) {
brother.color = TreeNode.RED;
brother.left.color = TreeNode.BLACK;
brother.rotateRight();
}
else {
brother.color = TreeNode.RED;
curNode = parentNode;
}
}
}
else {
var brother = parentNode.left;
if (brother.color === TreeNode.RED) {
brother.color = TreeNode.BLACK;
parentNode.color = TreeNode.RED;
if (parentNode === this.root) {
this.root = parentNode.rotateRight();
}
else
parentNode.rotateRight();
}
else {
if (brother.left && brother.left.color === TreeNode.RED) {
brother.color = parentNode.color;
parentNode.color = TreeNode.BLACK;
brother.left.color = TreeNode.BLACK;
if (parentNode === this.root) {
this.root = parentNode.rotateRight();
}
else
parentNode.rotateRight();
return;
}
else if (brother.right && brother.right.color === TreeNode.RED) {
brother.color = TreeNode.RED;
brother.right.color = TreeNode.BLACK;
brother.rotateLeft();
}
else {
brother.color = TreeNode.RED;
curNode = parentNode;
}
}
}
}
};
/**
* @description Remove a node.
* @param curNode The node you want to remove.
* @protected
*/
TreeContainer.prototype.eraseNode = function (curNode) {
var _a, _b;
if (this.length === 1) {
this.clear();
return;
}
var swapNode = curNode;
while (swapNode.left || swapNode.right) {
if (swapNode.right) {
swapNode = swapNode.right;
while (swapNode.left)
swapNode = swapNode.left;
}
else if (swapNode.left) {
swapNode = swapNode.left;
}
_a = __read([swapNode.key, curNode.key], 2), curNode.key = _a[0], swapNode.key = _a[1];
_b = __read([swapNode.value, curNode.value], 2), curNode.value = _b[0], swapNode.value = _b[1];
curNode = swapNode;
}
if (this.header.left === swapNode) {
this.header.left = swapNode.parent;
}
else if (this.header.right === swapNode) {
this.header.right = swapNode.parent;
}
this.eraseNodeSelfBalance(swapNode);
swapNode.remove();
this.length -= 1;
this.root.color = TreeNode.BLACK;
};
/**
* @description Make self balance after insert a node.
* @param curNode The node want to insert.
* @protected
*/
TreeContainer.prototype.insertNodeSelfBalance = function (curNode) {
while (true) {
var parentNode = curNode.parent;
if (parentNode.color === TreeNode.BLACK)
return;
var grandParent = parentNode.parent;
if (parentNode === grandParent.left) {
var uncle = grandParent.right;
if (uncle && uncle.color === TreeNode.RED) {
uncle.color = parentNode.color = TreeNode.BLACK;
if (grandParent === this.root)
return;
grandParent.color = TreeNode.RED;
curNode = grandParent;
continue;
}
else if (curNode === parentNode.right) {
curNode.color = TreeNode.BLACK;
if (curNode.left)
curNode.left.parent = parentNode;
if (curNode.right)
curNode.right.parent = grandParent;
parentNode.right = curNode.left;
grandParent.left = curNode.right;
curNode.left = parentNode;
curNode.right = grandParent;
if (grandParent === this.root) {
this.root = curNode;
this.header.parent = curNode;
}
else {
var GP = grandParent.parent;
if (GP.left === grandParent) {
GP.left = curNode;
}
else
GP.right = curNode;
}
curNode.parent = grandParent.parent;
parentNode.parent = curNode;
grandParent.parent = curNode;
}
else {
parentNode.color = TreeNode.BLACK;
if (grandParent === this.root) {
this.root = grandParent.rotateRight();
}
else
grandParent.rotateRight();
}
grandParent.color = TreeNode.RED;
}
else {
var uncle = grandParent.left;
if (uncle && uncle.color === TreeNode.RED) {
uncle.color = parentNode.color = TreeNode.BLACK;
if (grandParent === this.root)
return;
grandParent.color = TreeNode.RED;
curNode = grandParent;
continue;
}
else if (curNode === parentNode.left) {
curNode.color = TreeNode.BLACK;
if (curNode.left)
curNode.left.parent = grandParent;
if (curNode.right)
curNode.right.parent = parentNode;
grandParent.right = curNode.left;
parentNode.left = curNode.right;
curNode.left = grandParent;
curNode.right = parentNode;
if (grandParent === this.root) {
this.root = curNode;
this.header.parent = curNode;
}
else {
var GP = grandParent.parent;
if (GP.left === grandParent) {
GP.left = curNode;
}
else
GP.right = curNode;
}
curNode.parent = grandParent.parent;
parentNode.parent = curNode;
grandParent.parent = curNode;
}
else {
parentNode.color = TreeNode.BLACK;
if (grandParent === this.root) {
this.root = grandParent.rotateLeft();
}
else
grandParent.rotateLeft();
}
grandParent.color = TreeNode.RED;
}
return;
}
};
/**
* @description Find node which key is equals to the given key.
* @param curNode The starting node of the search.
* @param key The key you want to search.
* @protected
*/
TreeContainer.prototype.findElementNode = function (curNode, key) {
while (curNode) {
var cmpResult = this.cmp(curNode.key, key);
if (cmpResult < 0) {
curNode = curNode.right;
}
else if (cmpResult > 0) {
curNode = curNode.left;
}
else
return curNode;
}
return curNode;
};
/**
* @description Insert a key-value pair or set value by the given key.
* @param key The key want to insert.
* @param value The value want to set.
* @param hint You can give an iterator hint to improve insertion efficiency.
* @protected
*/
TreeContainer.prototype.set = function (key, value, hint) {
if (this.root === undefined) {
this.length += 1;
this.root = new TreeNode(key, value);
this.root.color = TreeNode.BLACK;
this.root.parent = this.header;
this.header.parent = this.root;
this.header.left = this.root;
this.header.right = this.root;
return;
}
var curNode;
var minNode = this.header.left;
var compareToMin = this.cmp(minNode.key, key);
if (compareToMin === 0) {
minNode.value = value;
return;
}
else if (compareToMin > 0) {
minNode.left = new TreeNode(key, value);
minNode.left.parent = minNode;
curNode = minNode.left;
this.header.left = curNode;
}
else {
var maxNode = this.header.right;
var compareToMax = this.cmp(maxNode.key, key);
if (compareToMax === 0) {
maxNode.value = value;
return;
}
else if (compareToMax < 0) {
maxNode.right = new TreeNode(key, value);
maxNode.right.parent = maxNode;
curNode = maxNode.right;
this.header.right = curNode;
}
else {
if (hint !== undefined) {
// @ts-ignore
var iterNode = hint.node;
if (iterNode !== this.header) {
var iterCmpRes = this.cmp(iterNode.key, key);
if (iterCmpRes === 0) {
iterNode.value = value;
return;
}
else if (iterCmpRes > 0) {
var preNode = iterNode.pre();
var preCmpRes = this.cmp(preNode.key, key);
if (preCmpRes === 0) {
preNode.value = value;
return;
}
else if (preCmpRes < 0) {
curNode = new TreeNode(key, value);
if (preNode.right === undefined) {
preNode.right = curNode;
curNode.parent = preNode;
}
else {
iterNode.left = curNode;
curNode.parent = iterNode;
}
}
}
}
}
if (curNode === undefined) {
curNode = this.root;
while (true) {
var cmpResult = this.cmp(curNode.key, key);
if (cmpResult > 0) {
if (curNode.left === undefined) {
curNode.left = new TreeNode(key, value);
curNode.left.parent = curNode;
curNode = curNode.left;
break;
}
curNode = curNode.left;
}
else if (cmpResult < 0) {
if (curNode.right === undefined) {
curNode.right = new TreeNode(key, value);
curNode.right.parent = curNode;
curNode = curNode.right;
break;
}
curNode = curNode.right;
}
else {
curNode.value = value;
return;
}
}
}
}
}
this.length += 1;
this.insertNodeSelfBalance(curNode);
};
TreeContainer.prototype.clear = function () {
this.length = 0;
this.root = undefined;
this.header.parent = undefined;
this.header.left = this.header.right = undefined;
};
/**
* @description Update node's key by iterator.
* @param iter The iterator you want to change.
* @param key The key you want to update.
* @return Boolean about if the modification is successful.
*/
TreeContainer.prototype.updateKeyByIterator = function (iter, key) {
// @ts-ignore
var node = iter.node;
if (node === this.header) {
throw new TypeError('Invalid iterator!');
}
if (this.length === 1) {
node.key = key;
return true;
}
if (node === this.header.left) {
if (this.cmp(node.next().key, key) > 0) {
node.key = key;
return true;
}
return false;
}
if (node === this.header.right) {
if (this.cmp(node.pre().key, key) < 0) {
node.key = key;
return true;
}
return false;
}
var preKey = node.pre().key;
if (this.cmp(preKey, key) >= 0)
return false;
var nextKey = node.next().key;
if (this.cmp(nextKey, key) <= 0)
return false;
node.key = key;
return true;
};
TreeContainer.prototype.eraseElementByPos = function (pos) {
var _this = this;
checkWithinAccessParams(pos, 0, this.length - 1);
var index = 0;
this.inOrderTraversal(this.root, function (curNode) {
if (pos === index) {
_this.eraseNode(curNode);
return true;
}
index += 1;
return false;
});
};
/**
* @description Remove the element of the specified key.
* @param key The key you want to remove.
*/
TreeContainer.prototype.eraseElementByKey = function (key) {
if (!this.length)
return;
var curNode = this.findElementNode(this.root, key);
if (curNode === undefined)
return;
this.eraseNode(curNode);
};
TreeContainer.prototype.eraseElementByIterator = function (iter) {
// @ts-ignore
var node = iter.node;
if (node === this.header) {
throw new RangeError('Invalid iterator');
}
if (node.right === undefined) {
iter = iter.next();
}
this.eraseNode(node);
return iter;
};
/**
* @description Get the height of the tree.
* @return Number about the height of the RB-tree.
*/
TreeContainer.prototype.getHeight = function () {
if (!this.length)
return 0;
var traversal = function (curNode) {
if (!curNode)
return 0;
return Math.max(traversal(curNode.left), traversal(curNode.right)) + 1;
};
return traversal(this.root);
};
return TreeContainer;
}(Container));
export default TreeContainer;

View File

@@ -0,0 +1,38 @@
import { initContainer } from "../ContainerBase/index";
import TreeContainer from './Base/index';
import TreeIterator from './Base/TreeIterator';
export declare class OrderedMapIterator<K, V> extends TreeIterator<K, V> {
get pointer(): [K, V];
copy(): OrderedMapIterator<K, V>;
}
declare class OrderedMap<K, V> extends TreeContainer<K, V> {
constructor(container?: initContainer<[K, V]>, cmp?: (x: K, y: K) => number);
private readonly iterationFunc;
begin(): OrderedMapIterator<K, V>;
end(): OrderedMapIterator<K, V>;
rBegin(): OrderedMapIterator<K, V>;
rEnd(): OrderedMapIterator<K, V>;
front(): [K, V] | undefined;
back(): [K, V] | undefined;
forEach(callback: (element: [K, V], index: number) => void): void;
lowerBound(key: K): OrderedMapIterator<K, V>;
upperBound(key: K): OrderedMapIterator<K, V>;
reverseLowerBound(key: K): OrderedMapIterator<K, V>;
reverseUpperBound(key: K): OrderedMapIterator<K, V>;
/**
* @description Insert a key-value pair or set value by the given key.
* @param key The key want to insert.
* @param value The value want to set.
* @param hint You can give an iterator hint to improve insertion efficiency.
*/
setElement(key: K, value: V, hint?: OrderedMapIterator<K, V>): void;
find(key: K): OrderedMapIterator<K, V>;
/**
* @description Get the value of the element of the specified key.
*/
getElementByKey(key: K): V | undefined;
getElementByPos(pos: number): [K, V];
union(other: OrderedMap<K, V>): void;
[Symbol.iterator](): Generator<[K, V], void, undefined>;
}
export default OrderedMap;

View File

@@ -0,0 +1,257 @@
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __values = (this && this.__values) || function(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
import { ContainerIterator } from "../ContainerBase/index";
import { checkWithinAccessParams } from "../../utils/checkParams";
import TreeContainer from './Base/index';
import TreeIterator from './Base/TreeIterator';
var OrderedMapIterator = /** @class */ (function (_super) {
__extends(OrderedMapIterator, _super);
function OrderedMapIterator() {
return _super !== null && _super.apply(this, arguments) || this;
}
Object.defineProperty(OrderedMapIterator.prototype, "pointer", {
get: function () {
var _this = this;
if (this.node === this.header) {
throw new RangeError('OrderedMap iterator access denied');
}
return new Proxy([], {
get: function (_, props) {
if (props === '0')
return _this.node.key;
else if (props === '1')
return _this.node.value;
},
set: function (_, props, newValue) {
if (props !== '1') {
throw new TypeError('props must be 1');
}
_this.node.value = newValue;
return true;
}
});
},
enumerable: false,
configurable: true
});
OrderedMapIterator.prototype.copy = function () {
return new OrderedMapIterator(this.node, this.header, this.iteratorType);
};
return OrderedMapIterator;
}(TreeIterator));
export { OrderedMapIterator };
var OrderedMap = /** @class */ (function (_super) {
__extends(OrderedMap, _super);
function OrderedMap(container, cmp) {
if (container === void 0) { container = []; }
var _this = _super.call(this, cmp) || this;
_this.iterationFunc = function (curNode) {
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (curNode === undefined)
return [2 /*return*/];
return [5 /*yield**/, __values(this.iterationFunc(curNode.left))];
case 1:
_a.sent();
return [4 /*yield*/, [curNode.key, curNode.value]];
case 2:
_a.sent();
return [5 /*yield**/, __values(this.iterationFunc(curNode.right))];
case 3:
_a.sent();
return [2 /*return*/];
}
});
};
_this.iterationFunc = _this.iterationFunc.bind(_this);
container.forEach(function (_a) {
var _b = __read(_a, 2), key = _b[0], value = _b[1];
return _this.setElement(key, value);
});
return _this;
}
OrderedMap.prototype.begin = function () {
return new OrderedMapIterator(this.header.left || this.header, this.header);
};
OrderedMap.prototype.end = function () {
return new OrderedMapIterator(this.header, this.header);
};
OrderedMap.prototype.rBegin = function () {
return new OrderedMapIterator(this.header.right || this.header, this.header, ContainerIterator.REVERSE);
};
OrderedMap.prototype.rEnd = function () {
return new OrderedMapIterator(this.header, this.header, ContainerIterator.REVERSE);
};
OrderedMap.prototype.front = function () {
if (!this.length)
return undefined;
var minNode = this.header.left;
return [minNode.key, minNode.value];
};
OrderedMap.prototype.back = function () {
if (!this.length)
return undefined;
var maxNode = this.header.right;
return [maxNode.key, maxNode.value];
};
OrderedMap.prototype.forEach = function (callback) {
var e_1, _a;
var index = 0;
try {
for (var _b = __values(this), _c = _b.next(); !_c.done; _c = _b.next()) {
var pair = _c.value;
callback(pair, index++);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_1) throw e_1.error; }
}
};
OrderedMap.prototype.lowerBound = function (key) {
var resNode = this._lowerBound(this.root, key);
return new OrderedMapIterator(resNode, this.header);
};
OrderedMap.prototype.upperBound = function (key) {
var resNode = this._upperBound(this.root, key);
return new OrderedMapIterator(resNode, this.header);
};
OrderedMap.prototype.reverseLowerBound = function (key) {
var resNode = this._reverseLowerBound(this.root, key);
return new OrderedMapIterator(resNode, this.header);
};
OrderedMap.prototype.reverseUpperBound = function (key) {
var resNode = this._reverseUpperBound(this.root, key);
return new OrderedMapIterator(resNode, this.header);
};
/**
* @description Insert a key-value pair or set value by the given key.
* @param key The key want to insert.
* @param value The value want to set.
* @param hint You can give an iterator hint to improve insertion efficiency.
*/
OrderedMap.prototype.setElement = function (key, value, hint) {
this.set(key, value, hint);
};
OrderedMap.prototype.find = function (key) {
var curNode = this.findElementNode(this.root, key);
if (curNode !== undefined) {
return new OrderedMapIterator(curNode, this.header);
}
return this.end();
};
/**
* @description Get the value of the element of the specified key.
*/
OrderedMap.prototype.getElementByKey = function (key) {
var curNode = this.findElementNode(this.root, key);
return curNode ? curNode.value : undefined;
};
OrderedMap.prototype.getElementByPos = function (pos) {
var e_2, _a;
checkWithinAccessParams(pos, 0, this.length - 1);
var res;
var index = 0;
try {
for (var _b = __values(this), _c = _b.next(); !_c.done; _c = _b.next()) {
var pair = _c.value;
if (index === pos) {
res = pair;
break;
}
index += 1;
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_2) throw e_2.error; }
}
return res;
};
OrderedMap.prototype.union = function (other) {
var _this = this;
other.forEach(function (_a) {
var _b = __read(_a, 2), key = _b[0], value = _b[1];
return _this.setElement(key, value);
});
};
OrderedMap.prototype[Symbol.iterator] = function () {
return this.iterationFunc(this.root);
};
return OrderedMap;
}(TreeContainer));
export default OrderedMap;

View File

@@ -0,0 +1,33 @@
import TreeContainer from './Base/index';
import { initContainer } from "../ContainerBase/index";
import TreeIterator from './Base/TreeIterator';
export declare class OrderedSetIterator<K> extends TreeIterator<K, undefined> {
get pointer(): K;
copy(): OrderedSetIterator<K>;
}
declare class OrderedSet<K> extends TreeContainer<K, undefined> {
constructor(container?: initContainer<K>, cmp?: (x: K, y: K) => number);
private readonly iterationFunc;
begin(): OrderedSetIterator<K>;
end(): OrderedSetIterator<K>;
rBegin(): OrderedSetIterator<K>;
rEnd(): OrderedSetIterator<K>;
front(): K | undefined;
back(): K | undefined;
forEach(callback: (element: K, index: number) => void): void;
getElementByPos(pos: number): K;
/**
* @description Insert element to set.
* @param key The key want to insert.
* @param hint You can give an iterator hint to improve insertion efficiency.
*/
insert(key: K, hint?: OrderedSetIterator<K>): void;
find(element: K): OrderedSetIterator<K>;
lowerBound(key: K): OrderedSetIterator<K>;
upperBound(key: K): OrderedSetIterator<K>;
reverseLowerBound(key: K): OrderedSetIterator<K>;
reverseUpperBound(key: K): OrderedSetIterator<K>;
union(other: OrderedSet<K>): void;
[Symbol.iterator](): Generator<K, void, undefined>;
}
export default OrderedSet;

View File

@@ -0,0 +1,205 @@
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __values = (this && this.__values) || function(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
import TreeContainer from './Base/index';
import { ContainerIterator } from "../ContainerBase/index";
import { checkWithinAccessParams } from "../../utils/checkParams";
import TreeIterator from './Base/TreeIterator';
var OrderedSetIterator = /** @class */ (function (_super) {
__extends(OrderedSetIterator, _super);
function OrderedSetIterator() {
return _super !== null && _super.apply(this, arguments) || this;
}
Object.defineProperty(OrderedSetIterator.prototype, "pointer", {
get: function () {
if (this.node === this.header) {
throw new RangeError('OrderedSet iterator access denied!');
}
return this.node.key;
},
enumerable: false,
configurable: true
});
OrderedSetIterator.prototype.copy = function () {
return new OrderedSetIterator(this.node, this.header, this.iteratorType);
};
return OrderedSetIterator;
}(TreeIterator));
export { OrderedSetIterator };
var OrderedSet = /** @class */ (function (_super) {
__extends(OrderedSet, _super);
function OrderedSet(container, cmp) {
if (container === void 0) { container = []; }
var _this = _super.call(this, cmp) || this;
_this.iterationFunc = function (curNode) {
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (curNode === undefined)
return [2 /*return*/];
return [5 /*yield**/, __values(this.iterationFunc(curNode.left))];
case 1:
_a.sent();
return [4 /*yield*/, curNode.key];
case 2:
_a.sent();
return [5 /*yield**/, __values(this.iterationFunc(curNode.right))];
case 3:
_a.sent();
return [2 /*return*/];
}
});
};
container.forEach(function (element) { return _this.insert(element); });
_this.iterationFunc = _this.iterationFunc.bind(_this);
return _this;
}
OrderedSet.prototype.begin = function () {
return new OrderedSetIterator(this.header.left || this.header, this.header);
};
OrderedSet.prototype.end = function () {
return new OrderedSetIterator(this.header, this.header);
};
OrderedSet.prototype.rBegin = function () {
return new OrderedSetIterator(this.header.right || this.header, this.header, ContainerIterator.REVERSE);
};
OrderedSet.prototype.rEnd = function () {
return new OrderedSetIterator(this.header, this.header, ContainerIterator.REVERSE);
};
OrderedSet.prototype.front = function () {
return this.header.left ? this.header.left.key : undefined;
};
OrderedSet.prototype.back = function () {
return this.header.right ? this.header.right.key : undefined;
};
OrderedSet.prototype.forEach = function (callback) {
var e_1, _a;
var index = 0;
try {
for (var _b = __values(this), _c = _b.next(); !_c.done; _c = _b.next()) {
var element = _c.value;
callback(element, index++);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_1) throw e_1.error; }
}
};
OrderedSet.prototype.getElementByPos = function (pos) {
var e_2, _a;
checkWithinAccessParams(pos, 0, this.length - 1);
var res;
var index = 0;
try {
for (var _b = __values(this), _c = _b.next(); !_c.done; _c = _b.next()) {
var element = _c.value;
if (index === pos) {
res = element;
}
index += 1;
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_2) throw e_2.error; }
}
return res;
};
/**
* @description Insert element to set.
* @param key The key want to insert.
* @param hint You can give an iterator hint to improve insertion efficiency.
*/
OrderedSet.prototype.insert = function (key, hint) {
this.set(key, undefined, hint);
};
OrderedSet.prototype.find = function (element) {
var curNode = this.findElementNode(this.root, element);
if (curNode !== undefined) {
return new OrderedSetIterator(curNode, this.header);
}
return this.end();
};
OrderedSet.prototype.lowerBound = function (key) {
var resNode = this._lowerBound(this.root, key);
return new OrderedSetIterator(resNode, this.header);
};
OrderedSet.prototype.upperBound = function (key) {
var resNode = this._upperBound(this.root, key);
return new OrderedSetIterator(resNode, this.header);
};
OrderedSet.prototype.reverseLowerBound = function (key) {
var resNode = this._reverseLowerBound(this.root, key);
return new OrderedSetIterator(resNode, this.header);
};
OrderedSet.prototype.reverseUpperBound = function (key) {
var resNode = this._reverseUpperBound(this.root, key);
return new OrderedSetIterator(resNode, this.header);
};
OrderedSet.prototype.union = function (other) {
var _this = this;
other.forEach(function (element) { return _this.insert(element); });
};
OrderedSet.prototype[Symbol.iterator] = function () {
return this.iterationFunc(this.root);
};
return OrderedSet;
}(TreeContainer));
export default OrderedSet;

14
WebUI/node_modules/js-sdsl/dist/esm/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,14 @@
export { default as Stack } from "./container/OtherContainer/Stack";
export { default as Queue } from "./container/OtherContainer/Queue";
export { default as PriorityQueue } from "./container/OtherContainer/PriorityQueue";
export { default as Vector, VectorIterator } from "./container/SequentialContainer/Vector";
export { default as LinkList, LinkListIterator } from "./container/SequentialContainer/LinkList";
export { default as Deque, DequeIterator } from "./container/SequentialContainer/Deque";
export { default as OrderedSet, OrderedSetIterator } from "./container/TreeContainer/OrderedSet";
export { default as OrderedMap, OrderedMapIterator } from "./container/TreeContainer/OrderedMap";
export { default as HashSet } from "./container/HashContainer/HashSet";
export { default as HashMap } from "./container/HashContainer/HashMap";
export { Container, ContainerIterator } from "./container/ContainerBase/index";
export { default as SequentialContainer } from "./container/SequentialContainer/Base/index";
export { default as TreeContainer } from "./container/TreeContainer/Base/index";
export { default as HashContainer } from "./container/HashContainer/Base/index";

14
WebUI/node_modules/js-sdsl/dist/esm/index.js generated vendored Normal file
View File

@@ -0,0 +1,14 @@
export { default as Stack } from "./container/OtherContainer/Stack";
export { default as Queue } from "./container/OtherContainer/Queue";
export { default as PriorityQueue } from "./container/OtherContainer/PriorityQueue";
export { default as Vector, VectorIterator } from "./container/SequentialContainer/Vector";
export { default as LinkList, LinkListIterator } from "./container/SequentialContainer/LinkList";
export { default as Deque, DequeIterator } from "./container/SequentialContainer/Deque";
export { default as OrderedSet, OrderedSetIterator } from "./container/TreeContainer/OrderedSet";
export { default as OrderedMap, OrderedMapIterator } from "./container/TreeContainer/OrderedMap";
export { default as HashSet } from "./container/HashContainer/HashSet";
export { default as HashMap } from "./container/HashContainer/HashMap";
export { Container, ContainerIterator } from "./container/ContainerBase/index";
export { default as SequentialContainer } from "./container/SequentialContainer/Base/index";
export { default as TreeContainer } from "./container/TreeContainer/Base/index";
export { default as HashContainer } from "./container/HashContainer/Base/index";

View File

@@ -0,0 +1,8 @@
/**
* @description Check if access is out of bounds.
* @param pos The position want to access.
* @param lower The lower bound.
* @param upper The upper bound.
* @return Boolean about if access is out of bounds.
*/
export declare function checkWithinAccessParams(pos: number, lower: number, upper: number): void;

View File

@@ -0,0 +1,12 @@
/**
* @description Check if access is out of bounds.
* @param pos The position want to access.
* @param lower The lower bound.
* @param upper The upper bound.
* @return Boolean about if access is out of bounds.
*/
export function checkWithinAccessParams(pos, lower, upper) {
if (pos < lower || pos > upper) {
throw new RangeError();
}
}

2968
WebUI/node_modules/js-sdsl/dist/umd/js-sdsl.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

1
WebUI/node_modules/js-sdsl/dist/umd/js-sdsl.min.js generated vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

115
WebUI/node_modules/js-sdsl/package.json generated vendored Normal file
View File

@@ -0,0 +1,115 @@
{
"name": "js-sdsl",
"version": "4.1.4",
"description": "javascript standard data structure library which benchmark against C++ STL",
"main": "./dist/cjs/index.js",
"module": "./dist/esm/index.js",
"author": {
"name": "ZLY201",
"email": "951711127@qq.com",
"url": "https://github.com/js-sdsl/js-sdsl"
},
"browserslist": [
"last 2 version",
"> 1%",
"not dead",
"maintained node versions"
],
"sideEffects": false,
"homepage": "https://js-sdsl.github.io",
"scripts": {
"setup": "rm -rf node_modules && yarn install",
"dev": "ttsc --project tsconfig.cjs.json --watch",
"build": "yarn build:esm && yarn build:cjs && yarn build:umd:min",
"build:cjs": "rm -rf dist/cjs && ttsc --project tsconfig.cjs.json",
"build:esm": "rm -rf dist/esm && ttsc --project tsconfig.esm.json",
"build:umd": "rm -rf dist/umd && rollup -c",
"build:umd:min": "yarn build:umd && uglifyjs --compress --mangle --source-map --comments -o dist/umd/js-sdsl.min.js -- dist/umd/js-sdsl.js",
"test": "yarn test:unit && yarn test:performance",
"test:unit": "jest --coverage",
"test:performance": "rm -rf dist/performance && ttsc --project tsconfig.performance.json && node dist/performance/performance/index.js",
"lint": "eslint --fix --color --cache --max-warnings=0 .",
"generate": "typedoc src/index.ts",
"generate:dev": "typedoc src/index.ts --watch",
"prepare": "husky install"
},
"lint-staged": {
"*.{js,ts}": [
"yarn lint"
]
},
"devDependencies": {
"@types/jest": "^28.1.6",
"@types/node": "^17.0.0",
"@typescript-eslint/eslint-plugin": "^5.33.1",
"@typescript-eslint/parser": "^5.33.1",
"all-contributors-cli": "^6.20.0",
"browserslist": "^4.21.3",
"caniuse-lite": "^1.0.30001380",
"commitlint": "^17.0.3",
"conventional-changelog-conventionalcommits": "^5.0.0",
"coveralls": "^3.1.1",
"eslint": "^8.4.1",
"eslint-plugin-compat": "^4.0.2",
"gh-pages": "^3.2.3",
"husky": "^8.0.1",
"jest": "^28.1.3",
"lint-staged": "^12.1.0",
"rollup": "^2.78.1",
"rollup-plugin-typescript2": "^0.33.0",
"ts-jest": "^28.0.7",
"ts-node": "^10.9.1",
"ts-transform-paths": "^2.0.3",
"tsconfig-paths": "^4.0.0",
"tslib": "^2.4.0",
"ttypescript": "^1.5.13",
"typedoc": "^0.23.10",
"typedoc-plugin-missing-exports": "^1.0.0",
"typescript": "^4.7.4",
"uglify-js": "^3.14.5"
},
"repository": {
"type": "github",
"url": "https://github.com/js-sdsl/js-sdsl.git"
},
"license": "MIT",
"files": [
"dist/cjs",
"dist/esm",
"dist/umd",
"CHANGELOG.md"
],
"keywords": [
"data",
"structure",
"data structure",
"rbTree",
"rbtree",
"RBTree",
"red black tree",
"ordered",
"set",
"map",
"ordered map",
"ordered set",
"deque",
"heap",
"priority queue",
"link list",
"LinkList",
"linkedList",
"vector",
"stack",
"queue",
"hash",
"hash set",
"hash map",
"c++",
"stl"
],
"bugs": {
"email": "951711127@qq.com",
"url": "https://github.com/js-sdsl/js-sdsl/issues"
},
"dependencies": {}
}