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

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;