mirror of
https://github.com/krahets/hello-algo.git
synced 2024-12-25 01:16:31 +08:00
Fomrat the JS and TS codes with prettier.
This commit is contained in:
parent
9a98ff8a5e
commit
c4ea4e39f3
68 changed files with 634 additions and 510 deletions
6
codes/javascript/.prettierrc
Normal file
6
codes/javascript/.prettierrc
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"tabWidth": 4,
|
||||||
|
"useTabs": false,
|
||||||
|
"semi": true,
|
||||||
|
"singleQuote": true
|
||||||
|
}
|
|
@ -69,29 +69,29 @@ function find(nums, target) {
|
||||||
/* Driver Codes*/
|
/* Driver Codes*/
|
||||||
/* 初始化数组 */
|
/* 初始化数组 */
|
||||||
const arr = new Array(5).fill(0);
|
const arr = new Array(5).fill(0);
|
||||||
console.log("数组 arr =", arr);
|
console.log('数组 arr =', arr);
|
||||||
let nums = [1, 3, 2, 5, 4];
|
let nums = [1, 3, 2, 5, 4];
|
||||||
console.log("数组 nums =", nums);
|
console.log('数组 nums =', nums);
|
||||||
|
|
||||||
/* 随机访问 */
|
/* 随机访问 */
|
||||||
let random_num = randomAccess(nums);
|
let random_num = randomAccess(nums);
|
||||||
console.log("在 nums 中获取随机元素", random_num);
|
console.log('在 nums 中获取随机元素', random_num);
|
||||||
|
|
||||||
/* 长度扩展 */
|
/* 长度扩展 */
|
||||||
nums = extend(nums, 3);
|
nums = extend(nums, 3);
|
||||||
console.log("将数组长度扩展至 8 ,得到 nums =", nums);
|
console.log('将数组长度扩展至 8 ,得到 nums =', nums);
|
||||||
|
|
||||||
/* 插入元素 */
|
/* 插入元素 */
|
||||||
insert(nums, 6, 3);
|
insert(nums, 6, 3);
|
||||||
console.log("在索引 3 处插入数字 6 ,得到 nums =", nums);
|
console.log('在索引 3 处插入数字 6 ,得到 nums =', nums);
|
||||||
|
|
||||||
/* 删除元素 */
|
/* 删除元素 */
|
||||||
remove(nums, 2);
|
remove(nums, 2);
|
||||||
console.log("删除索引 2 处的元素,得到 nums =", nums);
|
console.log('删除索引 2 处的元素,得到 nums =', nums);
|
||||||
|
|
||||||
/* 遍历数组 */
|
/* 遍历数组 */
|
||||||
traverse(nums);
|
traverse(nums);
|
||||||
|
|
||||||
/* 查找元素 */
|
/* 查找元素 */
|
||||||
let index = find(nums, 3);
|
let index = find(nums, 3);
|
||||||
console.log("在 nums 中查找元素 3 ,得到索引 =", index);
|
console.log('在 nums 中查找元素 3 ,得到索引 =', index);
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
* Author: IsChristina (christinaxia77@foxmail.com), Justin (xiefahit@gmail.com)
|
* Author: IsChristina (christinaxia77@foxmail.com), Justin (xiefahit@gmail.com)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { printLinkedList } = require("../modules/PrintUtil");
|
const { printLinkedList } = require('../modules/PrintUtil');
|
||||||
const { ListNode } = require("../modules/ListNode");
|
const { ListNode } = require('../modules/ListNode');
|
||||||
|
|
||||||
/* 在链表的节点 n0 之后插入节点 P */
|
/* 在链表的节点 n0 之后插入节点 P */
|
||||||
function insert(n0, P) {
|
function insert(n0, P) {
|
||||||
|
@ -16,8 +16,7 @@ function insert(n0, P) {
|
||||||
|
|
||||||
/* 删除链表的节点 n0 之后的首个节点 */
|
/* 删除链表的节点 n0 之后的首个节点 */
|
||||||
function remove(n0) {
|
function remove(n0) {
|
||||||
if (!n0.next)
|
if (!n0.next) return;
|
||||||
return;
|
|
||||||
// n0 -> P -> n1
|
// n0 -> P -> n1
|
||||||
const P = n0.next;
|
const P = n0.next;
|
||||||
const n1 = P.next;
|
const n1 = P.next;
|
||||||
|
@ -61,23 +60,23 @@ n0.next = n1;
|
||||||
n1.next = n2;
|
n1.next = n2;
|
||||||
n2.next = n3;
|
n2.next = n3;
|
||||||
n3.next = n4;
|
n3.next = n4;
|
||||||
console.log("初始化的链表为");
|
console.log('初始化的链表为');
|
||||||
printLinkedList(n0);
|
printLinkedList(n0);
|
||||||
|
|
||||||
/* 插入节点 */
|
/* 插入节点 */
|
||||||
insert(n0, new ListNode(0));
|
insert(n0, new ListNode(0));
|
||||||
console.log("插入节点后的链表为");
|
console.log('插入节点后的链表为');
|
||||||
printLinkedList(n0);
|
printLinkedList(n0);
|
||||||
|
|
||||||
/* 删除节点 */
|
/* 删除节点 */
|
||||||
remove(n0);
|
remove(n0);
|
||||||
console.log("删除节点后的链表为");
|
console.log('删除节点后的链表为');
|
||||||
printLinkedList(n0);
|
printLinkedList(n0);
|
||||||
|
|
||||||
/* 访问节点 */
|
/* 访问节点 */
|
||||||
const node = access(n0, 3);
|
const node = access(n0, 3);
|
||||||
console.log("链表中索引 3 处的节点的值 = " + node.val);
|
console.log('链表中索引 3 处的节点的值 = ' + node.val);
|
||||||
|
|
||||||
/* 查找节点 */
|
/* 查找节点 */
|
||||||
const index = find(n0, 2);
|
const index = find(n0, 2);
|
||||||
console.log("链表中值为 2 的节点的索引 = " + index);
|
console.log('链表中值为 2 的节点的索引 = ' + index);
|
||||||
|
|
|
@ -29,15 +29,13 @@ class MyList {
|
||||||
/* 访问元素 */
|
/* 访问元素 */
|
||||||
get(index) {
|
get(index) {
|
||||||
// 索引如果越界则抛出异常,下同
|
// 索引如果越界则抛出异常,下同
|
||||||
if (index < 0 || index >= this.#size)
|
if (index < 0 || index >= this.#size) throw new Error('索引越界');
|
||||||
throw new Error('索引越界');
|
|
||||||
return this.#nums[index];
|
return this.#nums[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 更新元素 */
|
/* 更新元素 */
|
||||||
set(index, num) {
|
set(index, num) {
|
||||||
if (index < 0 || index >= this.#size)
|
if (index < 0 || index >= this.#size) throw new Error('索引越界');
|
||||||
throw new Error('索引越界');
|
|
||||||
this.#nums[index] = num;
|
this.#nums[index] = num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,8 +52,7 @@ class MyList {
|
||||||
|
|
||||||
/* 中间插入元素 */
|
/* 中间插入元素 */
|
||||||
insert(index, num) {
|
insert(index, num) {
|
||||||
if (index < 0 || index >= this.#size)
|
if (index < 0 || index >= this.#size) throw new Error('索引越界');
|
||||||
throw new Error('索引越界');
|
|
||||||
// 元素数量超出容量时,触发扩容机制
|
// 元素数量超出容量时,触发扩容机制
|
||||||
if (this.#size === this.#capacity) {
|
if (this.#size === this.#capacity) {
|
||||||
this.extendCapacity();
|
this.extendCapacity();
|
||||||
|
@ -71,8 +68,7 @@ class MyList {
|
||||||
|
|
||||||
/* 删除元素 */
|
/* 删除元素 */
|
||||||
remove(index) {
|
remove(index) {
|
||||||
if (index < 0 || index >= this.#size)
|
if (index < 0 || index >= this.#size) throw new Error('索引越界');
|
||||||
throw new Error('索引越界');
|
|
||||||
let num = this.#nums[index];
|
let num = this.#nums[index];
|
||||||
// 将索引 index 之后的元素都向前移动一位
|
// 将索引 index 之后的元素都向前移动一位
|
||||||
for (let j = index; j < this.#size - 1; j++) {
|
for (let j = index; j < this.#size - 1; j++) {
|
||||||
|
|
|
@ -7,16 +7,19 @@
|
||||||
/* 二分查找(双闭区间) */
|
/* 二分查找(双闭区间) */
|
||||||
function binarySearch(nums, target) {
|
function binarySearch(nums, target) {
|
||||||
// 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素
|
// 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素
|
||||||
let i = 0, j = nums.length - 1;
|
let i = 0,
|
||||||
|
j = nums.length - 1;
|
||||||
// 循环,当搜索区间为空时跳出(当 i > j 时为空)
|
// 循环,当搜索区间为空时跳出(当 i > j 时为空)
|
||||||
while (i <= j) {
|
while (i <= j) {
|
||||||
const m = parseInt((i + j) / 2); // 计算中点索引 m ,在 JS 中需使用 parseInt 函数取整
|
// 计算中点索引 m ,使用 parseInt() 向下取整
|
||||||
if (nums[m] < target) // 此情况说明 target 在区间 [m+1, j] 中
|
const m = parseInt((i + j) / 2);
|
||||||
|
if (nums[m] < target)
|
||||||
|
// 此情况说明 target 在区间 [m+1, j] 中
|
||||||
i = m + 1;
|
i = m + 1;
|
||||||
else if (nums[m] > target) // 此情况说明 target 在区间 [i, m-1] 中
|
else if (nums[m] > target)
|
||||||
|
// 此情况说明 target 在区间 [i, m-1] 中
|
||||||
j = m - 1;
|
j = m - 1;
|
||||||
else
|
else return m; // 找到目标元素,返回其索引
|
||||||
return m; // 找到目标元素,返回其索引
|
|
||||||
}
|
}
|
||||||
// 未找到目标元素,返回 -1
|
// 未找到目标元素,返回 -1
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -25,16 +28,20 @@ function binarySearch(nums, target) {
|
||||||
/* 二分查找(左闭右开) */
|
/* 二分查找(左闭右开) */
|
||||||
function binarySearch1(nums, target) {
|
function binarySearch1(nums, target) {
|
||||||
// 初始化左闭右开 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1
|
// 初始化左闭右开 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1
|
||||||
let i = 0, j = nums.length;
|
let i = 0,
|
||||||
|
j = nums.length;
|
||||||
// 循环,当搜索区间为空时跳出(当 i = j 时为空)
|
// 循环,当搜索区间为空时跳出(当 i = j 时为空)
|
||||||
while (i < j) {
|
while (i < j) {
|
||||||
const m = parseInt((i + j) / 2); // 计算中点索引 m ,在 JS 中需使用 parseInt 函数取整
|
// 计算中点索引 m ,使用 parseInt() 向下取整
|
||||||
if (nums[m] < target) // 此情况说明 target 在区间 [m+1, j) 中
|
const m = parseInt((i + j) / 2);
|
||||||
|
if (nums[m] < target)
|
||||||
|
// 此情况说明 target 在区间 [m+1, j) 中
|
||||||
i = m + 1;
|
i = m + 1;
|
||||||
else if (nums[m] > target) // 此情况说明 target 在区间 [i, m) 中
|
else if (nums[m] > target)
|
||||||
|
// 此情况说明 target 在区间 [i, m) 中
|
||||||
j = m;
|
j = m;
|
||||||
else // 找到目标元素,返回其索引
|
// 找到目标元素,返回其索引
|
||||||
return m;
|
else return m;
|
||||||
}
|
}
|
||||||
// 未找到目标元素,返回 -1
|
// 未找到目标元素,返回 -1
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -46,8 +53,8 @@ const nums = [1, 3, 6, 8, 12, 15, 23, 67, 70, 92];
|
||||||
|
|
||||||
/* 二分查找(双闭区间) */
|
/* 二分查找(双闭区间) */
|
||||||
let index = binarySearch(nums, target);
|
let index = binarySearch(nums, target);
|
||||||
console.log("目标元素 6 的索引 = " + index);
|
console.log('目标元素 6 的索引 = ' + index);
|
||||||
|
|
||||||
/* 二分查找(左闭右开) */
|
/* 二分查找(左闭右开) */
|
||||||
index = binarySearch1(nums, target);
|
index = binarySearch1(nums, target);
|
||||||
console.log("目标元素 6 的索引 = " + index);
|
console.log('目标元素 6 的索引 = ' + index);
|
||||||
|
|
|
@ -57,7 +57,9 @@ function linearRecur(n) {
|
||||||
/* 平方阶 */
|
/* 平方阶 */
|
||||||
function quadratic(n) {
|
function quadratic(n) {
|
||||||
// 矩阵占用 O(n^2) 空间
|
// 矩阵占用 O(n^2) 空间
|
||||||
const numMatrix = Array(n).fill(null).map(() => Array(n).fill(null));
|
const numMatrix = Array(n)
|
||||||
|
.fill(null)
|
||||||
|
.map(() => Array(n).fill(null));
|
||||||
// 二维列表占用 O(n^2) 空间
|
// 二维列表占用 O(n^2) 空间
|
||||||
const numList = [];
|
const numList = [];
|
||||||
for (let i = 0; i < n; i++) {
|
for (let i = 0; i < n; i++) {
|
||||||
|
|
|
@ -121,35 +121,35 @@ function factorialRecur(n) {
|
||||||
/* Driver Code */
|
/* Driver Code */
|
||||||
// 可以修改 n 运行,体会一下各种复杂度的操作数量变化趋势
|
// 可以修改 n 运行,体会一下各种复杂度的操作数量变化趋势
|
||||||
const n = 8;
|
const n = 8;
|
||||||
console.log("输入数据大小 n = " + n);
|
console.log('输入数据大小 n = ' + n);
|
||||||
|
|
||||||
let count = constant(n);
|
let count = constant(n);
|
||||||
console.log("常数阶的计算操作数量 = " + count);
|
console.log('常数阶的计算操作数量 = ' + count);
|
||||||
|
|
||||||
count = linear(n);
|
count = linear(n);
|
||||||
console.log("线性阶的计算操作数量 = " + count);
|
console.log('线性阶的计算操作数量 = ' + count);
|
||||||
count = arrayTraversal(new Array(n));
|
count = arrayTraversal(new Array(n));
|
||||||
console.log("线性阶(遍历数组)的计算操作数量 = " + count);
|
console.log('线性阶(遍历数组)的计算操作数量 = ' + count);
|
||||||
|
|
||||||
count = quadratic(n);
|
count = quadratic(n);
|
||||||
console.log("平方阶的计算操作数量 = " + count);
|
console.log('平方阶的计算操作数量 = ' + count);
|
||||||
let nums = new Array(n);
|
let nums = new Array(n);
|
||||||
for (let i = 0; i < n; i++) nums[i] = n - i; // [n,n-1,...,2,1]
|
for (let i = 0; i < n; i++) nums[i] = n - i; // [n,n-1,...,2,1]
|
||||||
count = bubbleSort(nums);
|
count = bubbleSort(nums);
|
||||||
console.log("平方阶(冒泡排序)的计算操作数量 = " + count);
|
console.log('平方阶(冒泡排序)的计算操作数量 = ' + count);
|
||||||
|
|
||||||
count = exponential(n);
|
count = exponential(n);
|
||||||
console.log("指数阶(循环实现)的计算操作数量 = " + count);
|
console.log('指数阶(循环实现)的计算操作数量 = ' + count);
|
||||||
count = expRecur(n);
|
count = expRecur(n);
|
||||||
console.log("指数阶(递归实现)的计算操作数量 = " + count);
|
console.log('指数阶(递归实现)的计算操作数量 = ' + count);
|
||||||
|
|
||||||
count = logarithmic(n);
|
count = logarithmic(n);
|
||||||
console.log("对数阶(循环实现)的计算操作数量 = " + count);
|
console.log('对数阶(循环实现)的计算操作数量 = ' + count);
|
||||||
count = logRecur(n);
|
count = logRecur(n);
|
||||||
console.log("对数阶(递归实现)的计算操作数量 = " + count);
|
console.log('对数阶(递归实现)的计算操作数量 = ' + count);
|
||||||
|
|
||||||
count = linearLogRecur(n);
|
count = linearLogRecur(n);
|
||||||
console.log("线性对数阶(递归实现)的计算操作数量 = " + count);
|
console.log('线性对数阶(递归实现)的计算操作数量 = ' + count);
|
||||||
|
|
||||||
count = factorialRecur(n);
|
count = factorialRecur(n);
|
||||||
console.log("阶乘阶(递归实现)的计算操作数量 = " + count);
|
console.log('阶乘阶(递归实现)的计算操作数量 = ' + count);
|
||||||
|
|
|
@ -38,8 +38,6 @@ for (let i = 0; i < 10; i++) {
|
||||||
const n = 100;
|
const n = 100;
|
||||||
const nums = randomNumbers(n);
|
const nums = randomNumbers(n);
|
||||||
const index = findOne(nums);
|
const index = findOne(nums);
|
||||||
console.log(
|
console.log('\n数组 [ 1, 2, ..., n ] 被打乱后 = [' + nums.join(', ') + ']');
|
||||||
"\n数组 [ 1, 2, ..., n ] 被打乱后 = [" + nums.join(", ") + "]"
|
console.log('数字 1 的索引为 ' + index);
|
||||||
);
|
|
||||||
console.log("数字 1 的索引为 " + index);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* Author: Justin (xiefahit@gmail.com)
|
* Author: Justin (xiefahit@gmail.com)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { Vertex } = require('../modules/Vertex')
|
const { Vertex } = require('../modules/Vertex');
|
||||||
|
|
||||||
/* 基于邻接表实现的无向图类 */
|
/* 基于邻接表实现的无向图类 */
|
||||||
class GraphAdjList {
|
class GraphAdjList {
|
||||||
|
@ -29,8 +29,12 @@ class GraphAdjList {
|
||||||
|
|
||||||
/* 添加边 */
|
/* 添加边 */
|
||||||
addEdge(vet1, vet2) {
|
addEdge(vet1, vet2) {
|
||||||
if (!this.adjList.has(vet1) || !this.adjList.has(vet2) || vet1 === vet2) {
|
if (
|
||||||
throw new Error("Illegal Argument Exception");
|
!this.adjList.has(vet1) ||
|
||||||
|
!this.adjList.has(vet2) ||
|
||||||
|
vet1 === vet2
|
||||||
|
) {
|
||||||
|
throw new Error('Illegal Argument Exception');
|
||||||
}
|
}
|
||||||
// 添加边 vet1 - vet2
|
// 添加边 vet1 - vet2
|
||||||
this.adjList.get(vet1).push(vet2);
|
this.adjList.get(vet1).push(vet2);
|
||||||
|
@ -39,8 +43,12 @@ class GraphAdjList {
|
||||||
|
|
||||||
/* 删除边 */
|
/* 删除边 */
|
||||||
removeEdge(vet1, vet2) {
|
removeEdge(vet1, vet2) {
|
||||||
if (!this.adjList.has(vet1) || !this.adjList.has(vet2) || vet1 === vet2) {
|
if (
|
||||||
throw new Error("Illegal Argument Exception");
|
!this.adjList.has(vet1) ||
|
||||||
|
!this.adjList.has(vet2) ||
|
||||||
|
vet1 === vet2
|
||||||
|
) {
|
||||||
|
throw new Error('Illegal Argument Exception');
|
||||||
}
|
}
|
||||||
// 删除边 vet1 - vet2
|
// 删除边 vet1 - vet2
|
||||||
this.adjList.get(vet1).splice(this.adjList.get(vet1).indexOf(vet2), 1);
|
this.adjList.get(vet1).splice(this.adjList.get(vet1).indexOf(vet2), 1);
|
||||||
|
@ -57,7 +65,7 @@ class GraphAdjList {
|
||||||
/* 删除顶点 */
|
/* 删除顶点 */
|
||||||
removeVertex(vet) {
|
removeVertex(vet) {
|
||||||
if (!this.adjList.has(vet)) {
|
if (!this.adjList.has(vet)) {
|
||||||
throw new Error("Illegal Argument Exception");
|
throw new Error('Illegal Argument Exception');
|
||||||
}
|
}
|
||||||
// 在邻接表中删除顶点 vet 对应的链表
|
// 在邻接表中删除顶点 vet 对应的链表
|
||||||
this.adjList.delete(vet);
|
this.adjList.delete(vet);
|
||||||
|
@ -72,13 +80,13 @@ class GraphAdjList {
|
||||||
|
|
||||||
/* 打印邻接表 */
|
/* 打印邻接表 */
|
||||||
print() {
|
print() {
|
||||||
console.log("邻接表 =");
|
console.log('邻接表 =');
|
||||||
for (const [key, value] of this.adjList) {
|
for (const [key, value] of this.adjList) {
|
||||||
const tmp = [];
|
const tmp = [];
|
||||||
for (const vertex of value) {
|
for (const vertex of value) {
|
||||||
tmp.push(vertex.val);
|
tmp.push(vertex.val);
|
||||||
}
|
}
|
||||||
console.log(key.val + ": " + tmp.join());
|
console.log(key.val + ': ' + tmp.join());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,37 +99,43 @@ if (require.main === module) {
|
||||||
v2 = new Vertex(2),
|
v2 = new Vertex(2),
|
||||||
v3 = new Vertex(5),
|
v3 = new Vertex(5),
|
||||||
v4 = new Vertex(4);
|
v4 = new Vertex(4);
|
||||||
const edges = [[v0, v1], [v1, v2], [v2, v3], [v0, v3], [v2, v4], [v3, v4]];
|
const edges = [
|
||||||
|
[v0, v1],
|
||||||
|
[v1, v2],
|
||||||
|
[v2, v3],
|
||||||
|
[v0, v3],
|
||||||
|
[v2, v4],
|
||||||
|
[v3, v4],
|
||||||
|
];
|
||||||
const graph = new GraphAdjList(edges);
|
const graph = new GraphAdjList(edges);
|
||||||
console.log("\n初始化后,图为");
|
console.log('\n初始化后,图为');
|
||||||
graph.print();
|
graph.print();
|
||||||
|
|
||||||
/* 添加边 */
|
/* 添加边 */
|
||||||
// 顶点 1, 2 即 v0, v2
|
// 顶点 1, 2 即 v0, v2
|
||||||
graph.addEdge(v0, v2);
|
graph.addEdge(v0, v2);
|
||||||
console.log("\n添加边 1-2 后,图为");
|
console.log('\n添加边 1-2 后,图为');
|
||||||
graph.print();
|
graph.print();
|
||||||
|
|
||||||
/* 删除边 */
|
/* 删除边 */
|
||||||
// 顶点 1, 3 即 v0, v1
|
// 顶点 1, 3 即 v0, v1
|
||||||
graph.removeEdge(v0, v1);
|
graph.removeEdge(v0, v1);
|
||||||
console.log("\n删除边 1-3 后,图为");
|
console.log('\n删除边 1-3 后,图为');
|
||||||
graph.print();
|
graph.print();
|
||||||
|
|
||||||
/* 添加顶点 */
|
/* 添加顶点 */
|
||||||
const v5 = new Vertex(6);
|
const v5 = new Vertex(6);
|
||||||
graph.addVertex(v5);
|
graph.addVertex(v5);
|
||||||
console.log("\n添加顶点 6 后,图为");
|
console.log('\n添加顶点 6 后,图为');
|
||||||
graph.print();
|
graph.print();
|
||||||
|
|
||||||
/* 删除顶点 */
|
/* 删除顶点 */
|
||||||
// 顶点 3 即 v1
|
// 顶点 3 即 v1
|
||||||
graph.removeVertex(v1);
|
graph.removeVertex(v1);
|
||||||
console.log("\n删除顶点 3 后,图为");
|
console.log('\n删除顶点 3 后,图为');
|
||||||
graph.print();
|
graph.print();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
GraphAdjList
|
GraphAdjList,
|
||||||
};
|
};
|
||||||
|
|
|
@ -49,7 +49,7 @@ class GraphAdjMat {
|
||||||
/* 删除顶点 */
|
/* 删除顶点 */
|
||||||
removeVertex(index) {
|
removeVertex(index) {
|
||||||
if (index >= this.size()) {
|
if (index >= this.size()) {
|
||||||
throw new RangeError("Index Out Of Bounds Exception");
|
throw new RangeError('Index Out Of Bounds Exception');
|
||||||
}
|
}
|
||||||
// 在顶点列表中移除索引 index 的顶点
|
// 在顶点列表中移除索引 index 的顶点
|
||||||
this.vertices.splice(index, 1);
|
this.vertices.splice(index, 1);
|
||||||
|
@ -67,7 +67,7 @@ class GraphAdjMat {
|
||||||
addEdge(i, j) {
|
addEdge(i, j) {
|
||||||
// 索引越界与相等处理
|
// 索引越界与相等处理
|
||||||
if (i < 0 || j < 0 || i >= this.size() || j >= this.size() || i === j) {
|
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)
|
// 在无向图中,邻接矩阵沿主对角线对称,即满足 (i, j) == (j, i)
|
||||||
this.adjMat[i][j] = 1;
|
this.adjMat[i][j] = 1;
|
||||||
|
@ -79,7 +79,7 @@ class GraphAdjMat {
|
||||||
removeEdge(i, j) {
|
removeEdge(i, j) {
|
||||||
// 索引越界与相等处理
|
// 索引越界与相等处理
|
||||||
if (i < 0 || j < 0 || i >= this.size() || j >= this.size() || i === j) {
|
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[i][j] = 0;
|
||||||
this.adjMat[j][i] = 0;
|
this.adjMat[j][i] = 0;
|
||||||
|
@ -87,8 +87,8 @@ class GraphAdjMat {
|
||||||
|
|
||||||
/* 打印邻接矩阵 */
|
/* 打印邻接矩阵 */
|
||||||
print() {
|
print() {
|
||||||
console.log("顶点列表 = ", this.vertices);
|
console.log('顶点列表 = ', this.vertices);
|
||||||
console.log("邻接矩阵 =", this.adjMat);
|
console.log('邻接矩阵 =', this.adjMat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,32 +96,37 @@ class GraphAdjMat {
|
||||||
/* 初始化无向图 */
|
/* 初始化无向图 */
|
||||||
// 请注意,edges 元素代表顶点索引,即对应 vertices 元素索引
|
// 请注意,edges 元素代表顶点索引,即对应 vertices 元素索引
|
||||||
const vertices = [1, 3, 2, 5, 4];
|
const vertices = [1, 3, 2, 5, 4];
|
||||||
const edges = [[0, 1], [1, 2], [2, 3], [0, 3], [2, 4], [3, 4]
|
const edges = [
|
||||||
|
[0, 1],
|
||||||
|
[1, 2],
|
||||||
|
[2, 3],
|
||||||
|
[0, 3],
|
||||||
|
[2, 4],
|
||||||
|
[3, 4],
|
||||||
];
|
];
|
||||||
const graph = new GraphAdjMat(vertices, edges);
|
const graph = new GraphAdjMat(vertices, edges);
|
||||||
console.log("\n初始化后,图为");
|
console.log('\n初始化后,图为');
|
||||||
graph.print();
|
graph.print();
|
||||||
|
|
||||||
/* 添加边 */
|
/* 添加边 */
|
||||||
// 顶点 1, 2 的索引分别为 0, 2
|
// 顶点 1, 2 的索引分别为 0, 2
|
||||||
graph.addEdge(0, 2);
|
graph.addEdge(0, 2);
|
||||||
console.log("\n添加边 1-2 后,图为");
|
console.log('\n添加边 1-2 后,图为');
|
||||||
graph.print();
|
graph.print();
|
||||||
|
|
||||||
/* 删除边 */
|
/* 删除边 */
|
||||||
// 顶点 1, 3 的索引分别为 0, 1
|
// 顶点 1, 3 的索引分别为 0, 1
|
||||||
graph.removeEdge(0, 1);
|
graph.removeEdge(0, 1);
|
||||||
console.log("\n删除边 1-3 后,图为");
|
console.log('\n删除边 1-3 后,图为');
|
||||||
graph.print();
|
graph.print();
|
||||||
|
|
||||||
/* 添加顶点 */
|
/* 添加顶点 */
|
||||||
graph.addVertex(6);
|
graph.addVertex(6);
|
||||||
console.log("\n添加顶点 6 后,图为");
|
console.log('\n添加顶点 6 后,图为');
|
||||||
graph.print();
|
graph.print();
|
||||||
|
|
||||||
/* 删除顶点 */
|
/* 删除顶点 */
|
||||||
// 顶点 3 的索引为 1
|
// 顶点 3 的索引为 1
|
||||||
graph.removeVertex(1);
|
graph.removeVertex(1);
|
||||||
console.log("\n删除顶点 3 后,图为");
|
console.log('\n删除顶点 3 后,图为');
|
||||||
graph.print();
|
graph.print();
|
||||||
|
|
||||||
|
|
|
@ -37,14 +37,25 @@ function graphBFS(graph, startVet) {
|
||||||
/* Driver Code */
|
/* Driver Code */
|
||||||
/* 初始化无向图 */
|
/* 初始化无向图 */
|
||||||
const v = Vertex.valsToVets([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
|
const v = Vertex.valsToVets([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
|
||||||
const edges = [[v[0], v[1]], [v[0], v[3]], [v[1], v[2]], [v[1], v[4]],
|
const edges = [
|
||||||
[v[2], v[5]], [v[3], v[4]], [v[3], v[6]], [v[4], v[5]],
|
[v[0], v[1]],
|
||||||
[v[4], v[7]], [v[5], v[8]], [v[6], v[7]], [v[7], v[8]]];
|
[v[0], v[3]],
|
||||||
|
[v[1], v[2]],
|
||||||
|
[v[1], v[4]],
|
||||||
|
[v[2], v[5]],
|
||||||
|
[v[3], v[4]],
|
||||||
|
[v[3], v[6]],
|
||||||
|
[v[4], v[5]],
|
||||||
|
[v[4], v[7]],
|
||||||
|
[v[5], v[8]],
|
||||||
|
[v[6], v[7]],
|
||||||
|
[v[7], v[8]],
|
||||||
|
];
|
||||||
const graph = new GraphAdjList(edges);
|
const graph = new GraphAdjList(edges);
|
||||||
console.log("\n初始化后,图为");
|
console.log('\n初始化后,图为');
|
||||||
graph.print();
|
graph.print();
|
||||||
|
|
||||||
/* 广度优先遍历 BFS */
|
/* 广度优先遍历 BFS */
|
||||||
const res = graphBFS(graph, v[0]);
|
const res = graphBFS(graph, v[0]);
|
||||||
console.log("\n广度优先遍历(BFS)顶点序列为");
|
console.log('\n广度优先遍历(BFS)顶点序列为');
|
||||||
console.log(Vertex.vetsToVals(res));
|
console.log(Vertex.vetsToVals(res));
|
||||||
|
|
|
@ -36,13 +36,19 @@ function graphDFS(graph, startVet) {
|
||||||
/* Driver Code */
|
/* Driver Code */
|
||||||
/* 初始化无向图 */
|
/* 初始化无向图 */
|
||||||
const v = Vertex.valsToVets([0, 1, 2, 3, 4, 5, 6]);
|
const v = Vertex.valsToVets([0, 1, 2, 3, 4, 5, 6]);
|
||||||
const edges = [[v[0], v[1]], [v[0], v[3]], [v[1], v[2]],
|
const edges = [
|
||||||
[v[2], v[5]], [v[4], v[5]], [v[5], v[6]]];
|
[v[0], v[1]],
|
||||||
|
[v[0], v[3]],
|
||||||
|
[v[1], v[2]],
|
||||||
|
[v[2], v[5]],
|
||||||
|
[v[4], v[5]],
|
||||||
|
[v[5], v[6]],
|
||||||
|
];
|
||||||
const graph = new GraphAdjList(edges);
|
const graph = new GraphAdjList(edges);
|
||||||
console.log("\n初始化后,图为");
|
console.log('\n初始化后,图为');
|
||||||
graph.print();
|
graph.print();
|
||||||
|
|
||||||
/* 深度优先遍历 DFS */
|
/* 深度优先遍历 DFS */
|
||||||
const res = graphDFS(graph, v[0]);
|
const res = graphDFS(graph, v[0]);
|
||||||
console.log("\n深度优先遍历(DFS)顶点序列为");
|
console.log('\n深度优先遍历(DFS)顶点序列为');
|
||||||
console.log(Vertex.vetsToVals(res));
|
console.log(Vertex.vetsToVals(res));
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* Author: what-is-me (whatisme@outlook.jp)
|
* Author: what-is-me (whatisme@outlook.jp)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { printHeap } = require("../modules/PrintUtil");
|
const { printHeap } = require('../modules/PrintUtil');
|
||||||
|
|
||||||
/* 最大堆类 */
|
/* 最大堆类 */
|
||||||
class MaxHeap {
|
class MaxHeap {
|
||||||
|
@ -84,7 +84,7 @@ class MaxHeap {
|
||||||
/* 元素出堆 */
|
/* 元素出堆 */
|
||||||
pop() {
|
pop() {
|
||||||
// 判空处理
|
// 判空处理
|
||||||
if (this.isEmpty()) throw new Error("堆为空");
|
if (this.isEmpty()) throw new Error('堆为空');
|
||||||
// 交换根节点与最右叶节点(即交换首元素与尾元素)
|
// 交换根节点与最右叶节点(即交换首元素与尾元素)
|
||||||
this.#swap(0, this.size() - 1);
|
this.#swap(0, this.size() - 1);
|
||||||
// 删除节点
|
// 删除节点
|
||||||
|
@ -122,7 +122,7 @@ class MaxHeap {
|
||||||
/* Driver Code */
|
/* Driver Code */
|
||||||
/* 初始化大顶堆 */
|
/* 初始化大顶堆 */
|
||||||
const maxHeap = new MaxHeap([9, 8, 6, 6, 7, 5, 2, 1, 4, 3, 6, 2]);
|
const maxHeap = new MaxHeap([9, 8, 6, 6, 7, 5, 2, 1, 4, 3, 6, 2]);
|
||||||
console.log("\n输入列表并建堆后");
|
console.log('\n输入列表并建堆后');
|
||||||
maxHeap.print();
|
maxHeap.print();
|
||||||
|
|
||||||
/* 获取堆顶元素 */
|
/* 获取堆顶元素 */
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* Author: Zhuo Qinyue (1403450829@qq.com)
|
* Author: Zhuo Qinyue (1403450829@qq.com)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { arrToLinkedList } = require("../modules/ListNode");
|
const { arrToLinkedList } = require('../modules/ListNode');
|
||||||
|
|
||||||
/* 哈希查找(数组) */
|
/* 哈希查找(数组) */
|
||||||
function hashingSearchArray(map, target) {
|
function hashingSearchArray(map, target) {
|
||||||
|
@ -31,10 +31,10 @@ for (let i = 0; i < nums.length; i++) {
|
||||||
map.set(nums[i], i); // key: 元素,value: 索引
|
map.set(nums[i], i); // key: 元素,value: 索引
|
||||||
}
|
}
|
||||||
const index = hashingSearchArray(map, target);
|
const index = hashingSearchArray(map, target);
|
||||||
console.log("目标元素 3 的索引 = " + index);
|
console.log('目标元素 3 的索引 = ' + index);
|
||||||
|
|
||||||
/* 哈希查找(链表) */
|
/* 哈希查找(链表) */
|
||||||
let head = arrToLinkedList(nums)
|
let head = arrToLinkedList(nums);
|
||||||
// 初始化哈希表
|
// 初始化哈希表
|
||||||
const map1 = new Map();
|
const map1 = new Map();
|
||||||
while (head != null) {
|
while (head != null) {
|
||||||
|
@ -42,4 +42,4 @@ while (head != null) {
|
||||||
head = head.next;
|
head = head.next;
|
||||||
}
|
}
|
||||||
const node = hashingSearchLinkedList(map1, target);
|
const node = hashingSearchLinkedList(map1, target);
|
||||||
console.log("目标节点值 3 的对应节点对象为", node);
|
console.log('目标节点值 3 的对应节点对象为', node);
|
||||||
|
|
|
@ -35,11 +35,12 @@ function twoSumHashTable(nums, target) {
|
||||||
|
|
||||||
/* Driver Code */
|
/* Driver Code */
|
||||||
// 方法一
|
// 方法一
|
||||||
const nums = [2, 7, 11, 15], target = 9;
|
const nums = [2, 7, 11, 15],
|
||||||
|
target = 9;
|
||||||
|
|
||||||
let res = twoSumBruteForce(nums, target);
|
let res = twoSumBruteForce(nums, target);
|
||||||
console.log("方法一 res = ", res);
|
console.log('方法一 res = ', res);
|
||||||
|
|
||||||
// 方法二
|
// 方法二
|
||||||
res = twoSumHashTable(nums, target);
|
res = twoSumHashTable(nums, target);
|
||||||
console.log("方法二 res = ", res);
|
console.log('方法二 res = ', res);
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* Author: JoseHung (szhong@link.cuhk.edu.hk)
|
* Author: JoseHung (szhong@link.cuhk.edu.hk)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { ListNode, arrToLinkedList } = require("../modules/ListNode");
|
const { ListNode, arrToLinkedList } = require('../modules/ListNode');
|
||||||
|
|
||||||
/* 线性查找(数组) */
|
/* 线性查找(数组) */
|
||||||
function linearSearchArray(nums, target) {
|
function linearSearchArray(nums, target) {
|
||||||
|
@ -39,9 +39,9 @@ const target = 3;
|
||||||
/* 在数组中执行线性查找 */
|
/* 在数组中执行线性查找 */
|
||||||
const nums = [1, 5, 3, 2, 4, 7, 5, 9, 10, 8];
|
const nums = [1, 5, 3, 2, 4, 7, 5, 9, 10, 8];
|
||||||
const index = linearSearchArray(nums, target);
|
const index = linearSearchArray(nums, target);
|
||||||
console.log("目标元素 3 的索引 = " + index);
|
console.log('目标元素 3 的索引 = ' + index);
|
||||||
|
|
||||||
/* 在链表中执行线性查找 */
|
/* 在链表中执行线性查找 */
|
||||||
const head = arrToLinkedList(nums);
|
const head = arrToLinkedList(nums);
|
||||||
const node = linearSearchLinkedList(head, target);
|
const node = linearSearchLinkedList(head, target);
|
||||||
console.log("目标节点值 3 的对应节点对象为 ", node);
|
console.log('目标节点值 3 的对应节点对象为 ', node);
|
||||||
|
|
|
@ -42,8 +42,8 @@ function bubbleSortWithFlag(nums) {
|
||||||
/* Driver Code */
|
/* Driver Code */
|
||||||
const nums = [4, 1, 3, 1, 5, 2];
|
const nums = [4, 1, 3, 1, 5, 2];
|
||||||
bubbleSort(nums);
|
bubbleSort(nums);
|
||||||
console.log("排序后数组 nums =", nums);
|
console.log('排序后数组 nums =', nums);
|
||||||
|
|
||||||
const nums1 = [4, 1, 3, 1, 5, 2];
|
const nums1 = [4, 1, 3, 1, 5, 2];
|
||||||
bubbleSortWithFlag(nums1);
|
bubbleSortWithFlag(nums1);
|
||||||
console.log("排序后数组 nums =", nums1);
|
console.log('排序后数组 nums =', nums1);
|
||||||
|
|
|
@ -8,7 +8,8 @@
|
||||||
function insertionSort(nums) {
|
function insertionSort(nums) {
|
||||||
// 外循环:base = nums[1], nums[2], ..., nums[n-1]
|
// 外循环:base = nums[1], nums[2], ..., nums[n-1]
|
||||||
for (let i = 1; i < nums.length; i++) {
|
for (let i = 1; i < nums.length; i++) {
|
||||||
let base = nums[i], j = i - 1;
|
let base = nums[i],
|
||||||
|
j = i - 1;
|
||||||
// 内循环:将 base 插入到左边的正确位置
|
// 内循环:将 base 插入到左边的正确位置
|
||||||
while (j >= 0 && nums[j] > base) {
|
while (j >= 0 && nums[j] > base) {
|
||||||
nums[j + 1] = nums[j]; // 1. 将 nums[j] 向右移动一位
|
nums[j + 1] = nums[j]; // 1. 将 nums[j] 向右移动一位
|
||||||
|
|
|
@ -11,21 +11,24 @@ function merge(nums, left, mid, right) {
|
||||||
// 初始化辅助数组
|
// 初始化辅助数组
|
||||||
let tmp = nums.slice(left, right + 1);
|
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 分别指向左子数组、右子数组的首元素
|
// i, j 分别指向左子数组、右子数组的首元素
|
||||||
let i = leftStart, j = rightStart;
|
let i = leftStart,
|
||||||
|
j = rightStart;
|
||||||
// 通过覆盖原数组 nums 来合并左子数组和右子数组
|
// 通过覆盖原数组 nums 来合并左子数组和右子数组
|
||||||
for (let k = left; k <= right; k++) {
|
for (let k = left; k <= right; k++) {
|
||||||
// 若“左子数组已全部合并完”,则选取右子数组元素,并且 j++
|
|
||||||
if (i > leftEnd) {
|
if (i > leftEnd) {
|
||||||
|
// 若“左子数组已全部合并完”,则选取右子数组元素,并且 j++
|
||||||
nums[k] = tmp[j++];
|
nums[k] = tmp[j++];
|
||||||
// 否则,若“右子数组已全部合并完”或“左子数组元素 <= 右子数组元素”,则选取左子数组元素,并且 i++
|
|
||||||
} else if (j > rightEnd || tmp[i] <= tmp[j]) {
|
} else if (j > rightEnd || tmp[i] <= tmp[j]) {
|
||||||
|
// 否则,若“右子数组已全部合并完”或“左子数组元素 <= 右子数组元素”,则选取左子数组元素,并且 i++
|
||||||
nums[k] = tmp[i++];
|
nums[k] = tmp[i++];
|
||||||
// 否则,若“左右子数组都未全部合并完”且“左子数组元素 > 右子数组元素”,则选取右子数组元素,并且 j++
|
|
||||||
} else {
|
} else {
|
||||||
|
// 否则,若“左右子数组都未全部合并完”且“左子数组元素 > 右子数组元素”,则选取右子数组元素,并且 j++
|
||||||
nums[k] = tmp[j++];
|
nums[k] = tmp[j++];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,8 @@ class QuickSort {
|
||||||
/* 哨兵划分 */
|
/* 哨兵划分 */
|
||||||
partition(nums, left, right) {
|
partition(nums, left, right) {
|
||||||
// 以 nums[left] 作为基准数
|
// 以 nums[left] 作为基准数
|
||||||
let i = left, j = right;
|
let i = left,
|
||||||
|
j = right;
|
||||||
while (i < j) {
|
while (i < j) {
|
||||||
while (i < j && nums[j] >= nums[left]) {
|
while (i < j && nums[j] >= nums[left]) {
|
||||||
j -= 1; // 从右向左找首个小于基准数的元素
|
j -= 1; // 从右向左找首个小于基准数的元素
|
||||||
|
@ -57,18 +58,25 @@ class QuickSortMedian {
|
||||||
// 此处使用异或运算来简化代码
|
// 此处使用异或运算来简化代码
|
||||||
// 异或规则为 0 ^ 0 = 1 ^ 1 = 0, 0 ^ 1 = 1 ^ 0 = 1
|
// 异或规则为 0 ^ 0 = 1 ^ 1 = 0, 0 ^ 1 = 1 ^ 0 = 1
|
||||||
if ((nums[left] < nums[mid]) ^ (nums[left] < nums[right])) return left;
|
if ((nums[left] < nums[mid]) ^ (nums[left] < nums[right])) return left;
|
||||||
else if ((nums[mid] < nums[left]) ^ (nums[mid] < nums[right])) return mid;
|
else if ((nums[mid] < nums[left]) ^ (nums[mid] < nums[right]))
|
||||||
|
return mid;
|
||||||
else return right;
|
else return right;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 哨兵划分(三数取中值) */
|
/* 哨兵划分(三数取中值) */
|
||||||
partition(nums, left, right) {
|
partition(nums, left, right) {
|
||||||
// 选取三个候选元素的中位数
|
// 选取三个候选元素的中位数
|
||||||
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);
|
this.swap(nums, left, med);
|
||||||
// 以 nums[left] 作为基准数
|
// 以 nums[left] 作为基准数
|
||||||
let i = left, j = right;
|
let i = left,
|
||||||
|
j = right;
|
||||||
while (i < j) {
|
while (i < j) {
|
||||||
while (i < j && nums[j] >= nums[left]) j--; // 从右向左找首个小于基准数的元素
|
while (i < j && nums[j] >= nums[left]) j--; // 从右向左找首个小于基准数的元素
|
||||||
while (i < j && nums[i] <= nums[left]) i++; // 从左向右找首个大于基准数的元素
|
while (i < j && nums[i] <= nums[left]) i++; // 从左向右找首个大于基准数的元素
|
||||||
|
@ -102,7 +110,8 @@ class QuickSortTailCall {
|
||||||
/* 哨兵划分 */
|
/* 哨兵划分 */
|
||||||
partition(nums, left, right) {
|
partition(nums, left, right) {
|
||||||
// 以 nums[left] 作为基准数
|
// 以 nums[left] 作为基准数
|
||||||
let i = left, j = right;
|
let i = left,
|
||||||
|
j = right;
|
||||||
while (i < j) {
|
while (i < j) {
|
||||||
while (i < j && nums[j] >= nums[left]) j--; // 从右向左找首个小于基准数的元素
|
while (i < j && nums[j] >= nums[left]) j--; // 从右向左找首个小于基准数的元素
|
||||||
while (i < j && nums[i] <= nums[left]) i++; // 从左向右找首个大于基准数的元素
|
while (i < j && nums[i] <= nums[left]) i++; // 从左向右找首个大于基准数的元素
|
||||||
|
|
|
@ -58,7 +58,9 @@ function radixSort(nums) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Driver Code */
|
/* Driver Code */
|
||||||
const nums = [10546151, 35663510, 42865989, 34862445, 81883077,
|
const nums = [
|
||||||
88906420, 72429244, 30524779, 82060337, 63832996];
|
10546151, 35663510, 42865989, 34862445, 81883077, 88906420, 72429244,
|
||||||
|
30524779, 82060337, 63832996,
|
||||||
|
];
|
||||||
radixSort(nums);
|
radixSort(nums);
|
||||||
console.log('基数排序完成后 nums =', nums);
|
console.log('基数排序完成后 nums =', nums);
|
||||||
|
|
|
@ -43,7 +43,7 @@ class ArrayDeque {
|
||||||
/* 队首入队 */
|
/* 队首入队 */
|
||||||
pushFirst(num) {
|
pushFirst(num) {
|
||||||
if (this.#queSize === this.capacity()) {
|
if (this.#queSize === this.capacity()) {
|
||||||
console.log("双向队列已满");
|
console.log('双向队列已满');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 队首指针向左移动一位
|
// 队首指针向左移动一位
|
||||||
|
@ -57,7 +57,7 @@ class ArrayDeque {
|
||||||
/* 队尾入队 */
|
/* 队尾入队 */
|
||||||
pushLast(num) {
|
pushLast(num) {
|
||||||
if (this.#queSize === this.capacity()) {
|
if (this.#queSize === this.capacity()) {
|
||||||
console.log("双向队列已满");
|
console.log('双向队列已满');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 计算尾指针,指向队尾索引 + 1
|
// 计算尾指针,指向队尾索引 + 1
|
||||||
|
@ -85,15 +85,13 @@ class ArrayDeque {
|
||||||
|
|
||||||
/* 访问队首元素 */
|
/* 访问队首元素 */
|
||||||
peekFirst() {
|
peekFirst() {
|
||||||
if (this.isEmpty())
|
if (this.isEmpty()) throw new Error('The Deque Is Empty.');
|
||||||
throw new Error("The Deque Is Empty.");
|
|
||||||
return this.#nums[this.#front];
|
return this.#nums[this.#front];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 访问队尾元素 */
|
/* 访问队尾元素 */
|
||||||
peekLast() {
|
peekLast() {
|
||||||
if (this.isEmpty())
|
if (this.isEmpty()) throw new Error('The Deque Is Empty.');
|
||||||
throw new Error("The Deque Is Empty.");
|
|
||||||
// 计算尾元素索引
|
// 计算尾元素索引
|
||||||
const last = this.index(this.#front + this.#queSize - 1);
|
const last = this.index(this.#front + this.#queSize - 1);
|
||||||
return this.#nums[last];
|
return this.#nums[last];
|
||||||
|
@ -117,30 +115,42 @@ const deque = new ArrayDeque(capacity);
|
||||||
deque.pushLast(3);
|
deque.pushLast(3);
|
||||||
deque.pushLast(2);
|
deque.pushLast(2);
|
||||||
deque.pushLast(5);
|
deque.pushLast(5);
|
||||||
console.log("双向队列 deque = [" + deque.toArray() + "]");
|
console.log('双向队列 deque = [' + deque.toArray() + ']');
|
||||||
|
|
||||||
/* 访问元素 */
|
/* 访问元素 */
|
||||||
const peekFirst = deque.peekFirst();
|
const peekFirst = deque.peekFirst();
|
||||||
console.log("队首元素 peekFirst = " + peekFirst);
|
console.log('队首元素 peekFirst = ' + peekFirst);
|
||||||
const peekLast = deque.peekLast();
|
const peekLast = deque.peekLast();
|
||||||
console.log("队尾元素 peekLast = " + peekLast);
|
console.log('队尾元素 peekLast = ' + peekLast);
|
||||||
|
|
||||||
/* 元素入队 */
|
/* 元素入队 */
|
||||||
deque.pushLast(4);
|
deque.pushLast(4);
|
||||||
console.log("元素 4 队尾入队后 deque = [" + deque.toArray() + "]");
|
console.log('元素 4 队尾入队后 deque = [' + deque.toArray() + ']');
|
||||||
deque.pushFirst(1);
|
deque.pushFirst(1);
|
||||||
console.log("元素 1 队首入队后 deque = [" + deque.toArray() + "]");
|
console.log('元素 1 队首入队后 deque = [' + deque.toArray() + ']');
|
||||||
|
|
||||||
/* 元素出队 */
|
/* 元素出队 */
|
||||||
const popLast = deque.popLast();
|
const popLast = deque.popLast();
|
||||||
console.log("队尾出队元素 = " + popLast + ",队尾出队后 deque = [" + deque.toArray() + "]");
|
console.log(
|
||||||
|
'队尾出队元素 = ' +
|
||||||
|
popLast +
|
||||||
|
',队尾出队后 deque = [' +
|
||||||
|
deque.toArray() +
|
||||||
|
']'
|
||||||
|
);
|
||||||
const popFirst = deque.popFirst();
|
const popFirst = deque.popFirst();
|
||||||
console.log("队首出队元素 = " + popFirst + ",队首出队后 deque = [" + deque.toArray()+ "]");
|
console.log(
|
||||||
|
'队首出队元素 = ' +
|
||||||
|
popFirst +
|
||||||
|
',队首出队后 deque = [' +
|
||||||
|
deque.toArray() +
|
||||||
|
']'
|
||||||
|
);
|
||||||
|
|
||||||
/* 获取双向队列的长度 */
|
/* 获取双向队列的长度 */
|
||||||
const size = deque.size();
|
const size = deque.size();
|
||||||
console.log("双向队列长度 size = " + size);
|
console.log('双向队列长度 size = ' + size);
|
||||||
|
|
||||||
/* 判断双向队列是否为空 */
|
/* 判断双向队列是否为空 */
|
||||||
const isEmpty = deque.isEmpty();
|
const isEmpty = deque.isEmpty();
|
||||||
console.log("双向队列是否为空 = " + isEmpty);
|
console.log('双向队列是否为空 = ' + isEmpty);
|
||||||
|
|
|
@ -32,7 +32,7 @@ class ArrayQueue {
|
||||||
/* 入队 */
|
/* 入队 */
|
||||||
push(num) {
|
push(num) {
|
||||||
if (this.size == this.capacity) {
|
if (this.size == this.capacity) {
|
||||||
console.log("队列已满");
|
console.log('队列已满');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 计算尾指针,指向队尾索引 + 1
|
// 计算尾指针,指向队尾索引 + 1
|
||||||
|
@ -54,8 +54,7 @@ class ArrayQueue {
|
||||||
|
|
||||||
/* 访问队首元素 */
|
/* 访问队首元素 */
|
||||||
peek() {
|
peek() {
|
||||||
if (this.empty())
|
if (this.empty()) throw new Error('队列为空');
|
||||||
throw new Error("队列为空");
|
|
||||||
return this.#nums[this.#front];
|
return this.#nums[this.#front];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +69,6 @@ class ArrayQueue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Driver Code */
|
/* Driver Code */
|
||||||
/* 初始化队列 */
|
/* 初始化队列 */
|
||||||
const capacity = 10;
|
const capacity = 10;
|
||||||
|
@ -82,27 +80,27 @@ queue.push(3);
|
||||||
queue.push(2);
|
queue.push(2);
|
||||||
queue.push(5);
|
queue.push(5);
|
||||||
queue.push(4);
|
queue.push(4);
|
||||||
console.log("队列 queue =", queue.toArray());
|
console.log('队列 queue =', queue.toArray());
|
||||||
|
|
||||||
/* 访问队首元素 */
|
/* 访问队首元素 */
|
||||||
const peek = queue.peek();
|
const peek = queue.peek();
|
||||||
console.log("队首元素 peek = " + peek);
|
console.log('队首元素 peek = ' + peek);
|
||||||
|
|
||||||
/* 元素出队 */
|
/* 元素出队 */
|
||||||
const pop = queue.pop();
|
const pop = queue.pop();
|
||||||
console.log("出队元素 pop = " + pop + ",出队后 queue =", queue.toArray());
|
console.log('出队元素 pop = ' + pop + ',出队后 queue =', queue.toArray());
|
||||||
|
|
||||||
/* 获取队列的长度 */
|
/* 获取队列的长度 */
|
||||||
const size = queue.size;
|
const size = queue.size;
|
||||||
console.log("队列长度 size = " + size);
|
console.log('队列长度 size = ' + size);
|
||||||
|
|
||||||
/* 判断队列是否为空 */
|
/* 判断队列是否为空 */
|
||||||
const empty = queue.empty();
|
const empty = queue.empty();
|
||||||
console.log("队列是否为空 = " + empty);
|
console.log('队列是否为空 = ' + empty);
|
||||||
|
|
||||||
/* 测试环形数组 */
|
/* 测试环形数组 */
|
||||||
for (let i = 0; i < 10; i++) {
|
for (let i = 0; i < 10; i++) {
|
||||||
queue.push(i);
|
queue.push(i);
|
||||||
queue.pop();
|
queue.pop();
|
||||||
console.log("第 " + i + " 轮入队 + 出队后 queue =", queue.toArray());
|
console.log('第 ' + i + ' 轮入队 + 出队后 queue =', queue.toArray());
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
* Author: S-N-O-R-L-A-X (snorlax.xu@outlook.com)
|
* Author: S-N-O-R-L-A-X (snorlax.xu@outlook.com)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* 基于数组实现的栈 */
|
/* 基于数组实现的栈 */
|
||||||
class ArrayStack {
|
class ArrayStack {
|
||||||
#stack;
|
#stack;
|
||||||
|
@ -29,15 +28,13 @@ class ArrayStack {
|
||||||
|
|
||||||
/* 出栈 */
|
/* 出栈 */
|
||||||
pop() {
|
pop() {
|
||||||
if (this.empty())
|
if (this.empty()) throw new Error('栈为空');
|
||||||
throw new Error("栈为空");
|
|
||||||
return this.#stack.pop();
|
return this.#stack.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 访问栈顶元素 */
|
/* 访问栈顶元素 */
|
||||||
top() {
|
top() {
|
||||||
if (this.empty())
|
if (this.empty()) throw new Error('栈为空');
|
||||||
throw new Error("栈为空");
|
|
||||||
return this.#stack[this.#stack.length - 1];
|
return this.#stack[this.#stack.length - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,8 +42,7 @@ class ArrayStack {
|
||||||
toArray() {
|
toArray() {
|
||||||
return this.#stack;
|
return this.#stack;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Driver Code */
|
/* Driver Code */
|
||||||
/* 初始化栈 */
|
/* 初始化栈 */
|
||||||
|
@ -58,22 +54,22 @@ stack.push(3);
|
||||||
stack.push(2);
|
stack.push(2);
|
||||||
stack.push(5);
|
stack.push(5);
|
||||||
stack.push(4);
|
stack.push(4);
|
||||||
console.log("栈 stack = ");
|
console.log('栈 stack = ');
|
||||||
console.log(stack.toArray());
|
console.log(stack.toArray());
|
||||||
|
|
||||||
/* 访问栈顶元素 */
|
/* 访问栈顶元素 */
|
||||||
const top = stack.top();
|
const top = stack.top();
|
||||||
console.log("栈顶元素 top = " + top);
|
console.log('栈顶元素 top = ' + top);
|
||||||
|
|
||||||
/* 元素出栈 */
|
/* 元素出栈 */
|
||||||
const pop = stack.pop();
|
const pop = stack.pop();
|
||||||
console.log("出栈元素 pop = " + pop + ",出栈后 stack = ");
|
console.log('出栈元素 pop = ' + pop + ',出栈后 stack = ');
|
||||||
console.log(stack.toArray());
|
console.log(stack.toArray());
|
||||||
|
|
||||||
/* 获取栈的长度 */
|
/* 获取栈的长度 */
|
||||||
const size = stack.size;
|
const size = stack.size;
|
||||||
console.log("栈的长度 size = " + size);
|
console.log('栈的长度 size = ' + size);
|
||||||
|
|
||||||
/* 判断是否为空 */
|
/* 判断是否为空 */
|
||||||
const empty = stack.empty();
|
const empty = stack.empty();
|
||||||
console.log("栈是否为空 = " + empty);
|
console.log('栈是否为空 = ' + empty);
|
||||||
|
|
|
@ -16,25 +16,29 @@ deque.push(4);
|
||||||
// 请注意,由于是数组,unshift() 方法的时间复杂度为 O(n)
|
// 请注意,由于是数组,unshift() 方法的时间复杂度为 O(n)
|
||||||
deque.unshift(3);
|
deque.unshift(3);
|
||||||
deque.unshift(1);
|
deque.unshift(1);
|
||||||
console.log("双向队列 deque = ", deque);
|
console.log('双向队列 deque = ', deque);
|
||||||
|
|
||||||
/* 访问元素 */
|
/* 访问元素 */
|
||||||
const peekFirst = deque[0];
|
const peekFirst = deque[0];
|
||||||
console.log("队首元素 peekFirst = " + peekFirst);
|
console.log('队首元素 peekFirst = ' + peekFirst);
|
||||||
const peekLast = deque[deque.length - 1];
|
const peekLast = deque[deque.length - 1];
|
||||||
console.log("队尾元素 peekLast = " + peekLast);
|
console.log('队尾元素 peekLast = ' + peekLast);
|
||||||
|
|
||||||
/* 元素出队 */
|
/* 元素出队 */
|
||||||
// 请注意,由于是数组,shift() 方法的时间复杂度为 O(n)
|
// 请注意,由于是数组,shift() 方法的时间复杂度为 O(n)
|
||||||
const popFront = deque.shift();
|
const popFront = deque.shift();
|
||||||
console.log("队首出队元素 popFront = " + popFront + ",队首出队后 deque = " + deque);
|
console.log(
|
||||||
|
'队首出队元素 popFront = ' + popFront + ',队首出队后 deque = ' + deque
|
||||||
|
);
|
||||||
const popBack = deque.pop();
|
const popBack = deque.pop();
|
||||||
console.log("队尾出队元素 popBack = " + popBack + ",队尾出队后 deque = " + deque);
|
console.log(
|
||||||
|
'队尾出队元素 popBack = ' + popBack + ',队尾出队后 deque = ' + deque
|
||||||
|
);
|
||||||
|
|
||||||
/* 获取双向队列的长度 */
|
/* 获取双向队列的长度 */
|
||||||
const size = deque.length;
|
const size = deque.length;
|
||||||
console.log("双向队列长度 size = " + size);
|
console.log('双向队列长度 size = ' + size);
|
||||||
|
|
||||||
/* 判断双向队列是否为空 */
|
/* 判断双向队列是否为空 */
|
||||||
const isEmpty = size === 0;
|
const isEmpty = size === 0;
|
||||||
console.log("双向队列是否为空 = " + isEmpty);
|
console.log('双向队列是否为空 = ' + isEmpty);
|
||||||
|
|
|
@ -123,7 +123,7 @@ class LinkedListDeque {
|
||||||
arr.push(temp.val);
|
arr.push(temp.val);
|
||||||
temp = temp.next;
|
temp = temp.next;
|
||||||
}
|
}
|
||||||
console.log("[" + arr.join(", ") + "]");
|
console.log('[' + arr.join(', ') + ']');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,35 +133,35 @@ const linkedListDeque = new LinkedListDeque();
|
||||||
linkedListDeque.pushLast(3);
|
linkedListDeque.pushLast(3);
|
||||||
linkedListDeque.pushLast(2);
|
linkedListDeque.pushLast(2);
|
||||||
linkedListDeque.pushLast(5);
|
linkedListDeque.pushLast(5);
|
||||||
console.log("双向队列 linkedListDeque = ");
|
console.log('双向队列 linkedListDeque = ');
|
||||||
linkedListDeque.print();
|
linkedListDeque.print();
|
||||||
|
|
||||||
/* 访问元素 */
|
/* 访问元素 */
|
||||||
const peekFirst = linkedListDeque.peekFirst();
|
const peekFirst = linkedListDeque.peekFirst();
|
||||||
console.log("队首元素 peekFirst = " + peekFirst);
|
console.log('队首元素 peekFirst = ' + peekFirst);
|
||||||
const peekLast = linkedListDeque.peekLast();
|
const peekLast = linkedListDeque.peekLast();
|
||||||
console.log("队尾元素 peekLast = " + peekLast);
|
console.log('队尾元素 peekLast = ' + peekLast);
|
||||||
|
|
||||||
/* 元素入队 */
|
/* 元素入队 */
|
||||||
linkedListDeque.pushLast(4);
|
linkedListDeque.pushLast(4);
|
||||||
console.log("元素 4 队尾入队后 linkedListDeque = ");
|
console.log('元素 4 队尾入队后 linkedListDeque = ');
|
||||||
linkedListDeque.print();
|
linkedListDeque.print();
|
||||||
linkedListDeque.pushFirst(1);
|
linkedListDeque.pushFirst(1);
|
||||||
console.log("元素 1 队首入队后 linkedListDeque = ");
|
console.log('元素 1 队首入队后 linkedListDeque = ');
|
||||||
linkedListDeque.print();
|
linkedListDeque.print();
|
||||||
|
|
||||||
/* 元素出队 */
|
/* 元素出队 */
|
||||||
const popLast = linkedListDeque.popLast();
|
const popLast = linkedListDeque.popLast();
|
||||||
console.log("队尾出队元素 = " + popLast + ",队尾出队后 linkedListDeque = ");
|
console.log('队尾出队元素 = ' + popLast + ',队尾出队后 linkedListDeque = ');
|
||||||
linkedListDeque.print();
|
linkedListDeque.print();
|
||||||
const popFirst = linkedListDeque.popFirst();
|
const popFirst = linkedListDeque.popFirst();
|
||||||
console.log("队首出队元素 = " + popFirst + ",队首出队后 linkedListDeque = ");
|
console.log('队首出队元素 = ' + popFirst + ',队首出队后 linkedListDeque = ');
|
||||||
linkedListDeque.print();
|
linkedListDeque.print();
|
||||||
|
|
||||||
/* 获取双向队列的长度 */
|
/* 获取双向队列的长度 */
|
||||||
const size = linkedListDeque.size();
|
const size = linkedListDeque.size();
|
||||||
console.log("双向队列长度 size = " + size);
|
console.log('双向队列长度 size = ' + size);
|
||||||
|
|
||||||
/* 判断双向队列是否为空 */
|
/* 判断双向队列是否为空 */
|
||||||
const isEmpty = linkedListDeque.isEmpty();
|
const isEmpty = linkedListDeque.isEmpty();
|
||||||
console.log("双向队列是否为空 = " + isEmpty);
|
console.log('双向队列是否为空 = ' + isEmpty);
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* Author: S-N-O-R-L-A-X (snorlax.xu@outlook.com)
|
* Author: S-N-O-R-L-A-X (snorlax.xu@outlook.com)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { ListNode } = require("../modules/ListNode");
|
const { ListNode } = require('../modules/ListNode');
|
||||||
|
|
||||||
/* 基于链表实现的队列 */
|
/* 基于链表实现的队列 */
|
||||||
class LinkedListQueue {
|
class LinkedListQueue {
|
||||||
|
@ -54,8 +54,7 @@ class LinkedListQueue {
|
||||||
|
|
||||||
/* 访问队首元素 */
|
/* 访问队首元素 */
|
||||||
peek() {
|
peek() {
|
||||||
if (this.size === 0)
|
if (this.size === 0) throw new Error('队列为空');
|
||||||
throw new Error("队列为空");
|
|
||||||
return this.#front.val;
|
return this.#front.val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,8 +70,6 @@ class LinkedListQueue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Driver Code */
|
/* Driver Code */
|
||||||
/* 初始化队列 */
|
/* 初始化队列 */
|
||||||
const queue = new LinkedListQueue();
|
const queue = new LinkedListQueue();
|
||||||
|
@ -83,20 +80,20 @@ queue.push(3);
|
||||||
queue.push(2);
|
queue.push(2);
|
||||||
queue.push(5);
|
queue.push(5);
|
||||||
queue.push(4);
|
queue.push(4);
|
||||||
console.log("队列 queue = " + queue.toArray());
|
console.log('队列 queue = ' + queue.toArray());
|
||||||
|
|
||||||
/* 访问队首元素 */
|
/* 访问队首元素 */
|
||||||
const peek = queue.peek();
|
const peek = queue.peek();
|
||||||
console.log("队首元素 peek = " + peek);
|
console.log('队首元素 peek = ' + peek);
|
||||||
|
|
||||||
/* 元素出队 */
|
/* 元素出队 */
|
||||||
const pop = queue.pop();
|
const pop = queue.pop();
|
||||||
console.log("出队元素 pop = " + pop + ",出队后 queue = " + queue.toArray());
|
console.log('出队元素 pop = ' + pop + ',出队后 queue = ' + queue.toArray());
|
||||||
|
|
||||||
/* 获取队列的长度 */
|
/* 获取队列的长度 */
|
||||||
const size = queue.size;
|
const size = queue.size;
|
||||||
console.log("队列长度 size = " + size);
|
console.log('队列长度 size = ' + size);
|
||||||
|
|
||||||
/* 判断队列是否为空 */
|
/* 判断队列是否为空 */
|
||||||
const isEmpty = queue.isEmpty();
|
const isEmpty = queue.isEmpty();
|
||||||
console.log("队列是否为空 = " + isEmpty);
|
console.log('队列是否为空 = ' + isEmpty);
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* Author: S-N-O-R-L-A-X (snorlax.xu@outlook.com)
|
* Author: S-N-O-R-L-A-X (snorlax.xu@outlook.com)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { ListNode } = require("../modules/ListNode");
|
const { ListNode } = require('../modules/ListNode');
|
||||||
|
|
||||||
/* 基于链表实现的栈 */
|
/* 基于链表实现的栈 */
|
||||||
class LinkedListStack {
|
class LinkedListStack {
|
||||||
|
@ -43,8 +43,7 @@ class LinkedListStack {
|
||||||
|
|
||||||
/* 访问栈顶元素 */
|
/* 访问栈顶元素 */
|
||||||
peek() {
|
peek() {
|
||||||
if (!this.#stackPeek)
|
if (!this.#stackPeek) throw new Error('栈为空');
|
||||||
throw new Error("栈为空");
|
|
||||||
return this.#stackPeek.val;
|
return this.#stackPeek.val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,20 +69,20 @@ stack.push(3);
|
||||||
stack.push(2);
|
stack.push(2);
|
||||||
stack.push(5);
|
stack.push(5);
|
||||||
stack.push(4);
|
stack.push(4);
|
||||||
console.log("栈 stack = " + stack.toArray());
|
console.log('栈 stack = ' + stack.toArray());
|
||||||
|
|
||||||
/* 访问栈顶元素 */
|
/* 访问栈顶元素 */
|
||||||
const peek = stack.peek();
|
const peek = stack.peek();
|
||||||
console.log("栈顶元素 peek = " + peek);
|
console.log('栈顶元素 peek = ' + peek);
|
||||||
|
|
||||||
/* 元素出栈 */
|
/* 元素出栈 */
|
||||||
const pop = stack.pop();
|
const pop = stack.pop();
|
||||||
console.log("出栈元素 pop = " + pop + ",出栈后 stack = " + stack.toArray());
|
console.log('出栈元素 pop = ' + pop + ',出栈后 stack = ' + stack.toArray());
|
||||||
|
|
||||||
/* 获取栈的长度 */
|
/* 获取栈的长度 */
|
||||||
const size = stack.size;
|
const size = stack.size;
|
||||||
console.log("栈的长度 size = " + size);
|
console.log('栈的长度 size = ' + size);
|
||||||
|
|
||||||
/* 判断是否为空 */
|
/* 判断是否为空 */
|
||||||
const isEmpty = stack.isEmpty();
|
const isEmpty = stack.isEmpty();
|
||||||
console.log("栈是否为空 = " + isEmpty);
|
console.log('栈是否为空 = ' + isEmpty);
|
||||||
|
|
|
@ -15,21 +15,21 @@ queue.push(3);
|
||||||
queue.push(2);
|
queue.push(2);
|
||||||
queue.push(5);
|
queue.push(5);
|
||||||
queue.push(4);
|
queue.push(4);
|
||||||
console.log("队列 queue =", queue);
|
console.log('队列 queue =', queue);
|
||||||
|
|
||||||
/* 访问队首元素 */
|
/* 访问队首元素 */
|
||||||
const peek = queue[0];
|
const peek = queue[0];
|
||||||
console.log("队首元素 peek =", peek);
|
console.log('队首元素 peek =', peek);
|
||||||
|
|
||||||
/* 元素出队 */
|
/* 元素出队 */
|
||||||
// 底层是数组,因此 shift() 方法的时间复杂度为 O(n)
|
// 底层是数组,因此 shift() 方法的时间复杂度为 O(n)
|
||||||
const pop = queue.shift();
|
const pop = queue.shift();
|
||||||
console.log("出队元素 pop =", pop, ",出队后 queue = ", queue);
|
console.log('出队元素 pop =', pop, ',出队后 queue = ', queue);
|
||||||
|
|
||||||
/* 获取队列的长度 */
|
/* 获取队列的长度 */
|
||||||
const size = queue.length;
|
const size = queue.length;
|
||||||
console.log("队列长度 size =", size);
|
console.log('队列长度 size =', size);
|
||||||
|
|
||||||
/* 判断队列是否为空 */
|
/* 判断队列是否为空 */
|
||||||
const isEmpty = queue.length === 0;
|
const isEmpty = queue.length === 0;
|
||||||
console.log("队列是否为空 = ", isEmpty);
|
console.log('队列是否为空 = ', isEmpty);
|
||||||
|
|
|
@ -15,21 +15,21 @@ stack.push(3);
|
||||||
stack.push(2);
|
stack.push(2);
|
||||||
stack.push(5);
|
stack.push(5);
|
||||||
stack.push(4);
|
stack.push(4);
|
||||||
console.log("栈 stack =", stack);
|
console.log('栈 stack =', stack);
|
||||||
|
|
||||||
/* 访问栈顶元素 */
|
/* 访问栈顶元素 */
|
||||||
const peek = stack[stack.length - 1];
|
const peek = stack[stack.length - 1];
|
||||||
console.log("栈顶元素 peek =", peek);
|
console.log('栈顶元素 peek =', peek);
|
||||||
|
|
||||||
/* 元素出栈 */
|
/* 元素出栈 */
|
||||||
const pop = stack.pop();
|
const pop = stack.pop();
|
||||||
console.log("出栈元素 pop =", pop);
|
console.log('出栈元素 pop =', pop);
|
||||||
console.log("出栈后 stack =", stack);
|
console.log('出栈后 stack =', stack);
|
||||||
|
|
||||||
/* 获取栈的长度 */
|
/* 获取栈的长度 */
|
||||||
const size = stack.length;
|
const size = stack.length;
|
||||||
console.log("栈的长度 size =", size);
|
console.log('栈的长度 size =', size);
|
||||||
|
|
||||||
/* 判断是否为空 */
|
/* 判断是否为空 */
|
||||||
const isEmpty = stack.length === 0;
|
const isEmpty = stack.length === 0;
|
||||||
console.log("栈是否为空 =", isEmpty);
|
console.log('栈是否为空 =', isEmpty);
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
* Author: what-is-me (whatisme@outlook.jp)
|
* Author: what-is-me (whatisme@outlook.jp)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { TreeNode } = require("../modules/TreeNode");
|
const { TreeNode } = require('../modules/TreeNode');
|
||||||
const { printTree } = require("../modules/PrintUtil");
|
const { printTree } = require('../modules/PrintUtil');
|
||||||
|
|
||||||
/* AVL 树*/
|
/* AVL 树*/
|
||||||
class AVLTree {
|
class AVLTree {
|
||||||
|
@ -23,7 +23,8 @@ class AVLTree {
|
||||||
/* 更新节点高度 */
|
/* 更新节点高度 */
|
||||||
#updateHeight(node) {
|
#updateHeight(node) {
|
||||||
// 节点高度等于最高子树高度 + 1
|
// 节点高度等于最高子树高度 + 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 获取平衡因子 */
|
/* 获取平衡因子 */
|
||||||
|
@ -102,7 +103,8 @@ class AVLTree {
|
||||||
if (node === null) return new TreeNode(val);
|
if (node === null) return new TreeNode(val);
|
||||||
/* 1. 查找插入位置,并插入节点 */
|
/* 1. 查找插入位置,并插入节点 */
|
||||||
if (val < node.val) node.left = this.#insertHelper(node.left, val);
|
if (val < node.val) node.left = this.#insertHelper(node.left, val);
|
||||||
else if (val > node.val) node.right = this.#insertHelper(node.right, val);
|
else if (val > node.val)
|
||||||
|
node.right = this.#insertHelper(node.right, val);
|
||||||
else return node; // 重复节点不插入,直接返回
|
else return node; // 重复节点不插入,直接返回
|
||||||
this.#updateHeight(node); // 更新节点高度
|
this.#updateHeight(node); // 更新节点高度
|
||||||
/* 2. 执行旋转操作,使该子树重新恢复平衡 */
|
/* 2. 执行旋转操作,使该子树重新恢复平衡 */
|
||||||
|
@ -121,7 +123,8 @@ class AVLTree {
|
||||||
if (node === null) return null;
|
if (node === null) return null;
|
||||||
/* 1. 查找节点,并删除之 */
|
/* 1. 查找节点,并删除之 */
|
||||||
if (val < node.val) node.left = this.#removeHelper(node.left, val);
|
if (val < node.val) node.left = this.#removeHelper(node.left, val);
|
||||||
else if (val > node.val) node.right = this.#removeHelper(node.right, val);
|
else if (val > node.val)
|
||||||
|
node.right = this.#removeHelper(node.right, val);
|
||||||
else {
|
else {
|
||||||
if (node.left === null || node.right === null) {
|
if (node.left === null || node.right === null) {
|
||||||
const child = node.left !== null ? node.left : node.right;
|
const child = node.left !== null ? node.left : node.right;
|
||||||
|
@ -165,13 +168,13 @@ class AVLTree {
|
||||||
|
|
||||||
function testInsert(tree, val) {
|
function testInsert(tree, val) {
|
||||||
tree.insert(val);
|
tree.insert(val);
|
||||||
console.log("\n插入节点 " + val + " 后,AVL 树为");
|
console.log('\n插入节点 ' + val + ' 后,AVL 树为');
|
||||||
printTree(tree.root);
|
printTree(tree.root);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testRemove(tree, val) {
|
function testRemove(tree, val) {
|
||||||
tree.remove(val);
|
tree.remove(val);
|
||||||
console.log("\n删除节点 " + val + " 后,AVL 树为");
|
console.log('\n删除节点 ' + val + ' 后,AVL 树为');
|
||||||
printTree(tree.root);
|
printTree(tree.root);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,4 +205,4 @@ testRemove(avlTree, 4); // 删除度为 2 的节点
|
||||||
|
|
||||||
/* 查询节点 */
|
/* 查询节点 */
|
||||||
const node = avlTree.search(7);
|
const node = avlTree.search(7);
|
||||||
console.log("\n查找到的节点对象为", node, ",节点值 = " + node.val);
|
console.log('\n查找到的节点对象为', node, ',节点值 = ' + node.val);
|
||||||
|
|
|
@ -4,14 +4,16 @@
|
||||||
* Author: IsChristina (christinaxia77@foxmail.com)
|
* Author: IsChristina (christinaxia77@foxmail.com)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { TreeNode } = require("../modules/TreeNode");
|
const { TreeNode } = require('../modules/TreeNode');
|
||||||
const { printTree } = require("../modules/PrintUtil");
|
const { printTree } = require('../modules/PrintUtil');
|
||||||
|
|
||||||
/* 二叉搜索树 */
|
/* 二叉搜索树 */
|
||||||
let root;
|
let root;
|
||||||
|
|
||||||
function BinarySearchTree(nums) {
|
function BinarySearchTree(nums) {
|
||||||
nums.sort((a, b) => { return a - b }); // 排序数组
|
nums.sort((a, b) => {
|
||||||
|
return a - b;
|
||||||
|
}); // 排序数组
|
||||||
root = buildTree(nums, 0, nums.length - 1); // 构建二叉搜索树
|
root = buildTree(nums, 0, nums.length - 1); // 构建二叉搜索树
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +54,8 @@ function search(num) {
|
||||||
function insert(num) {
|
function insert(num) {
|
||||||
// 若树为空,直接提前返回
|
// 若树为空,直接提前返回
|
||||||
if (root === null) return;
|
if (root === null) return;
|
||||||
let cur = root, pre = null;
|
let cur = root,
|
||||||
|
pre = null;
|
||||||
// 循环查找,越过叶节点后跳出
|
// 循环查找,越过叶节点后跳出
|
||||||
while (cur !== null) {
|
while (cur !== null) {
|
||||||
// 找到重复节点,直接返回
|
// 找到重复节点,直接返回
|
||||||
|
@ -73,7 +76,8 @@ function insert(num) {
|
||||||
function remove(num) {
|
function remove(num) {
|
||||||
// 若树为空,直接提前返回
|
// 若树为空,直接提前返回
|
||||||
if (root === null) return;
|
if (root === null) return;
|
||||||
let cur = root, pre = null;
|
let cur = root,
|
||||||
|
pre = null;
|
||||||
// 循环查找,越过叶节点后跳出
|
// 循环查找,越过叶节点后跳出
|
||||||
while (cur !== null) {
|
while (cur !== null) {
|
||||||
// 找到待删除节点,跳出循环
|
// 找到待删除节点,跳出循环
|
||||||
|
@ -112,25 +116,25 @@ function remove(num) {
|
||||||
/* 初始化二叉搜索树 */
|
/* 初始化二叉搜索树 */
|
||||||
const nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
|
const nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
|
||||||
BinarySearchTree(nums);
|
BinarySearchTree(nums);
|
||||||
console.log("\n初始化的二叉树为\n");
|
console.log('\n初始化的二叉树为\n');
|
||||||
printTree(getRoot());
|
printTree(getRoot());
|
||||||
|
|
||||||
/* 查找节点 */
|
/* 查找节点 */
|
||||||
let node = search(7);
|
let node = search(7);
|
||||||
console.log("\n查找到的节点对象为 " + node + ",节点值 = " + node.val);
|
console.log('\n查找到的节点对象为 ' + node + ',节点值 = ' + node.val);
|
||||||
|
|
||||||
/* 插入节点 */
|
/* 插入节点 */
|
||||||
insert(16);
|
insert(16);
|
||||||
console.log("\n插入节点 16 后,二叉树为\n");
|
console.log('\n插入节点 16 后,二叉树为\n');
|
||||||
printTree(getRoot());
|
printTree(getRoot());
|
||||||
|
|
||||||
/* 删除节点 */
|
/* 删除节点 */
|
||||||
remove(1);
|
remove(1);
|
||||||
console.log("\n删除节点 1 后,二叉树为\n");
|
console.log('\n删除节点 1 后,二叉树为\n');
|
||||||
printTree(getRoot());
|
printTree(getRoot());
|
||||||
remove(2);
|
remove(2);
|
||||||
console.log("\n删除节点 2 后,二叉树为\n");
|
console.log('\n删除节点 2 后,二叉树为\n');
|
||||||
printTree(getRoot());
|
printTree(getRoot());
|
||||||
remove(4);
|
remove(4);
|
||||||
console.log("\n删除节点 4 后,二叉树为\n");
|
console.log('\n删除节点 4 后,二叉树为\n');
|
||||||
printTree(getRoot());
|
printTree(getRoot());
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
* Author: IsChristina (christinaxia77@foxmail.com)
|
* Author: IsChristina (christinaxia77@foxmail.com)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { TreeNode } = require("../modules/TreeNode");
|
const { TreeNode } = require('../modules/TreeNode');
|
||||||
const { printTree } = require("../modules/PrintUtil");
|
const { printTree } = require('../modules/PrintUtil');
|
||||||
|
|
||||||
/* 初始化二叉树 */
|
/* 初始化二叉树 */
|
||||||
// 初始化节点
|
// 初始化节点
|
||||||
|
@ -19,7 +19,7 @@ n1.left = n2;
|
||||||
n1.right = n3;
|
n1.right = n3;
|
||||||
n2.left = n4;
|
n2.left = n4;
|
||||||
n2.right = n5;
|
n2.right = n5;
|
||||||
console.log("\n初始化二叉树\n");
|
console.log('\n初始化二叉树\n');
|
||||||
printTree(n1);
|
printTree(n1);
|
||||||
|
|
||||||
/* 插入与删除节点 */
|
/* 插入与删除节点 */
|
||||||
|
@ -27,9 +27,9 @@ const P = new TreeNode(0);
|
||||||
// 在 n1 -> n2 中间插入节点 P
|
// 在 n1 -> n2 中间插入节点 P
|
||||||
n1.left = P;
|
n1.left = P;
|
||||||
P.left = n2;
|
P.left = n2;
|
||||||
console.log("\n插入节点 P 后\n");
|
console.log('\n插入节点 P 后\n');
|
||||||
printTree(n1);
|
printTree(n1);
|
||||||
// 删除节点 P
|
// 删除节点 P
|
||||||
n1.left = n2;
|
n1.left = n2;
|
||||||
console.log("\n删除节点 P 后\n");
|
console.log('\n删除节点 P 后\n');
|
||||||
printTree(n1);
|
printTree(n1);
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
* Author: IsChristina (christinaxia77@foxmail.com)
|
* Author: IsChristina (christinaxia77@foxmail.com)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { arrToTree } = require("../modules/TreeNode");
|
const { arrToTree } = require('../modules/TreeNode');
|
||||||
const { printTree } = require("../modules/PrintUtil");
|
const { printTree } = require('../modules/PrintUtil');
|
||||||
|
|
||||||
/* 层序遍历 */
|
/* 层序遍历 */
|
||||||
function levelOrder(root) {
|
function levelOrder(root) {
|
||||||
|
@ -16,11 +16,8 @@ function levelOrder(root) {
|
||||||
while (queue.length) {
|
while (queue.length) {
|
||||||
let node = queue.shift(); // 队列出队
|
let node = queue.shift(); // 队列出队
|
||||||
list.push(node.val); // 保存节点值
|
list.push(node.val); // 保存节点值
|
||||||
if (node.left)
|
if (node.left) queue.push(node.left); // 左子节点入队
|
||||||
queue.push(node.left); // 左子节点入队
|
if (node.right) queue.push(node.right); // 右子节点入队
|
||||||
if (node.right)
|
|
||||||
queue.push(node.right); // 右子节点入队
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
@ -29,9 +26,9 @@ function levelOrder(root) {
|
||||||
/* 初始化二叉树 */
|
/* 初始化二叉树 */
|
||||||
// 这里借助了一个从数组直接生成二叉树的函数
|
// 这里借助了一个从数组直接生成二叉树的函数
|
||||||
const root = arrToTree([1, 2, 3, 4, 5, 6, 7]);
|
const root = arrToTree([1, 2, 3, 4, 5, 6, 7]);
|
||||||
console.log("\n初始化二叉树\n");
|
console.log('\n初始化二叉树\n');
|
||||||
printTree(root);
|
printTree(root);
|
||||||
|
|
||||||
/* 层序遍历 */
|
/* 层序遍历 */
|
||||||
const list = levelOrder(root);
|
const list = levelOrder(root);
|
||||||
console.log("\n层序遍历的节点打印序列 = " + list);
|
console.log('\n层序遍历的节点打印序列 = ' + list);
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
* Author: IsChristina (christinaxia77@foxmail.com)
|
* Author: IsChristina (christinaxia77@foxmail.com)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { arrToTree } = require("../modules/TreeNode");
|
const { arrToTree } = require('../modules/TreeNode');
|
||||||
const { printTree } = require("../modules/PrintUtil");
|
const { printTree } = require('../modules/PrintUtil');
|
||||||
|
|
||||||
// 初始化列表,用于存储遍历序列
|
// 初始化列表,用于存储遍历序列
|
||||||
const list = [];
|
const list = [];
|
||||||
|
@ -41,20 +41,20 @@ function postOrder(root) {
|
||||||
/* 初始化二叉树 */
|
/* 初始化二叉树 */
|
||||||
// 这里借助了一个从数组直接生成二叉树的函数
|
// 这里借助了一个从数组直接生成二叉树的函数
|
||||||
const root = arrToTree([1, 2, 3, 4, 5, 6, 7]);
|
const root = arrToTree([1, 2, 3, 4, 5, 6, 7]);
|
||||||
console.log("\n初始化二叉树\n");
|
console.log('\n初始化二叉树\n');
|
||||||
printTree(root);
|
printTree(root);
|
||||||
|
|
||||||
/* 前序遍历 */
|
/* 前序遍历 */
|
||||||
list.length = 0;
|
list.length = 0;
|
||||||
preOrder(root);
|
preOrder(root);
|
||||||
console.log("\n前序遍历的节点打印序列 = " + list);
|
console.log('\n前序遍历的节点打印序列 = ' + list);
|
||||||
|
|
||||||
/* 中序遍历 */
|
/* 中序遍历 */
|
||||||
list.length = 0;
|
list.length = 0;
|
||||||
inOrder(root);
|
inOrder(root);
|
||||||
console.log("\n中序遍历的节点打印序列 = " + list);
|
console.log('\n中序遍历的节点打印序列 = ' + list);
|
||||||
|
|
||||||
/* 后序遍历 */
|
/* 后序遍历 */
|
||||||
list.length = 0;
|
list.length = 0;
|
||||||
postOrder(root);
|
postOrder(root);
|
||||||
console.log("\n后序遍历的节点打印序列 = " + list);
|
console.log('\n后序遍历的节点打印序列 = ' + list);
|
||||||
|
|
|
@ -11,8 +11,8 @@ class ListNode {
|
||||||
val;
|
val;
|
||||||
next;
|
next;
|
||||||
constructor(val, next) {
|
constructor(val, next) {
|
||||||
this.val = (val === undefined ? 0 : val);
|
this.val = val === undefined ? 0 : val;
|
||||||
this.next = (next === undefined ? null : next);
|
this.next = next === undefined ? null : next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,5 +47,5 @@ function getListNode(head, val) {
|
||||||
module.exports = {
|
module.exports = {
|
||||||
ListNode,
|
ListNode,
|
||||||
arrToLinkedList,
|
arrToLinkedList,
|
||||||
getListNode
|
getListNode,
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* Author: IsChristina (christinaxia77@foxmail.com)
|
* Author: IsChristina (christinaxia77@foxmail.com)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { arrToTree } = require("./TreeNode");
|
const { arrToTree } = require('./TreeNode');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Print a linked list
|
* Print a linked list
|
||||||
|
@ -16,7 +16,7 @@ function printLinkedList(head) {
|
||||||
list.push(head.val.toString());
|
list.push(head.val.toString());
|
||||||
head = head.next;
|
head = head.next;
|
||||||
}
|
}
|
||||||
console.log(list.join(" -> "));
|
console.log(list.join(' -> '));
|
||||||
}
|
}
|
||||||
|
|
||||||
function Trunk(prev, str) {
|
function Trunk(prev, str) {
|
||||||
|
@ -45,28 +45,28 @@ function printTree(root, prev, isLeft) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let prev_str = " ";
|
let prev_str = ' ';
|
||||||
let trunk = new Trunk(prev, prev_str);
|
let trunk = new Trunk(prev, prev_str);
|
||||||
|
|
||||||
printTree(root.right, trunk, true);
|
printTree(root.right, trunk, true);
|
||||||
|
|
||||||
if (!prev) {
|
if (!prev) {
|
||||||
trunk.str = "———";
|
trunk.str = '———';
|
||||||
} else if (isLeft) {
|
} else if (isLeft) {
|
||||||
trunk.str = "/———";
|
trunk.str = '/———';
|
||||||
prev_str = " |";
|
prev_str = ' |';
|
||||||
} else {
|
} else {
|
||||||
trunk.str = "\\———";
|
trunk.str = '\\———';
|
||||||
prev.str = prev_str;
|
prev.str = prev_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
showTrunks(trunk);
|
showTrunks(trunk);
|
||||||
console.log(" " + root.val);
|
console.log(' ' + root.val);
|
||||||
|
|
||||||
if (prev) {
|
if (prev) {
|
||||||
prev.str = prev_str;
|
prev.str = prev_str;
|
||||||
}
|
}
|
||||||
trunk.str = " |";
|
trunk.str = ' |';
|
||||||
|
|
||||||
printTree(root.left, trunk, false);
|
printTree(root.left, trunk, false);
|
||||||
}
|
}
|
||||||
|
@ -89,14 +89,14 @@ function showTrunks(p) {
|
||||||
* @param arr
|
* @param arr
|
||||||
*/
|
*/
|
||||||
function printHeap(arr) {
|
function printHeap(arr) {
|
||||||
console.log("堆的数组表示:");
|
console.log('堆的数组表示:');
|
||||||
console.log(arr);
|
console.log(arr);
|
||||||
console.log("堆的树状表示:");
|
console.log('堆的树状表示:');
|
||||||
printTree(arrToTree(arr));
|
printTree(arrToTree(arr));
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
printLinkedList,
|
printLinkedList,
|
||||||
printTree,
|
printTree,
|
||||||
printHeap
|
printHeap,
|
||||||
};
|
};
|
||||||
|
|
|
@ -50,5 +50,5 @@ function arrToTree(arr) {
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
TreeNode,
|
TreeNode,
|
||||||
arrToTree
|
arrToTree,
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
* Author: Zhuo Qinyue (1403450829@qq.com)
|
* Author: Zhuo Qinyue (1403450829@qq.com)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* 顶点类 */
|
/* 顶点类 */
|
||||||
class Vertex {
|
class Vertex {
|
||||||
val;
|
val;
|
||||||
|
@ -32,5 +31,5 @@ class Vertex {
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
Vertex
|
Vertex,
|
||||||
};
|
};
|
||||||
|
|
6
codes/typescript/.prettierrc
Normal file
6
codes/typescript/.prettierrc
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"tabWidth": 4,
|
||||||
|
"useTabs": false,
|
||||||
|
"semi": true,
|
||||||
|
"singleQuote": true
|
||||||
|
}
|
|
@ -29,23 +29,20 @@ class MyList {
|
||||||
/* 访问元素 */
|
/* 访问元素 */
|
||||||
public get(index: number): number {
|
public get(index: number): number {
|
||||||
// 索引如果越界则抛出异常,下同
|
// 索引如果越界则抛出异常,下同
|
||||||
if (index < 0 || index >= this._size)
|
if (index < 0 || index >= this._size) throw new Error('索引越界');
|
||||||
throw new Error('索引越界');
|
|
||||||
return this.nums[index];
|
return this.nums[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 更新元素 */
|
/* 更新元素 */
|
||||||
public set(index: number, num: number): void {
|
public set(index: number, num: number): void {
|
||||||
if (index < 0 || index >= this._size)
|
if (index < 0 || index >= this._size) throw new Error('索引越界');
|
||||||
throw new Error('索引越界');
|
|
||||||
this.nums[index] = num;
|
this.nums[index] = num;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 尾部添加元素 */
|
/* 尾部添加元素 */
|
||||||
public add(num: number): void {
|
public add(num: number): void {
|
||||||
// 如果长度等于容量,则需要扩容
|
// 如果长度等于容量,则需要扩容
|
||||||
if (this._size === this._capacity)
|
if (this._size === this._capacity) this.extendCapacity();
|
||||||
this.extendCapacity();
|
|
||||||
// 将新元素添加到列表尾部
|
// 将新元素添加到列表尾部
|
||||||
this.nums[this._size] = num;
|
this.nums[this._size] = num;
|
||||||
this._size++;
|
this._size++;
|
||||||
|
@ -53,8 +50,7 @@ class MyList {
|
||||||
|
|
||||||
/* 中间插入元素 */
|
/* 中间插入元素 */
|
||||||
public insert(index: number, num: number): void {
|
public insert(index: number, num: number): void {
|
||||||
if (index < 0 || index >= this._size)
|
if (index < 0 || index >= this._size) throw new Error('索引越界');
|
||||||
throw new Error('索引越界');
|
|
||||||
// 元素数量超出容量时,触发扩容机制
|
// 元素数量超出容量时,触发扩容机制
|
||||||
if (this._size === this._capacity) {
|
if (this._size === this._capacity) {
|
||||||
this.extendCapacity();
|
this.extendCapacity();
|
||||||
|
@ -70,8 +66,7 @@ class MyList {
|
||||||
|
|
||||||
/* 删除元素 */
|
/* 删除元素 */
|
||||||
public remove(index: number): number {
|
public remove(index: number): number {
|
||||||
if (index < 0 || index >= this._size)
|
if (index < 0 || index >= this._size) throw new Error('索引越界');
|
||||||
throw new Error('索引越界');
|
|
||||||
let num = this.nums[index];
|
let num = this.nums[index];
|
||||||
// 将索引 index 之后的元素都向前移动一位
|
// 将索引 index 之后的元素都向前移动一位
|
||||||
for (let j = index; j < this._size - 1; j++) {
|
for (let j = index; j < this._size - 1; j++) {
|
||||||
|
|
|
@ -7,15 +7,20 @@
|
||||||
/* 二分查找(双闭区间) */
|
/* 二分查找(双闭区间) */
|
||||||
function binarySearch(nums: number[], target: number): number {
|
function binarySearch(nums: number[], target: number): number {
|
||||||
// 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素
|
// 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素
|
||||||
let i = 0, j = nums.length - 1;
|
let i = 0,
|
||||||
|
j = nums.length - 1;
|
||||||
// 循环,当搜索区间为空时跳出(当 i > j 时为空)
|
// 循环,当搜索区间为空时跳出(当 i > j 时为空)
|
||||||
while (i <= j) {
|
while (i <= j) {
|
||||||
const m = Math.floor((i + j) / 2); // 计算中点索引 m
|
// 计算中点索引 m
|
||||||
if (nums[m] < target) { // 此情况说明 target 在区间 [m+1, j] 中
|
const m = Math.floor((i + j) / 2);
|
||||||
|
if (nums[m] < target) {
|
||||||
|
// 此情况说明 target 在区间 [m+1, j] 中
|
||||||
i = m + 1;
|
i = m + 1;
|
||||||
} else if (nums[m] > target) { // 此情况说明 target 在区间 [i, m-1] 中
|
} else if (nums[m] > target) {
|
||||||
|
// 此情况说明 target 在区间 [i, m-1] 中
|
||||||
j = m - 1;
|
j = m - 1;
|
||||||
} else { // 找到目标元素,返回其索引
|
} else {
|
||||||
|
// 找到目标元素,返回其索引
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,22 +30,26 @@ function binarySearch(nums: number[], target: number): number {
|
||||||
/* 二分查找(左闭右开) */
|
/* 二分查找(左闭右开) */
|
||||||
function binarySearch1(nums: number[], target: number): number {
|
function binarySearch1(nums: number[], target: number): number {
|
||||||
// 初始化左闭右开 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1
|
// 初始化左闭右开 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1
|
||||||
let i = 0, j = nums.length;
|
let i = 0,
|
||||||
|
j = nums.length;
|
||||||
// 循环,当搜索区间为空时跳出(当 i = j 时为空)
|
// 循环,当搜索区间为空时跳出(当 i = j 时为空)
|
||||||
while (i < j) {
|
while (i < j) {
|
||||||
const m = Math.floor((i + j) / 2); // 计算中点索引 m
|
// 计算中点索引 m
|
||||||
if (nums[m] < target) { // 此情况说明 target 在区间 [m+1, j) 中
|
const m = Math.floor((i + j) / 2);
|
||||||
|
if (nums[m] < target) {
|
||||||
|
// 此情况说明 target 在区间 [m+1, j) 中
|
||||||
i = m + 1;
|
i = m + 1;
|
||||||
} else if (nums[m] > target) { // 此情况说明 target 在区间 [i, m) 中
|
} else if (nums[m] > target) {
|
||||||
|
// 此情况说明 target 在区间 [i, m) 中
|
||||||
j = m;
|
j = m;
|
||||||
} else { // 找到目标元素,返回其索引
|
} else {
|
||||||
|
// 找到目标元素,返回其索引
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1; // 未找到目标元素,返回 -1
|
return -1; // 未找到目标元素,返回 -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Driver Code */
|
/* Driver Code */
|
||||||
const target = 6;
|
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];
|
||||||
|
|
|
@ -121,37 +121,37 @@ function factorialRecur(n: number): number {
|
||||||
/* Driver Code */
|
/* Driver Code */
|
||||||
// 可以修改 n 运行,体会一下各种复杂度的操作数量变化趋势
|
// 可以修改 n 运行,体会一下各种复杂度的操作数量变化趋势
|
||||||
const n = 8;
|
const n = 8;
|
||||||
console.log("输入数据大小 n = " + n);
|
console.log('输入数据大小 n = ' + n);
|
||||||
|
|
||||||
let count = constant(n);
|
let count = constant(n);
|
||||||
console.log("常数阶的计算操作数量 = " + count);
|
console.log('常数阶的计算操作数量 = ' + count);
|
||||||
|
|
||||||
count = linear(n);
|
count = linear(n);
|
||||||
console.log("线性阶的计算操作数量 = " + count);
|
console.log('线性阶的计算操作数量 = ' + count);
|
||||||
count = arrayTraversal(new Array(n));
|
count = arrayTraversal(new Array(n));
|
||||||
console.log("线性阶(遍历数组)的计算操作数量 = " + count);
|
console.log('线性阶(遍历数组)的计算操作数量 = ' + count);
|
||||||
|
|
||||||
count = quadratic(n);
|
count = quadratic(n);
|
||||||
console.log("平方阶的计算操作数量 = " + count);
|
console.log('平方阶的计算操作数量 = ' + count);
|
||||||
var nums = new Array(n);
|
var nums = new Array(n);
|
||||||
for (let i = 0; i < n; i++) nums[i] = n - i; // [n,n-1,...,2,1]
|
for (let i = 0; i < n; i++) nums[i] = n - i; // [n,n-1,...,2,1]
|
||||||
count = bubbleSort(nums);
|
count = bubbleSort(nums);
|
||||||
console.log("平方阶(冒泡排序)的计算操作数量 = " + count);
|
console.log('平方阶(冒泡排序)的计算操作数量 = ' + count);
|
||||||
|
|
||||||
count = exponential(n);
|
count = exponential(n);
|
||||||
console.log("指数阶(循环实现)的计算操作数量 = " + count);
|
console.log('指数阶(循环实现)的计算操作数量 = ' + count);
|
||||||
count = expRecur(n);
|
count = expRecur(n);
|
||||||
console.log("指数阶(递归实现)的计算操作数量 = " + count);
|
console.log('指数阶(递归实现)的计算操作数量 = ' + count);
|
||||||
|
|
||||||
count = logarithmic(n);
|
count = logarithmic(n);
|
||||||
console.log("对数阶(循环实现)的计算操作数量 = " + count);
|
console.log('对数阶(循环实现)的计算操作数量 = ' + count);
|
||||||
count = logRecur(n);
|
count = logRecur(n);
|
||||||
console.log("对数阶(递归实现)的计算操作数量 = " + count);
|
console.log('对数阶(递归实现)的计算操作数量 = ' + count);
|
||||||
|
|
||||||
count = linearLogRecur(n);
|
count = linearLogRecur(n);
|
||||||
console.log("线性对数阶(递归实现)的计算操作数量 = " + count);
|
console.log('线性对数阶(递归实现)的计算操作数量 = ' + count);
|
||||||
|
|
||||||
count = factorialRecur(n);
|
count = factorialRecur(n);
|
||||||
console.log("阶乘阶(递归实现)的计算操作数量 = " + count);
|
console.log('阶乘阶(递归实现)的计算操作数量 = ' + count);
|
||||||
|
|
||||||
export {};
|
export {};
|
||||||
|
|
|
@ -38,10 +38,8 @@ for (let i = 0; i < 10; i++) {
|
||||||
const n = 100;
|
const n = 100;
|
||||||
const nums = randomNumbers(n);
|
const nums = randomNumbers(n);
|
||||||
const index = findOne(nums);
|
const index = findOne(nums);
|
||||||
console.log(
|
console.log('\n数组 [ 1, 2, ..., n ] 被打乱后 = [' + nums.join(', ') + ']');
|
||||||
"\n数组 [ 1, 2, ..., n ] 被打乱后 = [" + nums.join(", ") + "]"
|
console.log('数字 1 的索引为 ' + index);
|
||||||
);
|
|
||||||
console.log("数字 1 的索引为 " + index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export {};
|
export {};
|
||||||
|
|
|
@ -29,7 +29,11 @@ class GraphAdjList {
|
||||||
|
|
||||||
/* 添加边 */
|
/* 添加边 */
|
||||||
addEdge(vet1: Vertex, vet2: Vertex): void {
|
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');
|
throw new Error('Illegal Argument Exception');
|
||||||
}
|
}
|
||||||
// 添加边 vet1 - vet2
|
// 添加边 vet1 - vet2
|
||||||
|
@ -39,7 +43,11 @@ class GraphAdjList {
|
||||||
|
|
||||||
/* 删除边 */
|
/* 删除边 */
|
||||||
removeEdge(vet1: Vertex, vet2: Vertex): void {
|
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');
|
throw new Error('Illegal Argument Exception');
|
||||||
}
|
}
|
||||||
// 删除边 vet1 - vet2
|
// 删除边 vet1 - vet2
|
||||||
|
@ -98,7 +106,7 @@ if (require.main === module) {
|
||||||
[v2, v3],
|
[v2, v3],
|
||||||
[v0, v3],
|
[v0, v3],
|
||||||
[v2, v4],
|
[v2, v4],
|
||||||
[v3, v4]
|
[v3, v4],
|
||||||
];
|
];
|
||||||
const graph = new GraphAdjList(edges);
|
const graph = new GraphAdjList(edges);
|
||||||
console.log('\n初始化后,图为');
|
console.log('\n初始化后,图为');
|
||||||
|
|
|
@ -49,7 +49,7 @@ class GraphAdjMat {
|
||||||
/* 删除顶点 */
|
/* 删除顶点 */
|
||||||
removeVertex(index: number): void {
|
removeVertex(index: number): void {
|
||||||
if (index >= this.size()) {
|
if (index >= this.size()) {
|
||||||
throw new RangeError("Index Out Of Bounds Exception");
|
throw new RangeError('Index Out Of Bounds Exception');
|
||||||
}
|
}
|
||||||
// 在顶点列表中移除索引 index 的顶点
|
// 在顶点列表中移除索引 index 的顶点
|
||||||
this.vertices.splice(index, 1);
|
this.vertices.splice(index, 1);
|
||||||
|
@ -67,7 +67,7 @@ class GraphAdjMat {
|
||||||
addEdge(i: number, j: number): void {
|
addEdge(i: number, j: number): void {
|
||||||
// 索引越界与相等处理
|
// 索引越界与相等处理
|
||||||
if (i < 0 || j < 0 || i >= this.size() || j >= this.size() || i === j) {
|
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)
|
// 在无向图中,邻接矩阵沿主对角线对称,即满足 (i, j) == (j, i)
|
||||||
this.adjMat[i][j] = 1;
|
this.adjMat[i][j] = 1;
|
||||||
|
@ -79,7 +79,7 @@ class GraphAdjMat {
|
||||||
removeEdge(i: number, j: number): void {
|
removeEdge(i: number, j: number): void {
|
||||||
// 索引越界与相等处理
|
// 索引越界与相等处理
|
||||||
if (i < 0 || j < 0 || i >= this.size() || j >= this.size() || i === j) {
|
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[i][j] = 0;
|
||||||
this.adjMat[j][i] = 0;
|
this.adjMat[j][i] = 0;
|
||||||
|
@ -87,8 +87,8 @@ class GraphAdjMat {
|
||||||
|
|
||||||
/* 打印邻接矩阵 */
|
/* 打印邻接矩阵 */
|
||||||
print(): void {
|
print(): void {
|
||||||
console.log("顶点列表 = ", this.vertices);
|
console.log('顶点列表 = ', this.vertices);
|
||||||
console.log("邻接矩阵 =", this.adjMat);
|
console.log('邻接矩阵 =', this.adjMat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,33 +96,39 @@ class GraphAdjMat {
|
||||||
/* 初始化无向图 */
|
/* 初始化无向图 */
|
||||||
// 请注意,edges 元素代表顶点索引,即对应 vertices 元素索引
|
// 请注意,edges 元素代表顶点索引,即对应 vertices 元素索引
|
||||||
const vertices: number[] = [1, 3, 2, 5, 4];
|
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);
|
const graph: GraphAdjMat = new GraphAdjMat(vertices, edges);
|
||||||
console.log("\n初始化后,图为");
|
console.log('\n初始化后,图为');
|
||||||
graph.print();
|
graph.print();
|
||||||
|
|
||||||
/* 添加边 */
|
/* 添加边 */
|
||||||
// 顶点 1, 2 的索引分别为 0, 2
|
// 顶点 1, 2 的索引分别为 0, 2
|
||||||
graph.addEdge(0, 2);
|
graph.addEdge(0, 2);
|
||||||
console.log("\n添加边 1-2 后,图为");
|
console.log('\n添加边 1-2 后,图为');
|
||||||
graph.print();
|
graph.print();
|
||||||
|
|
||||||
/* 删除边 */
|
/* 删除边 */
|
||||||
// 顶点 1, 3 的索引分别为 0, 1
|
// 顶点 1, 3 的索引分别为 0, 1
|
||||||
graph.removeEdge(0, 1);
|
graph.removeEdge(0, 1);
|
||||||
console.log("\n删除边 1-3 后,图为");
|
console.log('\n删除边 1-3 后,图为');
|
||||||
graph.print();
|
graph.print();
|
||||||
|
|
||||||
/* 添加顶点 */
|
/* 添加顶点 */
|
||||||
graph.addVertex(6);
|
graph.addVertex(6);
|
||||||
console.log("\n添加顶点 6 后,图为");
|
console.log('\n添加顶点 6 后,图为');
|
||||||
graph.print();
|
graph.print();
|
||||||
|
|
||||||
/* 删除顶点 */
|
/* 删除顶点 */
|
||||||
// 顶点 3 的索引为 1
|
// 顶点 3 的索引为 1
|
||||||
graph.removeVertex(1);
|
graph.removeVertex(1);
|
||||||
console.log("\n删除顶点 3 后,图为");
|
console.log('\n删除顶点 3 后,图为');
|
||||||
graph.print();
|
graph.print();
|
||||||
|
|
||||||
export {};
|
export {};
|
|
@ -49,7 +49,7 @@ const edges = [
|
||||||
[v[4], v[7]],
|
[v[4], v[7]],
|
||||||
[v[5], v[8]],
|
[v[5], v[8]],
|
||||||
[v[6], v[7]],
|
[v[6], v[7]],
|
||||||
[v[7], v[8]]
|
[v[7], v[8]],
|
||||||
];
|
];
|
||||||
const graph = new GraphAdjList(edges);
|
const graph = new GraphAdjList(edges);
|
||||||
console.log('\n初始化后,图为');
|
console.log('\n初始化后,图为');
|
||||||
|
|
|
@ -8,7 +8,12 @@ import { Vertex } from '../modules/Vertex';
|
||||||
import { GraphAdjList } from './graph_adjacency_list';
|
import { GraphAdjList } from './graph_adjacency_list';
|
||||||
|
|
||||||
/* 深度优先遍历 DFS 辅助函数 */
|
/* 深度优先遍历 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); // 记录访问顶点
|
res.push(vet); // 记录访问顶点
|
||||||
visited.add(vet); // 标记该顶点已被访问
|
visited.add(vet); // 标记该顶点已被访问
|
||||||
// 遍历该顶点的所有邻接顶点
|
// 遍历该顶点的所有邻接顶点
|
||||||
|
@ -41,7 +46,7 @@ const edges = [
|
||||||
[v[1], v[2]],
|
[v[1], v[2]],
|
||||||
[v[2], v[5]],
|
[v[2], v[5]],
|
||||||
[v[4], v[5]],
|
[v[4], v[5]],
|
||||||
[v[5], v[6]]
|
[v[5], v[6]],
|
||||||
];
|
];
|
||||||
const graph = new GraphAdjList(edges);
|
const graph = new GraphAdjList(edges);
|
||||||
console.log('\n初始化后,图为');
|
console.log('\n初始化后,图为');
|
||||||
|
|
|
@ -17,12 +17,11 @@ class Entry {
|
||||||
|
|
||||||
/* 基于数组简易实现的哈希表 */
|
/* 基于数组简易实现的哈希表 */
|
||||||
class ArrayHashMap {
|
class ArrayHashMap {
|
||||||
|
|
||||||
private readonly buckets: (Entry | null)[];
|
private readonly buckets: (Entry | null)[];
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
// 初始化数组,包含 100 个桶
|
// 初始化数组,包含 100 个桶
|
||||||
this.buckets = (new Array(100)).fill(null);
|
this.buckets = new Array(100).fill(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 哈希函数 */
|
/* 哈希函数 */
|
||||||
|
|
|
@ -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: 目标节点值,value: 节点对象
|
||||||
// 若哈希表中无此 key ,返回 null
|
// 若哈希表中无此 key ,返回 null
|
||||||
return map.has(target) ? (map.get(target) as ListNode) : null;
|
return map.has(target) ? (map.get(target) as ListNode) : null;
|
||||||
|
|
|
@ -16,7 +16,7 @@ function twoSumBruteForce(nums: number[], target: number): number[] {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
};
|
}
|
||||||
|
|
||||||
/* 方法二:辅助哈希表 */
|
/* 方法二:辅助哈希表 */
|
||||||
function twoSumHashTable(nums: number[], target: number): number[] {
|
function twoSumHashTable(nums: number[], target: number): number[] {
|
||||||
|
@ -32,17 +32,18 @@ function twoSumHashTable(nums: number[], target: number): number[] {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
};
|
}
|
||||||
|
|
||||||
/* Driver Code */
|
/* Driver Code */
|
||||||
// 方法一
|
// 方法一
|
||||||
const nums = [2, 7, 11, 15], target = 9;
|
const nums = [2, 7, 11, 15],
|
||||||
|
target = 9;
|
||||||
|
|
||||||
let res = twoSumBruteForce(nums, target);
|
let res = twoSumBruteForce(nums, target);
|
||||||
console.log("方法一 res = ", res);
|
console.log('方法一 res = ', res);
|
||||||
|
|
||||||
// 方法二
|
// 方法二
|
||||||
res = twoSumHashTable(nums, target);
|
res = twoSumHashTable(nums, target);
|
||||||
console.log("方法二 res = ", res);
|
console.log('方法二 res = ', res);
|
||||||
|
|
||||||
export {};
|
export {};
|
||||||
|
|
|
@ -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) {
|
while (head) {
|
||||||
// 找到目标节点,返回之
|
// 找到目标节点,返回之
|
||||||
|
|
|
@ -11,15 +11,18 @@ function merge(nums: number[], left: number, mid: number, right: number): void {
|
||||||
// 初始化辅助数组
|
// 初始化辅助数组
|
||||||
let tmp = nums.slice(left, right + 1);
|
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 分别指向左子数组、右子数组的首元素
|
// i, j 分别指向左子数组、右子数组的首元素
|
||||||
let i = leftStart, j = rightStart;
|
let i = leftStart,
|
||||||
|
j = rightStart;
|
||||||
// 通过覆盖原数组 nums 来合并左子数组和右子数组
|
// 通过覆盖原数组 nums 来合并左子数组和右子数组
|
||||||
for (let k = left; k <= right; k++) {
|
for (let k = left; k <= right; k++) {
|
||||||
// 若“左子数组已全部合并完”,则选取右子数组元素,并且 j++
|
|
||||||
if (i > leftEnd) {
|
if (i > leftEnd) {
|
||||||
|
// 若“左子数组已全部合并完”,则选取右子数组元素,并且 j++
|
||||||
nums[k] = tmp[j++];
|
nums[k] = tmp[j++];
|
||||||
// 否则,若“右子数组已全部合并完”或“左子数组元素 <= 右子数组元素”,则选取左子数组元素,并且 i++
|
// 否则,若“右子数组已全部合并完”或“左子数组元素 <= 右子数组元素”,则选取左子数组元素,并且 i++
|
||||||
} else if (j > rightEnd || tmp[i] <= tmp[j]) {
|
} else if (j > rightEnd || tmp[i] <= tmp[j]) {
|
||||||
|
|
|
@ -16,7 +16,8 @@ class QuickSort {
|
||||||
/* 哨兵划分 */
|
/* 哨兵划分 */
|
||||||
partition(nums: number[], left: number, right: number): number {
|
partition(nums: number[], left: number, right: number): number {
|
||||||
// 以 nums[left] 作为基准数
|
// 以 nums[left] 作为基准数
|
||||||
let i = left, j = right;
|
let i = left,
|
||||||
|
j = right;
|
||||||
while (i < j) {
|
while (i < j) {
|
||||||
while (i < j && nums[j] >= nums[left]) {
|
while (i < j && nums[j] >= nums[left]) {
|
||||||
j -= 1; // 从右向左找首个小于基准数的元素
|
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
|
// 异或规则为 0 ^ 0 = 1 ^ 1 = 0, 0 ^ 1 = 1 ^ 0 = 1
|
||||||
if (Number(nums[left] < nums[mid]) ^ Number(nums[left] < nums[right])) {
|
if (Number(nums[left] < nums[mid]) ^ Number(nums[left] < nums[right])) {
|
||||||
return left;
|
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;
|
return mid;
|
||||||
} else {
|
} else {
|
||||||
return right;
|
return right;
|
||||||
|
@ -70,11 +78,17 @@ class QuickSortMedian {
|
||||||
/* 哨兵划分(三数取中值) */
|
/* 哨兵划分(三数取中值) */
|
||||||
partition(nums: number[], left: number, right: number): number {
|
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);
|
this.swap(nums, left, med);
|
||||||
// 以 nums[left] 作为基准数
|
// 以 nums[left] 作为基准数
|
||||||
let i = left, j = right;
|
let i = left,
|
||||||
|
j = right;
|
||||||
while (i < j) {
|
while (i < j) {
|
||||||
while (i < j && nums[j] >= nums[left]) {
|
while (i < j && nums[j] >= nums[left]) {
|
||||||
j--; // 从右向左找首个小于基准数的元素
|
j--; // 从右向左找首个小于基准数的元素
|
||||||
|
@ -114,7 +128,8 @@ class QuickSortTailCall {
|
||||||
/* 哨兵划分 */
|
/* 哨兵划分 */
|
||||||
partition(nums: number[], left: number, right: number): number {
|
partition(nums: number[], left: number, right: number): number {
|
||||||
// 以 nums[left] 作为基准数
|
// 以 nums[left] 作为基准数
|
||||||
let i = left, j = right;
|
let i = left,
|
||||||
|
j = right;
|
||||||
while (i < j) {
|
while (i < j) {
|
||||||
while (i < j && nums[j] >= nums[left]) {
|
while (i < j && nums[j] >= nums[left]) {
|
||||||
j--; // 从右向左找首个小于基准数的元素
|
j--; // 从右向左找首个小于基准数的元素
|
||||||
|
|
|
@ -58,8 +58,10 @@ function radixSort(nums: number[]): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Driver Code */
|
/* Driver Code */
|
||||||
const nums = [10546151, 35663510, 42865989, 34862445, 81883077,
|
const nums = [
|
||||||
88906420, 72429244, 30524779, 82060337, 63832996];
|
10546151, 35663510, 42865989, 34862445, 81883077, 88906420, 72429244,
|
||||||
|
30524779, 82060337, 63832996,
|
||||||
|
];
|
||||||
radixSort(nums);
|
radixSort(nums);
|
||||||
console.log('基数排序完成后 nums =', nums);
|
console.log('基数排序完成后 nums =', nums);
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
* Author: Zhuo Qinyue (1403450829@qq.com)
|
* Author: Zhuo Qinyue (1403450829@qq.com)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* 基于环形数组实现的双向队列 */
|
/* 基于环形数组实现的双向队列 */
|
||||||
class ArrayDeque {
|
class ArrayDeque {
|
||||||
private nums: number[]; // 用于存储双向队列元素的数组
|
private nums: number[]; // 用于存储双向队列元素的数组
|
||||||
|
@ -44,7 +43,7 @@ class ArrayDeque {
|
||||||
/* 队首入队 */
|
/* 队首入队 */
|
||||||
pushFirst(num: number): void {
|
pushFirst(num: number): void {
|
||||||
if (this.queSize === this.capacity()) {
|
if (this.queSize === this.capacity()) {
|
||||||
console.log("双向队列已满");
|
console.log('双向队列已满');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 队首指针向左移动一位
|
// 队首指针向左移动一位
|
||||||
|
@ -58,7 +57,7 @@ class ArrayDeque {
|
||||||
/* 队尾入队 */
|
/* 队尾入队 */
|
||||||
pushLast(num: number): void {
|
pushLast(num: number): void {
|
||||||
if (this.queSize === this.capacity()) {
|
if (this.queSize === this.capacity()) {
|
||||||
console.log("双向队列已满");
|
console.log('双向队列已满');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 计算尾指针,指向队尾索引 + 1
|
// 计算尾指针,指向队尾索引 + 1
|
||||||
|
@ -86,15 +85,13 @@ class ArrayDeque {
|
||||||
|
|
||||||
/* 访问队首元素 */
|
/* 访问队首元素 */
|
||||||
peekFirst(): number {
|
peekFirst(): number {
|
||||||
if (this.isEmpty())
|
if (this.isEmpty()) throw new Error('The Deque Is Empty.');
|
||||||
throw new Error("The Deque Is Empty.");
|
|
||||||
return this.nums[this.front];
|
return this.nums[this.front];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 访问队尾元素 */
|
/* 访问队尾元素 */
|
||||||
peekLast(): number {
|
peekLast(): number {
|
||||||
if (this.isEmpty())
|
if (this.isEmpty()) throw new Error('The Deque Is Empty.');
|
||||||
throw new Error("The Deque Is Empty.");
|
|
||||||
// 计算尾元素索引
|
// 计算尾元素索引
|
||||||
const last = this.index(this.front + this.queSize - 1);
|
const last = this.index(this.front + this.queSize - 1);
|
||||||
return this.nums[last];
|
return this.nums[last];
|
||||||
|
@ -118,32 +115,44 @@ const deque: ArrayDeque = new ArrayDeque(capacity);
|
||||||
deque.pushLast(3);
|
deque.pushLast(3);
|
||||||
deque.pushLast(2);
|
deque.pushLast(2);
|
||||||
deque.pushLast(5);
|
deque.pushLast(5);
|
||||||
console.log("双向队列 deque = [" + deque.toArray() + "]");
|
console.log('双向队列 deque = [' + deque.toArray() + ']');
|
||||||
|
|
||||||
/* 访问元素 */
|
/* 访问元素 */
|
||||||
const peekFirst = deque.peekFirst();
|
const peekFirst = deque.peekFirst();
|
||||||
console.log("队首元素 peekFirst = " + peekFirst);
|
console.log('队首元素 peekFirst = ' + peekFirst);
|
||||||
const peekLast = deque.peekLast();
|
const peekLast = deque.peekLast();
|
||||||
console.log("队尾元素 peekLast = " + peekLast);
|
console.log('队尾元素 peekLast = ' + peekLast);
|
||||||
|
|
||||||
/* 元素入队 */
|
/* 元素入队 */
|
||||||
deque.pushLast(4);
|
deque.pushLast(4);
|
||||||
console.log("元素 4 队尾入队后 deque = [" + deque.toArray() + "]");
|
console.log('元素 4 队尾入队后 deque = [' + deque.toArray() + ']');
|
||||||
deque.pushFirst(1);
|
deque.pushFirst(1);
|
||||||
console.log("元素 1 队首入队后 deque = [" + deque.toArray() + "]");
|
console.log('元素 1 队首入队后 deque = [' + deque.toArray() + ']');
|
||||||
|
|
||||||
/* 元素出队 */
|
/* 元素出队 */
|
||||||
const popLast = deque.popLast();
|
const popLast = deque.popLast();
|
||||||
console.log("队尾出队元素 = " + popLast + ",队尾出队后 deque = [" + deque.toArray() + "]");
|
console.log(
|
||||||
|
'队尾出队元素 = ' +
|
||||||
|
popLast +
|
||||||
|
',队尾出队后 deque = [' +
|
||||||
|
deque.toArray() +
|
||||||
|
']'
|
||||||
|
);
|
||||||
const popFirst = deque.popFirst();
|
const popFirst = deque.popFirst();
|
||||||
console.log("队首出队元素 = " + popFirst + ",队首出队后 deque = [" + deque.toArray()+ "]");
|
console.log(
|
||||||
|
'队首出队元素 = ' +
|
||||||
|
popFirst +
|
||||||
|
',队首出队后 deque = [' +
|
||||||
|
deque.toArray() +
|
||||||
|
']'
|
||||||
|
);
|
||||||
|
|
||||||
/* 获取双向队列的长度 */
|
/* 获取双向队列的长度 */
|
||||||
const size = deque.size();
|
const size = deque.size();
|
||||||
console.log("双向队列长度 size = " + size);
|
console.log('双向队列长度 size = ' + size);
|
||||||
|
|
||||||
/* 判断双向队列是否为空 */
|
/* 判断双向队列是否为空 */
|
||||||
const isEmpty = deque.isEmpty();
|
const isEmpty = deque.isEmpty();
|
||||||
console.log("双向队列是否为空 = " + isEmpty);
|
console.log('双向队列是否为空 = ' + isEmpty);
|
||||||
|
|
||||||
export {};
|
export {};
|
||||||
|
|
|
@ -33,7 +33,7 @@ class ArrayQueue {
|
||||||
/* 入队 */
|
/* 入队 */
|
||||||
push(num: number): void {
|
push(num: number): void {
|
||||||
if (this.size == this.capacity) {
|
if (this.size == this.capacity) {
|
||||||
console.log("队列已满");
|
console.log('队列已满');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 计算尾指针,指向队尾索引 + 1
|
// 计算尾指针,指向队尾索引 + 1
|
||||||
|
@ -55,8 +55,7 @@ class ArrayQueue {
|
||||||
|
|
||||||
/* 访问队首元素 */
|
/* 访问队首元素 */
|
||||||
peek(): number {
|
peek(): number {
|
||||||
if (this.empty())
|
if (this.empty()) throw new Error('队列为空');
|
||||||
throw new Error("队列为空");
|
|
||||||
return this.nums[this.front];
|
return this.nums[this.front];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,29 +81,29 @@ queue.push(3);
|
||||||
queue.push(2);
|
queue.push(2);
|
||||||
queue.push(5);
|
queue.push(5);
|
||||||
queue.push(4);
|
queue.push(4);
|
||||||
console.log("队列 queue =", queue.toArray());
|
console.log('队列 queue =', queue.toArray());
|
||||||
|
|
||||||
/* 访问队首元素 */
|
/* 访问队首元素 */
|
||||||
const peek = queue.peek();
|
const peek = queue.peek();
|
||||||
console.log("队首元素 peek = " + peek);
|
console.log('队首元素 peek = ' + peek);
|
||||||
|
|
||||||
/* 元素出队 */
|
/* 元素出队 */
|
||||||
const pop = queue.pop();
|
const pop = queue.pop();
|
||||||
console.log("出队元素 pop = " + pop + ",出队后 queue =", queue.toArray());
|
console.log('出队元素 pop = ' + pop + ',出队后 queue =', queue.toArray());
|
||||||
|
|
||||||
/* 获取队列的长度 */
|
/* 获取队列的长度 */
|
||||||
const size = queue.size;
|
const size = queue.size;
|
||||||
console.log("队列长度 size = " + size);
|
console.log('队列长度 size = ' + size);
|
||||||
|
|
||||||
/* 判断队列是否为空 */
|
/* 判断队列是否为空 */
|
||||||
const empty = queue.empty();
|
const empty = queue.empty();
|
||||||
console.log("队列是否为空 = " + empty);
|
console.log('队列是否为空 = ' + empty);
|
||||||
|
|
||||||
/* 测试环形数组 */
|
/* 测试环形数组 */
|
||||||
for (let i = 0; i < 10; i++) {
|
for (let i = 0; i < 10; i++) {
|
||||||
queue.push(i);
|
queue.push(i);
|
||||||
queue.pop();
|
queue.pop();
|
||||||
console.log("第 " + i + " 轮入队 + 出队后 queue =", queue.toArray());
|
console.log('第 ' + i + ' 轮入队 + 出队后 queue =', queue.toArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
export {};
|
export {};
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
* Author: S-N-O-R-L-A-X (snorlax.xu@outlook.com)
|
* Author: S-N-O-R-L-A-X (snorlax.xu@outlook.com)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* 基于数组实现的栈 */
|
/* 基于数组实现的栈 */
|
||||||
class ArrayStack {
|
class ArrayStack {
|
||||||
private stack: number[];
|
private stack: number[];
|
||||||
|
@ -29,15 +28,13 @@ class ArrayStack {
|
||||||
|
|
||||||
/* 出栈 */
|
/* 出栈 */
|
||||||
pop(): number | undefined {
|
pop(): number | undefined {
|
||||||
if (this.empty())
|
if (this.empty()) throw new Error('栈为空');
|
||||||
throw new Error('栈为空');
|
|
||||||
return this.stack.pop();
|
return this.stack.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 访问栈顶元素 */
|
/* 访问栈顶元素 */
|
||||||
top(): number | undefined {
|
top(): number | undefined {
|
||||||
if (this.empty())
|
if (this.empty()) throw new Error('栈为空');
|
||||||
throw new Error('栈为空');
|
|
||||||
return this.stack[this.stack.length - 1];
|
return this.stack[this.stack.length - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,8 +42,7 @@ class ArrayStack {
|
||||||
toArray() {
|
toArray() {
|
||||||
return this.stack;
|
return this.stack;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Driver Code */
|
/* Driver Code */
|
||||||
/* 初始化栈 */
|
/* 初始化栈 */
|
||||||
|
@ -58,24 +54,24 @@ stack.push(3);
|
||||||
stack.push(2);
|
stack.push(2);
|
||||||
stack.push(5);
|
stack.push(5);
|
||||||
stack.push(4);
|
stack.push(4);
|
||||||
console.log("栈 stack = ");
|
console.log('栈 stack = ');
|
||||||
console.log(stack.toArray());
|
console.log(stack.toArray());
|
||||||
|
|
||||||
/* 访问栈顶元素 */
|
/* 访问栈顶元素 */
|
||||||
const top = stack.top();
|
const top = stack.top();
|
||||||
console.log("栈顶元素 top = " + top);
|
console.log('栈顶元素 top = ' + top);
|
||||||
|
|
||||||
/* 元素出栈 */
|
/* 元素出栈 */
|
||||||
const pop = stack.pop();
|
const pop = stack.pop();
|
||||||
console.log("出栈元素 pop = " + pop + ",出栈后 stack = ");
|
console.log('出栈元素 pop = ' + pop + ',出栈后 stack = ');
|
||||||
console.log(stack.toArray());
|
console.log(stack.toArray());
|
||||||
|
|
||||||
/* 获取栈的长度 */
|
/* 获取栈的长度 */
|
||||||
const size = stack.size;
|
const size = stack.size;
|
||||||
console.log("栈的长度 size = " + size);
|
console.log('栈的长度 size = ' + size);
|
||||||
|
|
||||||
/* 判断是否为空 */
|
/* 判断是否为空 */
|
||||||
const empty = stack.empty();
|
const empty = stack.empty();
|
||||||
console.log("栈是否为空 = " + empty);
|
console.log('栈是否为空 = ' + empty);
|
||||||
|
|
||||||
export {};
|
export {};
|
||||||
|
|
|
@ -16,27 +16,31 @@ deque.push(4);
|
||||||
// 请注意,由于是数组,unshift() 方法的时间复杂度为 O(n)
|
// 请注意,由于是数组,unshift() 方法的时间复杂度为 O(n)
|
||||||
deque.unshift(3);
|
deque.unshift(3);
|
||||||
deque.unshift(1);
|
deque.unshift(1);
|
||||||
console.log("双向队列 deque = ", deque);
|
console.log('双向队列 deque = ', deque);
|
||||||
|
|
||||||
/* 访问元素 */
|
/* 访问元素 */
|
||||||
const peekFirst: number = deque[0];
|
const peekFirst: number = deque[0];
|
||||||
console.log("队首元素 peekFirst = " + peekFirst);
|
console.log('队首元素 peekFirst = ' + peekFirst);
|
||||||
const peekLast: number = deque[deque.length - 1];
|
const peekLast: number = deque[deque.length - 1];
|
||||||
console.log("队尾元素 peekLast = " + peekLast);
|
console.log('队尾元素 peekLast = ' + peekLast);
|
||||||
|
|
||||||
/* 元素出队 */
|
/* 元素出队 */
|
||||||
// 请注意,由于是数组,shift() 方法的时间复杂度为 O(n)
|
// 请注意,由于是数组,shift() 方法的时间复杂度为 O(n)
|
||||||
const popFront: number = deque.shift() as number;
|
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;
|
const popBack: number = deque.pop() as number;
|
||||||
console.log("队尾出队元素 popBack = " + popBack + ",队尾出队后 deque = " + deque);
|
console.log(
|
||||||
|
'队尾出队元素 popBack = ' + popBack + ',队尾出队后 deque = ' + deque
|
||||||
|
);
|
||||||
|
|
||||||
/* 获取双向队列的长度 */
|
/* 获取双向队列的长度 */
|
||||||
const size: number = deque.length;
|
const size: number = deque.length;
|
||||||
console.log("双向队列长度 size = " + size);
|
console.log('双向队列长度 size = ' + size);
|
||||||
|
|
||||||
/* 判断双向队列是否为空 */
|
/* 判断双向队列是否为空 */
|
||||||
const isEmpty: boolean = size === 0;
|
const isEmpty: boolean = size === 0;
|
||||||
console.log("双向队列是否为空 = " + isEmpty);
|
console.log('双向队列是否为空 = ' + isEmpty);
|
||||||
|
|
||||||
export {};
|
export {};
|
||||||
|
|
|
@ -123,7 +123,7 @@ class LinkedListDeque {
|
||||||
arr.push(temp.val);
|
arr.push(temp.val);
|
||||||
temp = temp.next;
|
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(3);
|
||||||
linkedListDeque.pushLast(2);
|
linkedListDeque.pushLast(2);
|
||||||
linkedListDeque.pushLast(5);
|
linkedListDeque.pushLast(5);
|
||||||
console.log("双向队列 linkedListDeque = ");
|
console.log('双向队列 linkedListDeque = ');
|
||||||
linkedListDeque.print();
|
linkedListDeque.print();
|
||||||
|
|
||||||
/* 访问元素 */
|
/* 访问元素 */
|
||||||
const peekFirst: number = linkedListDeque.peekFirst();
|
const peekFirst: number = linkedListDeque.peekFirst();
|
||||||
console.log("队首元素 peekFirst = " + peekFirst);
|
console.log('队首元素 peekFirst = ' + peekFirst);
|
||||||
const peekLast: number = linkedListDeque.peekLast();
|
const peekLast: number = linkedListDeque.peekLast();
|
||||||
console.log("队尾元素 peekLast = " + peekLast);
|
console.log('队尾元素 peekLast = ' + peekLast);
|
||||||
|
|
||||||
/* 元素入队 */
|
/* 元素入队 */
|
||||||
linkedListDeque.pushLast(4);
|
linkedListDeque.pushLast(4);
|
||||||
console.log("元素 4 队尾入队后 linkedListDeque = ");
|
console.log('元素 4 队尾入队后 linkedListDeque = ');
|
||||||
linkedListDeque.print();
|
linkedListDeque.print();
|
||||||
linkedListDeque.pushFirst(1);
|
linkedListDeque.pushFirst(1);
|
||||||
console.log("元素 1 队首入队后 linkedListDeque = ");
|
console.log('元素 1 队首入队后 linkedListDeque = ');
|
||||||
linkedListDeque.print();
|
linkedListDeque.print();
|
||||||
|
|
||||||
/* 元素出队 */
|
/* 元素出队 */
|
||||||
const popLast: number = linkedListDeque.popLast();
|
const popLast: number = linkedListDeque.popLast();
|
||||||
console.log("队尾出队元素 = " + popLast + ",队尾出队后 linkedListDeque = ");
|
console.log('队尾出队元素 = ' + popLast + ',队尾出队后 linkedListDeque = ');
|
||||||
linkedListDeque.print();
|
linkedListDeque.print();
|
||||||
const popFirst: number = linkedListDeque.popFirst();
|
const popFirst: number = linkedListDeque.popFirst();
|
||||||
console.log("队首出队元素 = " + popFirst + ",队首出队后 linkedListDeque = ");
|
console.log('队首出队元素 = ' + popFirst + ',队首出队后 linkedListDeque = ');
|
||||||
linkedListDeque.print();
|
linkedListDeque.print();
|
||||||
|
|
||||||
/* 获取双向队列的长度 */
|
/* 获取双向队列的长度 */
|
||||||
const size: number = linkedListDeque.size();
|
const size: number = linkedListDeque.size();
|
||||||
console.log("双向队列长度 size = " + size);
|
console.log('双向队列长度 size = ' + size);
|
||||||
|
|
||||||
/* 判断双向队列是否为空 */
|
/* 判断双向队列是否为空 */
|
||||||
const isEmpty: boolean = linkedListDeque.isEmpty();
|
const isEmpty: boolean = linkedListDeque.isEmpty();
|
||||||
console.log("双向队列是否为空 = " + isEmpty);
|
console.log('双向队列是否为空 = ' + isEmpty);
|
||||||
|
|
|
@ -15,23 +15,23 @@ queue.push(3);
|
||||||
queue.push(2);
|
queue.push(2);
|
||||||
queue.push(5);
|
queue.push(5);
|
||||||
queue.push(4);
|
queue.push(4);
|
||||||
console.log("队列 queue =", queue);
|
console.log('队列 queue =', queue);
|
||||||
|
|
||||||
/* 访问队首元素 */
|
/* 访问队首元素 */
|
||||||
const peek = queue[0];
|
const peek = queue[0];
|
||||||
console.log("队首元素 peek =", peek);
|
console.log('队首元素 peek =', peek);
|
||||||
|
|
||||||
/* 元素出队 */
|
/* 元素出队 */
|
||||||
// 底层是数组,因此 shift() 方法的时间复杂度为 O(n)
|
// 底层是数组,因此 shift() 方法的时间复杂度为 O(n)
|
||||||
const pop = queue.shift();
|
const pop = queue.shift();
|
||||||
console.log("出队元素 pop =", pop, ",出队后 queue = ", queue);
|
console.log('出队元素 pop =', pop, ',出队后 queue = ', queue);
|
||||||
|
|
||||||
/* 获取队列的长度 */
|
/* 获取队列的长度 */
|
||||||
const size = queue.length;
|
const size = queue.length;
|
||||||
console.log("队列长度 size =", size);
|
console.log('队列长度 size =', size);
|
||||||
|
|
||||||
/* 判断队列是否为空 */
|
/* 判断队列是否为空 */
|
||||||
const isEmpty = queue.length === 0;
|
const isEmpty = queue.length === 0;
|
||||||
console.log("队列是否为空 = ", isEmpty);
|
console.log('队列是否为空 = ', isEmpty);
|
||||||
|
|
||||||
export {};
|
export {};
|
||||||
|
|
|
@ -15,23 +15,23 @@ stack.push(3);
|
||||||
stack.push(2);
|
stack.push(2);
|
||||||
stack.push(5);
|
stack.push(5);
|
||||||
stack.push(4);
|
stack.push(4);
|
||||||
console.log("栈 stack =", stack);
|
console.log('栈 stack =', stack);
|
||||||
|
|
||||||
/* 访问栈顶元素 */
|
/* 访问栈顶元素 */
|
||||||
const peek = stack[stack.length - 1];
|
const peek = stack[stack.length - 1];
|
||||||
console.log("栈顶元素 peek =", peek);
|
console.log('栈顶元素 peek =', peek);
|
||||||
|
|
||||||
/* 元素出栈 */
|
/* 元素出栈 */
|
||||||
const pop = stack.pop();
|
const pop = stack.pop();
|
||||||
console.log("出栈元素 pop =", pop);
|
console.log('出栈元素 pop =', pop);
|
||||||
console.log("出栈后 stack =", stack);
|
console.log('出栈后 stack =', stack);
|
||||||
|
|
||||||
/* 获取栈的长度 */
|
/* 获取栈的长度 */
|
||||||
const size = stack.length;
|
const size = stack.length;
|
||||||
console.log("栈的长度 size =", size);
|
console.log('栈的长度 size =', size);
|
||||||
|
|
||||||
/* 判断是否为空 */
|
/* 判断是否为空 */
|
||||||
const isEmpty = stack.length === 0;
|
const isEmpty = stack.length === 0;
|
||||||
console.log("栈是否为空 =", isEmpty);
|
console.log('栈是否为空 =', isEmpty);
|
||||||
|
|
||||||
export {};
|
export {};
|
||||||
|
|
|
@ -24,7 +24,8 @@ class AVLTree {
|
||||||
/* 更新节点高度 */
|
/* 更新节点高度 */
|
||||||
private updateHeight(node: TreeNode): void {
|
private updateHeight(node: TreeNode): void {
|
||||||
// 节点高度等于最高子树高度 + 1
|
// 节点高度等于最高子树高度 + 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 获取平衡因子 */
|
/* 获取平衡因子 */
|
||||||
|
|
|
@ -44,8 +44,4 @@ function getListNode(head: ListNode | null, val: number): ListNode | null {
|
||||||
return head;
|
return head;
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export { ListNode, arrToLinkedList, getListNode };
|
||||||
ListNode,
|
|
||||||
arrToLinkedList,
|
|
||||||
getListNode
|
|
||||||
};
|
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
* Author: Justin (xiefahit@gmail.com)
|
* Author: Justin (xiefahit@gmail.com)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { ListNode } from "./ListNode";
|
import { ListNode } from './ListNode';
|
||||||
import { TreeNode, arrToTree } from "./TreeNode";
|
import { TreeNode, arrToTree } from './TreeNode';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Print a linked list
|
* Print a linked list
|
||||||
|
@ -46,7 +46,11 @@ function printTree(root: TreeNode | null) {
|
||||||
* @param prev
|
* @param prev
|
||||||
* @param isLeft
|
* @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) {
|
if (root === null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -98,15 +102,11 @@ function showTrunks(p: Trunk | null) {
|
||||||
* @param arr
|
* @param arr
|
||||||
*/
|
*/
|
||||||
function printHeap(arr: number[]): void {
|
function printHeap(arr: number[]): void {
|
||||||
console.log("堆的数组表示:");
|
console.log('堆的数组表示:');
|
||||||
console.log(arr);
|
console.log(arr);
|
||||||
console.log("堆的树状表示:");
|
console.log('堆的树状表示:');
|
||||||
const root = arrToTree(arr);
|
const root = arrToTree(arr);
|
||||||
printTree(root);
|
printTree(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export { printLinkedList, printTree, printHeap };
|
||||||
printLinkedList,
|
|
||||||
printTree,
|
|
||||||
printHeap
|
|
||||||
};
|
|
||||||
|
|
|
@ -12,7 +12,12 @@ class TreeNode {
|
||||||
height: number; // 节点高度
|
height: number; // 节点高度
|
||||||
left: TreeNode | null; // 左子节点指针
|
left: TreeNode | null; // 左子节点指针
|
||||||
right: 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.val = val === undefined ? 0 : val;
|
||||||
this.height = height === undefined ? 0 : height;
|
this.height = height === undefined ? 0 : height;
|
||||||
this.left = left === undefined ? null : left;
|
this.left = left === undefined ? null : left;
|
||||||
|
@ -49,7 +54,4 @@ function arrToTree(arr: (number | null)[]): TreeNode | null {
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export { TreeNode, arrToTree };
|
||||||
TreeNode,
|
|
||||||
arrToTree
|
|
||||||
};
|
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
* Author: Zhuo Qinyue (1403450829@qq.com)
|
* Author: Zhuo Qinyue (1403450829@qq.com)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* 顶点类 */
|
/* 顶点类 */
|
||||||
class Vertex {
|
class Vertex {
|
||||||
val: number;
|
val: number;
|
||||||
|
@ -31,6 +30,4 @@ class Vertex {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export { Vertex };
|
||||||
Vertex
|
|
||||||
};
|
|
||||||
|
|
Loading…
Reference in a new issue