Fomrat the JS and TS codes with prettier.

This commit is contained in:
krahets
2023-04-17 21:58:11 +08:00
parent 9a98ff8a5e
commit c4ea4e39f3
68 changed files with 634 additions and 510 deletions

View File

@@ -0,0 +1,6 @@
{
"tabWidth": 4,
"useTabs": false,
"semi": true,
"singleQuote": true
}

View File

@@ -29,23 +29,20 @@ class MyList {
/* 访问元素 */
public get(index: number): number {
// 索引如果越界则抛出异常,下同
if (index < 0 || index >= this._size)
throw new Error('索引越界');
if (index < 0 || index >= this._size) throw new Error('索引越界');
return this.nums[index];
}
/* 更新元素 */
public set(index: number, num: number): void {
if (index < 0 || index >= this._size)
throw new Error('索引越界');
if (index < 0 || index >= this._size) throw new Error('索引越界');
this.nums[index] = num;
}
/* 尾部添加元素 */
public add(num: number): void {
// 如果长度等于容量,则需要扩容
if (this._size === this._capacity)
this.extendCapacity();
if (this._size === this._capacity) this.extendCapacity();
// 将新元素添加到列表尾部
this.nums[this._size] = num;
this._size++;
@@ -53,8 +50,7 @@ class MyList {
/* 中间插入元素 */
public insert(index: number, num: number): void {
if (index < 0 || index >= this._size)
throw new Error('索引越界');
if (index < 0 || index >= this._size) throw new Error('索引越界');
// 元素数量超出容量时,触发扩容机制
if (this._size === this._capacity) {
this.extendCapacity();
@@ -70,8 +66,7 @@ class MyList {
/* 删除元素 */
public remove(index: number): number {
if (index < 0 || index >= this._size)
throw new Error('索引越界');
if (index < 0 || index >= this._size) throw new Error('索引越界');
let num = this.nums[index];
// 将索引 index 之后的元素都向前移动一位
for (let j = index; j < this._size - 1; j++) {

View File

@@ -7,15 +7,20 @@
/* 二分查找(双闭区间) */
function binarySearch(nums: number[], target: number): number {
// 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素
let i = 0, j = nums.length - 1;
let i = 0,
j = nums.length - 1;
// 循环,当搜索区间为空时跳出(当 i > j 时为空)
while (i <= j) {
const m = Math.floor((i + j) / 2); // 计算中点索引 m
if (nums[m] < target) { // 此情况说明 target 在区间 [m+1, j] 中
// 计算中点索引 m
const m = Math.floor((i + j) / 2);
if (nums[m] < target) {
// 此情况说明 target 在区间 [m+1, j] 中
i = m + 1;
} else if (nums[m] > target) { // 此情况说明 target 在区间 [i, m-1] 中
} else if (nums[m] > target) {
// 此情况说明 target 在区间 [i, m-1] 中
j = m - 1;
} else { // 找到目标元素,返回其索引
} else {
// 找到目标元素,返回其索引
return m;
}
}
@@ -25,25 +30,29 @@ function binarySearch(nums: number[], target: number): number {
/* 二分查找(左闭右开) */
function binarySearch1(nums: number[], target: number): number {
// 初始化左闭右开 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1
let i = 0, j = nums.length;
let i = 0,
j = nums.length;
// 循环,当搜索区间为空时跳出(当 i = j 时为空)
while (i < j) {
const m = Math.floor((i + j) / 2); // 计算中点索引 m
if (nums[m] < target) { // 此情况说明 target 在区间 [m+1, j) 中
// 计算中点索引 m
const m = Math.floor((i + j) / 2);
if (nums[m] < target) {
// 此情况说明 target 在区间 [m+1, j) 中
i = m + 1;
} else if (nums[m] > target) { // 此情况说明 target 在区间 [i, m) 中
} else if (nums[m] > target) {
// 此情况说明 target 在区间 [i, m) 中
j = m;
} else { // 找到目标元素,返回其索引
} else {
// 找到目标元素,返回其索引
return m;
}
}
return -1; // 未找到目标元素,返回 -1
}
/* Driver Code */
const target = 6;
const nums = [ 1, 3, 6, 8, 12, 15, 23, 67, 70, 92 ];
const nums = [1, 3, 6, 8, 12, 15, 23, 67, 70, 92];
/* 二分查找(双闭区间) */
let index = binarySearch(nums, target);

View File

@@ -121,37 +121,37 @@ function factorialRecur(n: number): number {
/* Driver Code */
// 可以修改 n 运行,体会一下各种复杂度的操作数量变化趋势
const n = 8;
console.log("输入数据大小 n = " + n);
console.log('输入数据大小 n = ' + n);
let count = constant(n);
console.log("常数阶的计算操作数量 = " + count);
console.log('常数阶的计算操作数量 = ' + count);
count = linear(n);
console.log("线性阶的计算操作数量 = " + count);
console.log('线性阶的计算操作数量 = ' + count);
count = arrayTraversal(new Array(n));
console.log("线性阶(遍历数组)的计算操作数量 = " + count);
console.log('线性阶(遍历数组)的计算操作数量 = ' + count);
count = quadratic(n);
console.log("平方阶的计算操作数量 = " + count);
console.log('平方阶的计算操作数量 = ' + count);
var nums = new Array(n);
for (let i = 0; i < n; i++) nums[i] = n - i; // [n,n-1,...,2,1]
count = bubbleSort(nums);
console.log("平方阶(冒泡排序)的计算操作数量 = " + count);
console.log('平方阶(冒泡排序)的计算操作数量 = ' + count);
count = exponential(n);
console.log("指数阶(循环实现)的计算操作数量 = " + count);
console.log('指数阶(循环实现)的计算操作数量 = ' + count);
count = expRecur(n);
console.log("指数阶(递归实现)的计算操作数量 = " + count);
console.log('指数阶(递归实现)的计算操作数量 = ' + count);
count = logarithmic(n);
console.log("对数阶(循环实现)的计算操作数量 = " + count);
console.log('对数阶(循环实现)的计算操作数量 = ' + count);
count = logRecur(n);
console.log("对数阶(递归实现)的计算操作数量 = " + count);
console.log('对数阶(递归实现)的计算操作数量 = ' + count);
count = linearLogRecur(n);
console.log("线性对数阶(递归实现)的计算操作数量 = " + count);
console.log('线性对数阶(递归实现)的计算操作数量 = ' + count);
count = factorialRecur(n);
console.log("阶乘阶(递归实现)的计算操作数量 = " + count);
console.log('阶乘阶(递归实现)的计算操作数量 = ' + count);
export {};

View File

@@ -38,10 +38,8 @@ for (let i = 0; i < 10; i++) {
const n = 100;
const nums = randomNumbers(n);
const index = findOne(nums);
console.log(
"\n数组 [ 1, 2, ..., n ] 被打乱后 = [" + nums.join(", ") + "]"
);
console.log("数字 1 的索引为 " + index);
console.log('\n数组 [ 1, 2, ..., n ] 被打乱后 = [' + nums.join(', ') + ']');
console.log('数字 1 的索引为 ' + index);
}
export {};

View File

@@ -29,7 +29,11 @@ class GraphAdjList {
/* 添加边 */
addEdge(vet1: Vertex, vet2: Vertex): void {
if (!this.adjList.has(vet1) || !this.adjList.has(vet2) || vet1 === vet2) {
if (
!this.adjList.has(vet1) ||
!this.adjList.has(vet2) ||
vet1 === vet2
) {
throw new Error('Illegal Argument Exception');
}
// 添加边 vet1 - vet2
@@ -39,7 +43,11 @@ class GraphAdjList {
/* 删除边 */
removeEdge(vet1: Vertex, vet2: Vertex): void {
if (!this.adjList.has(vet1) || !this.adjList.has(vet2) || vet1 === vet2) {
if (
!this.adjList.has(vet1) ||
!this.adjList.has(vet2) ||
vet1 === vet2
) {
throw new Error('Illegal Argument Exception');
}
// 删除边 vet1 - vet2
@@ -98,7 +106,7 @@ if (require.main === module) {
[v2, v3],
[v0, v3],
[v2, v4],
[v3, v4]
[v3, v4],
];
const graph = new GraphAdjList(edges);
console.log('\n初始化后图为');

View File

@@ -6,8 +6,8 @@
/* 基于邻接矩阵实现的无向图类 */
class GraphAdjMat {
vertices: number[]; // 顶点列表,元素代表“顶点值”,索引代表“顶点索引”
adjMat: number[][]; // 邻接矩阵,行列索引对应“顶点索引”
vertices: number[]; // 顶点列表,元素代表“顶点值”,索引代表“顶点索引”
adjMat: number[][]; // 邻接矩阵,行列索引对应“顶点索引”
/* 构造函数 */
constructor(vertices: number[], edges: number[][]) {
@@ -49,7 +49,7 @@ class GraphAdjMat {
/* 删除顶点 */
removeVertex(index: number): void {
if (index >= this.size()) {
throw new RangeError("Index Out Of Bounds Exception");
throw new RangeError('Index Out Of Bounds Exception');
}
// 在顶点列表中移除索引 index 的顶点
this.vertices.splice(index, 1);
@@ -67,7 +67,7 @@ class GraphAdjMat {
addEdge(i: number, j: number): void {
// 索引越界与相等处理
if (i < 0 || j < 0 || i >= this.size() || j >= this.size() || i === j) {
throw new RangeError("Index Out Of Bounds Exception");
throw new RangeError('Index Out Of Bounds Exception');
}
// 在无向图中,邻接矩阵沿主对角线对称,即满足 (i, j) == (j, i)
this.adjMat[i][j] = 1;
@@ -79,7 +79,7 @@ class GraphAdjMat {
removeEdge(i: number, j: number): void {
// 索引越界与相等处理
if (i < 0 || j < 0 || i >= this.size() || j >= this.size() || i === j) {
throw new RangeError("Index Out Of Bounds Exception");
throw new RangeError('Index Out Of Bounds Exception');
}
this.adjMat[i][j] = 0;
this.adjMat[j][i] = 0;
@@ -87,8 +87,8 @@ class GraphAdjMat {
/* 打印邻接矩阵 */
print(): void {
console.log("顶点列表 = ", this.vertices);
console.log("邻接矩阵 =", this.adjMat);
console.log('顶点列表 = ', this.vertices);
console.log('邻接矩阵 =', this.adjMat);
}
}
@@ -96,33 +96,39 @@ class GraphAdjMat {
/* 初始化无向图 */
// 请注意edges 元素代表顶点索引,即对应 vertices 元素索引
const vertices: number[] = [1, 3, 2, 5, 4];
const edges: number[][] = [[0, 1], [1, 2], [2, 3], [0, 3], [2, 4], [3, 4]
const edges: number[][] = [
[0, 1],
[1, 2],
[2, 3],
[0, 3],
[2, 4],
[3, 4],
];
const graph: GraphAdjMat = new GraphAdjMat(vertices, edges);
console.log("\n初始化后图为");
console.log('\n初始化后图为');
graph.print();
/* 添加边 */
// 顶点 1, 2 的索引分别为 0, 2
graph.addEdge(0, 2);
console.log("\n添加边 1-2 后,图为");
console.log('\n添加边 1-2 后,图为');
graph.print();
/* 删除边 */
// 顶点 1, 3 的索引分别为 0, 1
graph.removeEdge(0, 1);
console.log("\n删除边 1-3 后,图为");
console.log('\n删除边 1-3 后,图为');
graph.print();
/* 添加顶点 */
graph.addVertex(6);
console.log("\n添加顶点 6 后,图为");
console.log('\n添加顶点 6 后,图为');
graph.print();
/* 删除顶点 */
// 顶点 3 的索引为 1
graph.removeVertex(1);
console.log("\n删除顶点 3 后,图为");
console.log('\n删除顶点 3 后,图为');
graph.print();
export {};
export {};

View File

@@ -49,7 +49,7 @@ const edges = [
[v[4], v[7]],
[v[5], v[8]],
[v[6], v[7]],
[v[7], v[8]]
[v[7], v[8]],
];
const graph = new GraphAdjList(edges);
console.log('\n初始化后图为');

View File

@@ -8,7 +8,12 @@ import { Vertex } from '../modules/Vertex';
import { GraphAdjList } from './graph_adjacency_list';
/* 深度优先遍历 DFS 辅助函数 */
function dfs(graph: GraphAdjList, visited: Set<Vertex>, res: Vertex[], vet: Vertex): void {
function dfs(
graph: GraphAdjList,
visited: Set<Vertex>,
res: Vertex[],
vet: Vertex
): void {
res.push(vet); // 记录访问顶点
visited.add(vet); // 标记该顶点已被访问
// 遍历该顶点的所有邻接顶点
@@ -41,7 +46,7 @@ const edges = [
[v[1], v[2]],
[v[2], v[5]],
[v[4], v[5]],
[v[5], v[6]]
[v[5], v[6]],
];
const graph = new GraphAdjList(edges);
console.log('\n初始化后图为');

View File

@@ -17,12 +17,11 @@ class Entry {
/* 基于数组简易实现的哈希表 */
class ArrayHashMap {
private readonly buckets: (Entry | null)[];
constructor() {
// 初始化数组,包含 100 个桶
this.buckets = (new Array(100)).fill(null);
this.buckets = new Array(100).fill(null);
}
/* 哈希函数 */

View File

@@ -14,7 +14,10 @@ function hashingSearchArray(map: Map<number, number>, target: number): number {
}
/* 哈希查找(链表) */
function hashingSearchLinkedList(map: Map<number, ListNode>, target: number): ListNode | null {
function hashingSearchLinkedList(
map: Map<number, ListNode>,
target: number
): ListNode | null {
// 哈希表的 key: 目标节点值value: 节点对象
// 若哈希表中无此 key ,返回 null
return map.has(target) ? (map.get(target) as ListNode) : null;

View File

@@ -1,7 +1,7 @@
/**
* File: leetcode_two_sum.ts
* Created Time: 2022-12-15
* Author: gyt95 (gytkwan@gmail.com)
* Author: gyt95 (gytkwan@gmail.com)
*/
/* 方法一:暴力枚举 */
@@ -16,7 +16,7 @@ function twoSumBruteForce(nums: number[], target: number): number[] {
}
}
return [];
};
}
/* 方法二:辅助哈希表 */
function twoSumHashTable(nums: number[], target: number): number[] {
@@ -32,17 +32,18 @@ function twoSumHashTable(nums: number[], target: number): number[] {
}
}
return [];
};
}
/* Driver Code */
// 方法一
const nums = [2, 7, 11, 15], target = 9;
const nums = [2, 7, 11, 15],
target = 9;
let res = twoSumBruteForce(nums, target);
console.log("方法一 res = ", res);
console.log('方法一 res = ', res);
// 方法二
res = twoSumHashTable(nums, target);
console.log("方法二 res = ", res);
console.log('方法二 res = ', res);
export {};

View File

@@ -20,7 +20,10 @@ function linearSearchArray(nums: number[], target: number): number {
}
/* 线性查找(链表)*/
function linearSearchLinkedList(head: ListNode | null, target: number): ListNode | null {
function linearSearchLinkedList(
head: ListNode | null,
target: number
): ListNode | null {
// 遍历链表
while (head) {
// 找到目标节点,返回之

View File

@@ -11,20 +11,23 @@ function merge(nums: number[], left: number, mid: number, right: number): void {
// 初始化辅助数组
let tmp = nums.slice(left, right + 1);
// 左子数组的起始索引和结束索引
let leftStart = left - left, leftEnd = mid - left;
let leftStart = left - left,
leftEnd = mid - left;
// 右子数组的起始索引和结束索引
let rightStart = mid + 1 - left, rightEnd = right - left;
let rightStart = mid + 1 - left,
rightEnd = right - left;
// i, j 分别指向左子数组、右子数组的首元素
let i = leftStart, j = rightStart;
let i = leftStart,
j = rightStart;
// 通过覆盖原数组 nums 来合并左子数组和右子数组
for (let k = left; k <= right; k++) {
// 若“左子数组已全部合并完”,则选取右子数组元素,并且 j++
if (i > leftEnd) {
// 若“左子数组已全部合并完”,则选取右子数组元素,并且 j++
nums[k] = tmp[j++];
// 否则,若“右子数组已全部合并完”或“左子数组元素 <= 右子数组元素”,则选取左子数组元素,并且 i++
// 否则,若“右子数组已全部合并完”或“左子数组元素 <= 右子数组元素”,则选取左子数组元素,并且 i++
} else if (j > rightEnd || tmp[i] <= tmp[j]) {
nums[k] = tmp[i++];
// 否则,若“左右子数组都未全部合并完”且“左子数组元素 > 右子数组元素”,则选取右子数组元素,并且 j++
// 否则,若“左右子数组都未全部合并完”且“左子数组元素 > 右子数组元素”,则选取右子数组元素,并且 j++
} else {
nums[k] = tmp[j++];
}

View File

@@ -16,7 +16,8 @@ class QuickSort {
/* 哨兵划分 */
partition(nums: number[], left: number, right: number): number {
// 以 nums[left] 作为基准数
let i = left, j = right;
let i = left,
j = right;
while (i < j) {
while (i < j && nums[j] >= nums[left]) {
j -= 1; // 从右向左找首个小于基准数的元素
@@ -55,12 +56,19 @@ class QuickSortMedian {
}
/* 选取三个元素的中位数 */
medianThree(nums: number[], left: number, mid: number, right: number): number {
medianThree(
nums: number[],
left: number,
mid: number,
right: number
): number {
// 此处使用异或运算来简化代码
// 异或规则为 0 ^ 0 = 1 ^ 1 = 0, 0 ^ 1 = 1 ^ 0 = 1
if (Number(nums[left] < nums[mid]) ^ Number(nums[left] < nums[right])) {
return left;
} else if (Number(nums[mid] < nums[left]) ^ Number(nums[mid] < nums[right])) {
} else if (
Number(nums[mid] < nums[left]) ^ Number(nums[mid] < nums[right])
) {
return mid;
} else {
return right;
@@ -70,11 +78,17 @@ class QuickSortMedian {
/* 哨兵划分(三数取中值) */
partition(nums: number[], left: number, right: number): number {
// 选取三个候选元素的中位数
let med = this.medianThree(nums, left, Math.floor((left + right) / 2), right);
let med = this.medianThree(
nums,
left,
Math.floor((left + right) / 2),
right
);
// 将中位数交换至数组最左端
this.swap(nums, left, med);
// 以 nums[left] 作为基准数
let i = left, j = right;
let i = left,
j = right;
while (i < j) {
while (i < j && nums[j] >= nums[left]) {
j--; // 从右向左找首个小于基准数的元素
@@ -114,7 +128,8 @@ class QuickSortTailCall {
/* 哨兵划分 */
partition(nums: number[], left: number, right: number): number {
// 以 nums[left] 作为基准数
let i = left, j = right;
let i = left,
j = right;
while (i < j) {
while (i < j && nums[j] >= nums[left]) {
j--; // 从右向左找首个小于基准数的元素

View File

@@ -18,7 +18,7 @@ function countingSortDigit(nums: number[], exp: number): void {
// 统计 0~9 各数字的出现次数
for (let i = 0; i < n; i++) {
const d = digit(nums[i], exp); // 获取 nums[i] 第 k 位,记为 d
counter[d]++; // 统计数字 d 的出现次数
counter[d]++; // 统计数字 d 的出现次数
}
// 求前缀和,将“出现个数”转换为“数组索引”
for (let i = 1; i < 10; i++) {
@@ -29,8 +29,8 @@ function countingSortDigit(nums: number[], exp: number): void {
for (let i = n - 1; i >= 0; i--) {
const d = digit(nums[i], exp);
const j = counter[d] - 1; // 获取 d 在数组中的索引 j
res[j] = nums[i]; // 将当前元素填入索引 j
counter[d]--; // 将 d 的数量减 1
res[j] = nums[i]; // 将当前元素填入索引 j
counter[d]--; // 将 d 的数量减 1
}
// 使用结果覆盖原数组 nums
for (let i = 0; i < n; i++) {
@@ -58,8 +58,10 @@ function radixSort(nums: number[]): void {
}
/* Driver Code */
const nums = [10546151, 35663510, 42865989, 34862445, 81883077,
88906420, 72429244, 30524779, 82060337, 63832996];
const nums = [
10546151, 35663510, 42865989, 34862445, 81883077, 88906420, 72429244,
30524779, 82060337, 63832996,
];
radixSort(nums);
console.log('基数排序完成后 nums =', nums);

View File

@@ -4,12 +4,11 @@
* Author: Zhuo Qinyue (1403450829@qq.com)
*/
/* 基于环形数组实现的双向队列 */
class ArrayDeque {
private nums: number[]; // 用于存储双向队列元素的数组
private front: number; // 队首指针,指向队首元素
private queSize: number; // 双向队列长度
private nums: number[]; // 用于存储双向队列元素的数组
private front: number; // 队首指针,指向队首元素
private queSize: number; // 双向队列长度
/* 构造方法 */
constructor(capacity: number) {
@@ -44,7 +43,7 @@ class ArrayDeque {
/* 队首入队 */
pushFirst(num: number): void {
if (this.queSize === this.capacity()) {
console.log("双向队列已满");
console.log('双向队列已满');
return;
}
// 队首指针向左移动一位
@@ -58,7 +57,7 @@ class ArrayDeque {
/* 队尾入队 */
pushLast(num: number): void {
if (this.queSize === this.capacity()) {
console.log("双向队列已满");
console.log('双向队列已满');
return;
}
// 计算尾指针,指向队尾索引 + 1
@@ -86,15 +85,13 @@ class ArrayDeque {
/* 访问队首元素 */
peekFirst(): number {
if (this.isEmpty())
throw new Error("The Deque Is Empty.");
if (this.isEmpty()) throw new Error('The Deque Is Empty.');
return this.nums[this.front];
}
/* 访问队尾元素 */
peekLast(): number {
if (this.isEmpty())
throw new Error("The Deque Is Empty.");
if (this.isEmpty()) throw new Error('The Deque Is Empty.');
// 计算尾元素索引
const last = this.index(this.front + this.queSize - 1);
return this.nums[last];
@@ -118,32 +115,44 @@ const deque: ArrayDeque = new ArrayDeque(capacity);
deque.pushLast(3);
deque.pushLast(2);
deque.pushLast(5);
console.log("双向队列 deque = [" + deque.toArray() + "]");
console.log('双向队列 deque = [' + deque.toArray() + ']');
/* 访问元素 */
const peekFirst = deque.peekFirst();
console.log("队首元素 peekFirst = " + peekFirst);
console.log('队首元素 peekFirst = ' + peekFirst);
const peekLast = deque.peekLast();
console.log("队尾元素 peekLast = " + peekLast);
console.log('队尾元素 peekLast = ' + peekLast);
/* 元素入队 */
deque.pushLast(4);
console.log("元素 4 队尾入队后 deque = [" + deque.toArray() + "]");
console.log('元素 4 队尾入队后 deque = [' + deque.toArray() + ']');
deque.pushFirst(1);
console.log("元素 1 队首入队后 deque = [" + deque.toArray() + "]");
console.log('元素 1 队首入队后 deque = [' + deque.toArray() + ']');
/* 元素出队 */
const popLast = deque.popLast();
console.log("队尾出队元素 = " + popLast + ",队尾出队后 deque = [" + deque.toArray() + "]");
console.log(
'队尾出队元素 = ' +
popLast +
',队尾出队后 deque = [' +
deque.toArray() +
']'
);
const popFirst = deque.popFirst();
console.log("队首出队元素 = " + popFirst + ",队首出队后 deque = [" + deque.toArray()+ "]");
console.log(
'队首出队元素 = ' +
popFirst +
',队首出队后 deque = [' +
deque.toArray() +
']'
);
/* 获取双向队列的长度 */
const size = deque.size();
console.log("双向队列长度 size = " + size);
console.log('双向队列长度 size = ' + size);
/* 判断双向队列是否为空 */
const isEmpty = deque.isEmpty();
console.log("双向队列是否为空 = " + isEmpty);
console.log('双向队列是否为空 = ' + isEmpty);
export {};

View File

@@ -6,8 +6,8 @@
/* 基于环形数组实现的队列 */
class ArrayQueue {
private nums: number[]; // 用于存储队列元素的数组
private front: number; // 队首指针,指向队首元素
private nums: number[]; // 用于存储队列元素的数组
private front: number; // 队首指针,指向队首元素
private queSize: number; // 队列长度
constructor(capacity: number) {
@@ -33,7 +33,7 @@ class ArrayQueue {
/* 入队 */
push(num: number): void {
if (this.size == this.capacity) {
console.log("队列已满");
console.log('队列已满');
return;
}
// 计算尾指针,指向队尾索引 + 1
@@ -55,8 +55,7 @@ class ArrayQueue {
/* 访问队首元素 */
peek(): number {
if (this.empty())
throw new Error("队列为空");
if (this.empty()) throw new Error('队列为空');
return this.nums[this.front];
}
@@ -82,29 +81,29 @@ queue.push(3);
queue.push(2);
queue.push(5);
queue.push(4);
console.log("队列 queue =", queue.toArray());
console.log('队列 queue =', queue.toArray());
/* 访问队首元素 */
const peek = queue.peek();
console.log("队首元素 peek = " + peek);
console.log('队首元素 peek = ' + peek);
/* 元素出队 */
const pop = queue.pop();
console.log("出队元素 pop = " + pop + ",出队后 queue =", queue.toArray());
console.log('出队元素 pop = ' + pop + ',出队后 queue =', queue.toArray());
/* 获取队列的长度 */
const size = queue.size;
console.log("队列长度 size = " + size);
console.log('队列长度 size = ' + size);
/* 判断队列是否为空 */
const empty = queue.empty();
console.log("队列是否为空 = " + empty);
console.log('队列是否为空 = ' + empty);
/* 测试环形数组 */
for (let i = 0; i < 10; i++) {
queue.push(i);
queue.pop();
console.log("" + i + " 轮入队 + 出队后 queue =", queue.toArray());
console.log('' + i + ' 轮入队 + 出队后 queue =', queue.toArray());
}
export {};

View File

@@ -4,7 +4,6 @@
* Author: S-N-O-R-L-A-X (snorlax.xu@outlook.com)
*/
/* 基于数组实现的栈 */
class ArrayStack {
private stack: number[];
@@ -29,15 +28,13 @@ class ArrayStack {
/* 出栈 */
pop(): number | undefined {
if (this.empty())
throw new Error('栈为空');
if (this.empty()) throw new Error('栈为空');
return this.stack.pop();
}
/* 访问栈顶元素 */
top(): number | undefined {
if (this.empty())
throw new Error('栈为空');
if (this.empty()) throw new Error('栈为空');
return this.stack[this.stack.length - 1];
}
@@ -45,8 +42,7 @@ class ArrayStack {
toArray() {
return this.stack;
}
};
}
/* Driver Code */
/* 初始化栈 */
@@ -58,24 +54,24 @@ stack.push(3);
stack.push(2);
stack.push(5);
stack.push(4);
console.log("栈 stack = ");
console.log('栈 stack = ');
console.log(stack.toArray());
/* 访问栈顶元素 */
const top = stack.top();
console.log("栈顶元素 top = " + top);
console.log('栈顶元素 top = ' + top);
/* 元素出栈 */
const pop = stack.pop();
console.log("出栈元素 pop = " + pop + ",出栈后 stack = ");
console.log('出栈元素 pop = ' + pop + ',出栈后 stack = ');
console.log(stack.toArray());
/* 获取栈的长度 */
const size = stack.size;
console.log("栈的长度 size = " + size);
console.log('栈的长度 size = ' + size);
/* 判断是否为空 */
const empty = stack.empty();
console.log("栈是否为空 = " + empty);
console.log('栈是否为空 = ' + empty);
export {};

View File

@@ -16,27 +16,31 @@ deque.push(4);
// 请注意由于是数组unshift() 方法的时间复杂度为 O(n)
deque.unshift(3);
deque.unshift(1);
console.log("双向队列 deque = ", deque);
console.log('双向队列 deque = ', deque);
/* 访问元素 */
const peekFirst: number = deque[0];
console.log("队首元素 peekFirst = " + peekFirst);
console.log('队首元素 peekFirst = ' + peekFirst);
const peekLast: number = deque[deque.length - 1];
console.log("队尾元素 peekLast = " + peekLast);
console.log('队尾元素 peekLast = ' + peekLast);
/* 元素出队 */
// 请注意由于是数组shift() 方法的时间复杂度为 O(n)
const popFront: number = deque.shift() as number;
console.log("队首出队元素 popFront = " + popFront + ",队首出队后 deque = " + deque);
console.log(
'队首出队元素 popFront = ' + popFront + ',队首出队后 deque = ' + deque
);
const popBack: number = deque.pop() as number;
console.log("队尾出队元素 popBack = " + popBack + ",队尾出队后 deque = " + deque);
console.log(
'队尾出队元素 popBack = ' + popBack + ',队尾出队后 deque = ' + deque
);
/* 获取双向队列的长度 */
const size: number = deque.length;
console.log("双向队列长度 size = " + size);
console.log('双向队列长度 size = ' + size);
/* 判断双向队列是否为空 */
const isEmpty: boolean = size === 0;
console.log("双向队列是否为空 = " + isEmpty);
console.log('双向队列是否为空 = ' + isEmpty);
export {};

View File

@@ -6,9 +6,9 @@
/* 双向链表节点 */
class ListNode {
prev: ListNode; // 前驱节点引用 (指针)
next: ListNode; // 后继节点引用 (指针)
val: number; // 节点值
prev: ListNode; // 前驱节点引用 (指针)
next: ListNode; // 后继节点引用 (指针)
val: number; // 节点值
constructor(val: number) {
this.val = val;
@@ -19,16 +19,16 @@ class ListNode {
/* 基于双向链表实现的双向队列 */
class LinkedListDeque {
private front: ListNode; // 头节点 front
private rear: ListNode; // 尾节点 rear
private queSize: number; // 双向队列的长度
private front: ListNode; // 头节点 front
private rear: ListNode; // 尾节点 rear
private queSize: number; // 双向队列的长度
constructor() {
this.front = null;
this.rear = null;
this.queSize = 0;
}
/* 队尾入队操作 */
pushLast(val: number): void {
const node: ListNode = new ListNode(val);
@@ -73,7 +73,7 @@ class LinkedListDeque {
temp.next = null;
this.rear.prev = null;
}
this.rear = temp; // 更新尾节点
this.rear = temp; // 更新尾节点
this.queSize--;
return value;
}
@@ -90,7 +90,7 @@ class LinkedListDeque {
temp.prev = null;
this.front.next = null;
}
this.front = temp; // 更新头节点
this.front = temp; // 更新头节点
this.queSize--;
return value;
}
@@ -123,7 +123,7 @@ class LinkedListDeque {
arr.push(temp.val);
temp = temp.next;
}
console.log("[" + arr.join(", ") + "]");
console.log('[' + arr.join(', ') + ']');
}
}
@@ -133,35 +133,35 @@ const linkedListDeque: LinkedListDeque = new LinkedListDeque();
linkedListDeque.pushLast(3);
linkedListDeque.pushLast(2);
linkedListDeque.pushLast(5);
console.log("双向队列 linkedListDeque = ");
console.log('双向队列 linkedListDeque = ');
linkedListDeque.print();
/* 访问元素 */
const peekFirst: number = linkedListDeque.peekFirst();
console.log("队首元素 peekFirst = " + peekFirst);
console.log('队首元素 peekFirst = ' + peekFirst);
const peekLast: number = linkedListDeque.peekLast();
console.log("队尾元素 peekLast = " + peekLast);
console.log('队尾元素 peekLast = ' + peekLast);
/* 元素入队 */
linkedListDeque.pushLast(4);
console.log("元素 4 队尾入队后 linkedListDeque = ");
console.log('元素 4 队尾入队后 linkedListDeque = ');
linkedListDeque.print();
linkedListDeque.pushFirst(1);
console.log("元素 1 队首入队后 linkedListDeque = ");
console.log('元素 1 队首入队后 linkedListDeque = ');
linkedListDeque.print();
/* 元素出队 */
const popLast: number = linkedListDeque.popLast();
console.log("队尾出队元素 = " + popLast + ",队尾出队后 linkedListDeque = ");
console.log('队尾出队元素 = ' + popLast + ',队尾出队后 linkedListDeque = ');
linkedListDeque.print();
const popFirst: number = linkedListDeque.popFirst();
console.log("队首出队元素 = " + popFirst + ",队首出队后 linkedListDeque = ");
console.log('队首出队元素 = ' + popFirst + ',队首出队后 linkedListDeque = ');
linkedListDeque.print();
/* 获取双向队列的长度 */
const size: number = linkedListDeque.size();
console.log("双向队列长度 size = " + size);
console.log('双向队列长度 size = ' + size);
/* 判断双向队列是否为空 */
const isEmpty: boolean = linkedListDeque.isEmpty();
console.log("双向队列是否为空 = " + isEmpty);
console.log('双向队列是否为空 = ' + isEmpty);

View File

@@ -6,7 +6,7 @@
/* Driver Code */
/* 初始化队列 */
// TypeScript 没有内置的队列,可以把 Array 当作队列来使用
// TypeScript 没有内置的队列,可以把 Array 当作队列来使用
const queue: number[] = [];
/* 元素入队 */
@@ -15,23 +15,23 @@ queue.push(3);
queue.push(2);
queue.push(5);
queue.push(4);
console.log("队列 queue =", queue);
console.log('队列 queue =', queue);
/* 访问队首元素 */
const peek = queue[0];
console.log("队首元素 peek =", peek);
console.log('队首元素 peek =', peek);
/* 元素出队 */
// 底层是数组,因此 shift() 方法的时间复杂度为 O(n)
const pop = queue.shift();
console.log("出队元素 pop =", pop, ",出队后 queue = ", queue);
console.log('出队元素 pop =', pop, ',出队后 queue = ', queue);
/* 获取队列的长度 */
const size = queue.length;
console.log("队列长度 size =", size);
console.log('队列长度 size =', size);
/* 判断队列是否为空 */
const isEmpty = queue.length === 0;
console.log("队列是否为空 = ", isEmpty);
console.log('队列是否为空 = ', isEmpty);
export {};

View File

@@ -6,7 +6,7 @@
/* Driver Code */
/* 初始化栈 */
// Typescript 没有内置的栈类,可以把 Array 当作栈来使用
// Typescript 没有内置的栈类,可以把 Array 当作栈来使用
const stack: number[] = [];
/* 元素入栈 */
@@ -15,23 +15,23 @@ stack.push(3);
stack.push(2);
stack.push(5);
stack.push(4);
console.log("栈 stack =", stack);
console.log('栈 stack =', stack);
/* 访问栈顶元素 */
const peek = stack[stack.length - 1];
console.log("栈顶元素 peek =", peek);
console.log('栈顶元素 peek =', peek);
/* 元素出栈 */
const pop = stack.pop();
console.log("出栈元素 pop =", pop);
console.log("出栈后 stack =", stack);
console.log('出栈元素 pop =', pop);
console.log('出栈后 stack =', stack);
/* 获取栈的长度 */
const size = stack.length;
console.log("栈的长度 size =", size);
console.log('栈的长度 size =', size);
/* 判断是否为空 */
const isEmpty = stack.length === 0;
console.log("栈是否为空 =", isEmpty);
console.log('栈是否为空 =', isEmpty);
export {};

View File

@@ -24,7 +24,8 @@ class AVLTree {
/* 更新节点高度 */
private updateHeight(node: TreeNode): void {
// 节点高度等于最高子树高度 + 1
node.height = Math.max(this.height(node.left), this.height(node.right)) + 1;
node.height =
Math.max(this.height(node.left), this.height(node.right)) + 1;
}
/* 获取平衡因子 */

View File

@@ -44,8 +44,4 @@ function getListNode(head: ListNode | null, val: number): ListNode | null {
return head;
}
export {
ListNode,
arrToLinkedList,
getListNode
};
export { ListNode, arrToLinkedList, getListNode };

View File

@@ -4,8 +4,8 @@
* Author: Justin (xiefahit@gmail.com)
*/
import { ListNode } from "./ListNode";
import { TreeNode, arrToTree } from "./TreeNode";
import { ListNode } from './ListNode';
import { TreeNode, arrToTree } from './TreeNode';
/**
* Print a linked list
@@ -46,7 +46,11 @@ function printTree(root: TreeNode | null) {
* @param prev
* @param isLeft
*/
function printTreeHelper(root: TreeNode | null, prev: Trunk | null, isLeft: boolean) {
function printTreeHelper(
root: TreeNode | null,
prev: Trunk | null,
isLeft: boolean
) {
if (root === null) {
return;
}
@@ -98,15 +102,11 @@ function showTrunks(p: Trunk | null) {
* @param arr
*/
function printHeap(arr: number[]): void {
console.log("堆的数组表示:");
console.log('堆的数组表示:');
console.log(arr);
console.log("堆的树状表示:");
console.log('堆的树状表示:');
const root = arrToTree(arr);
printTree(root);
}
export {
printLinkedList,
printTree,
printHeap
};
export { printLinkedList, printTree, printHeap };

View File

@@ -8,15 +8,20 @@
* Definition for a binary tree node.
*/
class TreeNode {
val: number; // 节点值
height: number; // 节点高度
left: TreeNode | null; // 左子节点指针
val: number; // 节点值
height: number; // 节点高度
left: TreeNode | null; // 左子节点指针
right: TreeNode | null; // 右子节点指针
constructor(val?: number, height?: number, left?: TreeNode | null, right?: TreeNode | null) {
constructor(
val?: number,
height?: number,
left?: TreeNode | null,
right?: TreeNode | null
) {
this.val = val === undefined ? 0 : val;
this.height = height === undefined ? 0 : height;
this.left = left === undefined ? null : left;
this.right = right === undefined ? null : right;
this.height = height === undefined ? 0 : height;
this.left = left === undefined ? null : left;
this.right = right === undefined ? null : right;
}
}
@@ -49,7 +54,4 @@ function arrToTree(arr: (number | null)[]): TreeNode | null {
return root;
}
export {
TreeNode,
arrToTree
};
export { TreeNode, arrToTree };

View File

@@ -4,7 +4,6 @@
* Author: Zhuo Qinyue (1403450829@qq.com)
*/
/* 顶点类 */
class Vertex {
val: number;
@@ -31,6 +30,4 @@ class Vertex {
}
}
export {
Vertex
};
export { Vertex };

View File

@@ -5,4 +5,4 @@
"outDir": "out",
"sourceMap": true
}
}
}