build
This commit is contained in:
parent
799698e67c
commit
503ca797b8
@ -122,7 +122,15 @@ status: new
|
|||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="iteration.swift"
|
```swift title="iteration.swift"
|
||||||
[class]{}-[func]{forLoop}
|
/* for 循环 */
|
||||||
|
func forLoop(n: Int) -> Int {
|
||||||
|
var res = 0
|
||||||
|
// 循环求和 1, 2, ..., n-1, n
|
||||||
|
for i in 1 ... n {
|
||||||
|
res += i
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
@ -148,7 +156,7 @@ status: new
|
|||||||
=== "Rust"
|
=== "Rust"
|
||||||
|
|
||||||
```rust title="iteration.rs"
|
```rust title="iteration.rs"
|
||||||
/* for 循环 */
|
/* for 循环 */
|
||||||
fn for_loop(n: i32) -> i32 {
|
fn for_loop(n: i32) -> i32 {
|
||||||
let mut res = 0;
|
let mut res = 0;
|
||||||
// 循环求和 1, 2, ..., n-1, n
|
// 循环求和 1, 2, ..., n-1, n
|
||||||
@ -294,7 +302,17 @@ status: new
|
|||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="iteration.swift"
|
```swift title="iteration.swift"
|
||||||
[class]{}-[func]{whileLoop}
|
/* while 循环 */
|
||||||
|
func whileLoop(n: Int) -> Int {
|
||||||
|
var res = 0
|
||||||
|
var i = 1 // 初始化条件变量
|
||||||
|
// 循环求和 1, 2, ..., n-1, n
|
||||||
|
while i <= n {
|
||||||
|
res += i
|
||||||
|
i += 1 // 更新条件变量
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
@ -473,7 +491,19 @@ status: new
|
|||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="iteration.swift"
|
```swift title="iteration.swift"
|
||||||
[class]{}-[func]{whileLoopII}
|
/* while 循环(两次更新) */
|
||||||
|
func whileLoopII(n: Int) -> Int {
|
||||||
|
var res = 0
|
||||||
|
var i = 1 // 初始化条件变量
|
||||||
|
// 循环求和 1, 4, ...
|
||||||
|
while i <= n {
|
||||||
|
res += i
|
||||||
|
// 更新条件变量
|
||||||
|
i += 1
|
||||||
|
i *= 2
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
@ -649,7 +679,18 @@ status: new
|
|||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="iteration.swift"
|
```swift title="iteration.swift"
|
||||||
[class]{}-[func]{nestedForLoop}
|
/* 双层 for 循环 */
|
||||||
|
func nestedForLoop(n: Int) -> String {
|
||||||
|
var res = ""
|
||||||
|
// 循环 i = 1, 2, ..., n-1, n
|
||||||
|
for i in 1 ... n {
|
||||||
|
// 循环 j = 1, 2, ..., n-1, n
|
||||||
|
for j in 1 ... n {
|
||||||
|
res.append("(\(i), \(j)), ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
@ -829,7 +870,17 @@ status: new
|
|||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="recursion.swift"
|
```swift title="recursion.swift"
|
||||||
[class]{}-[func]{recur}
|
/* 递归 */
|
||||||
|
func recur(n: Int) -> Int {
|
||||||
|
// 终止条件
|
||||||
|
if n == 1 {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
// 递:递归调用
|
||||||
|
let res = recur(n: n - 1)
|
||||||
|
// 归:返回结果
|
||||||
|
return n + res
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
@ -1006,7 +1057,15 @@ status: new
|
|||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="recursion.swift"
|
```swift title="recursion.swift"
|
||||||
[class]{}-[func]{tailRecur}
|
/* 尾递归 */
|
||||||
|
func tailRecur(n: Int, res: Int) -> Int {
|
||||||
|
// 终止条件
|
||||||
|
if n == 0 {
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
// 尾递归调用
|
||||||
|
return tailRecur(n: n - 1, res: res + n)
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
@ -1179,7 +1238,17 @@ status: new
|
|||||||
=== "Swift"
|
=== "Swift"
|
||||||
|
|
||||||
```swift title="recursion.swift"
|
```swift title="recursion.swift"
|
||||||
[class]{}-[func]{fib}
|
/* 斐波那契数列:递归 */
|
||||||
|
func fib(n: Int) -> Int {
|
||||||
|
// 终止条件 f(1) = 0, f(2) = 1
|
||||||
|
if n == 1 || n == 2 {
|
||||||
|
return n - 1
|
||||||
|
}
|
||||||
|
// 递归调用 f(n) = f(n-1) + f(n-2)
|
||||||
|
let res = fib(n: n - 1) + fib(n: n - 2)
|
||||||
|
// 返回结果 f(n)
|
||||||
|
return res
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Zig"
|
=== "Zig"
|
||||||
|
@ -1695,7 +1695,7 @@ $$
|
|||||||
let count = 0; // 计数器
|
let count = 0; // 计数器
|
||||||
// 外循环:未排序区间为 [0, i]
|
// 外循环:未排序区间为 [0, i]
|
||||||
for (let i = nums.length - 1; i > 0; i--) {
|
for (let i = nums.length - 1; i > 0; i--) {
|
||||||
// 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
|
// 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
|
||||||
for (let j = 0; j < i; j++) {
|
for (let j = 0; j < i; j++) {
|
||||||
if (nums[j] > nums[j + 1]) {
|
if (nums[j] > nums[j + 1]) {
|
||||||
// 交换 nums[j] 与 nums[j + 1]
|
// 交换 nums[j] 与 nums[j + 1]
|
||||||
@ -1718,7 +1718,7 @@ $$
|
|||||||
let count = 0; // 计数器
|
let count = 0; // 计数器
|
||||||
// 外循环:未排序区间为 [0, i]
|
// 外循环:未排序区间为 [0, i]
|
||||||
for (let i = nums.length - 1; i > 0; i--) {
|
for (let i = nums.length - 1; i > 0; i--) {
|
||||||
// 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
|
// 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
|
||||||
for (let j = 0; j < i; j++) {
|
for (let j = 0; j < i; j++) {
|
||||||
if (nums[j] > nums[j + 1]) {
|
if (nums[j] > nums[j + 1]) {
|
||||||
// 交换 nums[j] 与 nums[j + 1]
|
// 交换 nums[j] 与 nums[j + 1]
|
||||||
|
@ -659,10 +659,7 @@ $$
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
// 初始化 dp 表,用于存储子问题的解
|
// 初始化 dp 表,用于存储子问题的解
|
||||||
const dp = Array.from(
|
const dp = Array.from({ length: n + 1 }, () => new Array(3));
|
||||||
{ length: n + 1 },
|
|
||||||
() => new Array(3)
|
|
||||||
);
|
|
||||||
// 初始状态:预设最小子问题的解
|
// 初始状态:预设最小子问题的解
|
||||||
dp[1][1] = 1;
|
dp[1][1] = 1;
|
||||||
dp[1][2] = 0;
|
dp[1][2] = 0;
|
||||||
|
@ -185,8 +185,7 @@ $$
|
|||||||
}
|
}
|
||||||
// 计算不放入和放入物品 i 的最大价值
|
// 计算不放入和放入物品 i 的最大价值
|
||||||
const no = knapsackDFS(wgt, val, i - 1, c);
|
const no = knapsackDFS(wgt, val, i - 1, c);
|
||||||
const yes =
|
const yes = knapsackDFS(wgt, val, i - 1, c - wgt[i - 1]) + val[i - 1];
|
||||||
knapsackDFS(wgt, val, i - 1, c - wgt[i - 1]) + val[i - 1];
|
|
||||||
// 返回两种方案中价值更大的那一个
|
// 返回两种方案中价值更大的那一个
|
||||||
return Math.max(no, yes);
|
return Math.max(no, yes);
|
||||||
}
|
}
|
||||||
@ -438,7 +437,8 @@ $$
|
|||||||
}
|
}
|
||||||
// 计算不放入和放入物品 i 的最大价值
|
// 计算不放入和放入物品 i 的最大价值
|
||||||
const no = knapsackDFSMem(wgt, val, mem, i - 1, c);
|
const no = knapsackDFSMem(wgt, val, mem, i - 1, c);
|
||||||
const yes = knapsackDFSMem(wgt, val, mem, i - 1, c - wgt[i - 1]) + val[i - 1];
|
const yes =
|
||||||
|
knapsackDFSMem(wgt, val, mem, i - 1, c - wgt[i - 1]) + val[i - 1];
|
||||||
// 记录并返回两种方案中价值更大的那一个
|
// 记录并返回两种方案中价值更大的那一个
|
||||||
mem[i][c] = Math.max(no, yes);
|
mem[i][c] = Math.max(no, yes);
|
||||||
return mem[i][c];
|
return mem[i][c];
|
||||||
|
@ -193,17 +193,74 @@ status: new
|
|||||||
=== "JS"
|
=== "JS"
|
||||||
|
|
||||||
```javascript title="fractional_knapsack.js"
|
```javascript title="fractional_knapsack.js"
|
||||||
[class]{Item}-[func]{}
|
/* 物品 */
|
||||||
|
class Item {
|
||||||
|
constructor(w, v) {
|
||||||
|
this.w = w; // 物品重量
|
||||||
|
this.v = v; // 物品价值
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[class]{}-[func]{fractionalKnapsack}
|
/* 分数背包:贪心 */
|
||||||
|
function fractionalKnapsack(wgt, val, cap) {
|
||||||
|
// 创建物品列表,包含两个属性:重量、价值
|
||||||
|
const items = wgt.map((w, i) => new Item(w, val[i]));
|
||||||
|
// 按照单位价值 item.v / item.w 从高到低进行排序
|
||||||
|
items.sort((a, b) => b.v / b.w - a.v / a.w);
|
||||||
|
// 循环贪心选择
|
||||||
|
let res = 0;
|
||||||
|
for (const item of items) {
|
||||||
|
if (item.w <= cap) {
|
||||||
|
// 若剩余容量充足,则将当前物品整个装进背包
|
||||||
|
res += item.v;
|
||||||
|
cap -= item.w;
|
||||||
|
} else {
|
||||||
|
// 若剩余容量不足,则将当前物品的一部分装进背包
|
||||||
|
res += (item.v / item.w) * cap;
|
||||||
|
// 已无剩余容量,因此跳出循环
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "TS"
|
=== "TS"
|
||||||
|
|
||||||
```typescript title="fractional_knapsack.ts"
|
```typescript title="fractional_knapsack.ts"
|
||||||
[class]{Item}-[func]{}
|
/* 物品 */
|
||||||
|
class Item {
|
||||||
|
w: number; // 物品重量
|
||||||
|
v: number; // 物品价值
|
||||||
|
|
||||||
[class]{}-[func]{fractionalKnapsack}
|
constructor(w: number, v: number) {
|
||||||
|
this.w = w;
|
||||||
|
this.v = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 分数背包:贪心 */
|
||||||
|
function fractionalKnapsack(wgt: number[], val: number[], cap: number): number {
|
||||||
|
// 创建物品列表,包含两个属性:重量、价值
|
||||||
|
const items: Item[] = wgt.map((w, i) => new Item(w, val[i]));
|
||||||
|
// 按照单位价值 item.v / item.w 从高到低进行排序
|
||||||
|
items.sort((a, b) => b.v / b.w - a.v / a.w);
|
||||||
|
// 循环贪心选择
|
||||||
|
let res = 0;
|
||||||
|
for (const item of items) {
|
||||||
|
if (item.w <= cap) {
|
||||||
|
// 若剩余容量充足,则将当前物品整个装进背包
|
||||||
|
res += item.v;
|
||||||
|
cap -= item.w;
|
||||||
|
} else {
|
||||||
|
// 若剩余容量不足,则将当前物品的一部分装进背包
|
||||||
|
res += (item.v / item.w) * cap;
|
||||||
|
// 已无剩余容量,因此跳出循环
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "C"
|
=== "C"
|
||||||
|
@ -121,13 +121,47 @@ status: new
|
|||||||
=== "JS"
|
=== "JS"
|
||||||
|
|
||||||
```javascript title="coin_change_greedy.js"
|
```javascript title="coin_change_greedy.js"
|
||||||
[class]{}-[func]{coinChangeGreedy}
|
/* 零钱兑换:贪心 */
|
||||||
|
function coinChangeGreedy(coins, amt) {
|
||||||
|
// 假设 coins 数组有序
|
||||||
|
let i = coins.length - 1;
|
||||||
|
let count = 0;
|
||||||
|
// 循环进行贪心选择,直到无剩余金额
|
||||||
|
while (amt > 0) {
|
||||||
|
// 找到小于且最接近剩余金额的硬币
|
||||||
|
while (i > 0 && coins[i] > amt) {
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
// 选择 coins[i]
|
||||||
|
amt -= coins[i];
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
// 若未找到可行方案,则返回 -1
|
||||||
|
return amt === 0 ? count : -1;
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "TS"
|
=== "TS"
|
||||||
|
|
||||||
```typescript title="coin_change_greedy.ts"
|
```typescript title="coin_change_greedy.ts"
|
||||||
[class]{}-[func]{coinChangeGreedy}
|
/* 零钱兑换:贪心 */
|
||||||
|
function coinChangeGreedy(coins: number[], amt: number): number {
|
||||||
|
// 假设 coins 数组有序
|
||||||
|
let i = coins.length - 1;
|
||||||
|
let count = 0;
|
||||||
|
// 循环进行贪心选择,直到无剩余金额
|
||||||
|
while (amt > 0) {
|
||||||
|
// 找到小于且最接近剩余金额的硬币
|
||||||
|
while (i > 0 && coins[i] > amt) {
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
// 选择 coins[i]
|
||||||
|
amt -= coins[i];
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
// 若未找到可行方案,则返回 -1
|
||||||
|
return amt === 0 ? count : -1;
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "C"
|
=== "C"
|
||||||
|
@ -193,13 +193,53 @@ $$
|
|||||||
=== "JS"
|
=== "JS"
|
||||||
|
|
||||||
```javascript title="max_capacity.js"
|
```javascript title="max_capacity.js"
|
||||||
[class]{}-[func]{maxCapacity}
|
/* 最大容量:贪心 */
|
||||||
|
function maxCapacity(ht) {
|
||||||
|
// 初始化 i, j 分列数组两端
|
||||||
|
let i = 0,
|
||||||
|
j = ht.length - 1;
|
||||||
|
// 初始最大容量为 0
|
||||||
|
let res = 0;
|
||||||
|
// 循环贪心选择,直至两板相遇
|
||||||
|
while (i < j) {
|
||||||
|
// 更新最大容量
|
||||||
|
const cap = Math.min(ht[i], ht[j]) * (j - i);
|
||||||
|
res = Math.max(res, cap);
|
||||||
|
// 向内移动短板
|
||||||
|
if (ht[i] < ht[j]) {
|
||||||
|
i += 1;
|
||||||
|
} else {
|
||||||
|
j -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "TS"
|
=== "TS"
|
||||||
|
|
||||||
```typescript title="max_capacity.ts"
|
```typescript title="max_capacity.ts"
|
||||||
[class]{}-[func]{maxCapacity}
|
/* 最大容量:贪心 */
|
||||||
|
function maxCapacity(ht: number[]): number {
|
||||||
|
// 初始化 i, j 分列数组两端
|
||||||
|
let i = 0,
|
||||||
|
j = ht.length - 1;
|
||||||
|
// 初始最大容量为 0
|
||||||
|
let res = 0;
|
||||||
|
// 循环贪心选择,直至两板相遇
|
||||||
|
while (i < j) {
|
||||||
|
// 更新最大容量
|
||||||
|
const cap: number = Math.min(ht[i], ht[j]) * (j - i);
|
||||||
|
res = Math.max(res, cap);
|
||||||
|
// 向内移动短板
|
||||||
|
if (ht[i] < ht[j]) {
|
||||||
|
i += 1;
|
||||||
|
} else {
|
||||||
|
j -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "C"
|
=== "C"
|
||||||
|
@ -172,13 +172,51 @@ $$
|
|||||||
=== "JS"
|
=== "JS"
|
||||||
|
|
||||||
```javascript title="max_product_cutting.js"
|
```javascript title="max_product_cutting.js"
|
||||||
[class]{}-[func]{maxProductCutting}
|
/* 最大切分乘积:贪心 */
|
||||||
|
function maxProductCutting(n) {
|
||||||
|
// 当 n <= 3 时,必须切分出一个 1
|
||||||
|
if (n <= 3) {
|
||||||
|
return 1 * (n - 1);
|
||||||
|
}
|
||||||
|
// 贪心地切分出 3 ,a 为 3 的个数,b 为余数
|
||||||
|
let a = Math.floor(n / 3);
|
||||||
|
let b = n % 3;
|
||||||
|
if (b === 1) {
|
||||||
|
// 当余数为 1 时,将一对 1 * 3 转化为 2 * 2
|
||||||
|
return Math.pow(3, a - 1) * 2 * 2;
|
||||||
|
}
|
||||||
|
if (b === 2) {
|
||||||
|
// 当余数为 2 时,不做处理
|
||||||
|
return Math.pow(3, a) * 2;
|
||||||
|
}
|
||||||
|
// 当余数为 0 时,不做处理
|
||||||
|
return Math.pow(3, a);
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "TS"
|
=== "TS"
|
||||||
|
|
||||||
```typescript title="max_product_cutting.ts"
|
```typescript title="max_product_cutting.ts"
|
||||||
[class]{}-[func]{maxProductCutting}
|
/* 最大切分乘积:贪心 */
|
||||||
|
function maxProductCutting(n: number): number {
|
||||||
|
// 当 n <= 3 时,必须切分出一个 1
|
||||||
|
if (n <= 3) {
|
||||||
|
return 1 * (n - 1);
|
||||||
|
}
|
||||||
|
// 贪心地切分出 3 ,a 为 3 的个数,b 为余数
|
||||||
|
let a: number = Math.floor(n / 3);
|
||||||
|
let b: number = n % 3;
|
||||||
|
if (b === 1) {
|
||||||
|
// 当余数为 1 时,将一对 1 * 3 转化为 2 * 2
|
||||||
|
return Math.pow(3, a - 1) * 2 * 2;
|
||||||
|
}
|
||||||
|
if (b === 2) {
|
||||||
|
// 当余数为 2 时,不做处理
|
||||||
|
return Math.pow(3, a) * 2;
|
||||||
|
}
|
||||||
|
// 当余数为 0 时,不做处理
|
||||||
|
return Math.pow(3, a);
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "C"
|
=== "C"
|
||||||
|
@ -141,7 +141,10 @@ status: new
|
|||||||
|
|
||||||
```typescript title="binary_search_insertion.ts"
|
```typescript title="binary_search_insertion.ts"
|
||||||
/* 二分查找插入点(无重复元素) */
|
/* 二分查找插入点(无重复元素) */
|
||||||
function binarySearchInsertionSimple(nums: Array<number>, target: number): number {
|
function binarySearchInsertionSimple(
|
||||||
|
nums: Array<number>,
|
||||||
|
target: number
|
||||||
|
): number {
|
||||||
let i = 0,
|
let i = 0,
|
||||||
j = nums.length - 1; // 初始化双闭区间 [0, n-1]
|
j = nums.length - 1; // 初始化双闭区间 [0, n-1]
|
||||||
while (i <= j) {
|
while (i <= j) {
|
||||||
|
@ -330,7 +330,7 @@ comments: true
|
|||||||
// 单层循环,时间复杂度 O(n)
|
// 单层循环,时间复杂度 O(n)
|
||||||
for (let i = 0; i < nums.length; i++) {
|
for (let i = 0; i < nums.length; i++) {
|
||||||
if (m[target - nums[i]] !== undefined) {
|
if (m[target - nums[i]] !== undefined) {
|
||||||
return [m[target-nums[i]], i];
|
return [m[target - nums[i]], i];
|
||||||
} else {
|
} else {
|
||||||
m[nums[i]] = i;
|
m[nums[i]] = i;
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ comments: true
|
|||||||
function bubbleSort(nums) {
|
function bubbleSort(nums) {
|
||||||
// 外循环:未排序区间为 [0, i]
|
// 外循环:未排序区间为 [0, i]
|
||||||
for (let i = nums.length - 1; i > 0; i--) {
|
for (let i = nums.length - 1; i > 0; i--) {
|
||||||
// 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
|
// 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
|
||||||
for (let j = 0; j < i; j++) {
|
for (let j = 0; j < i; j++) {
|
||||||
if (nums[j] > nums[j + 1]) {
|
if (nums[j] > nums[j + 1]) {
|
||||||
// 交换 nums[j] 与 nums[j + 1]
|
// 交换 nums[j] 与 nums[j + 1]
|
||||||
@ -143,7 +143,7 @@ comments: true
|
|||||||
function bubbleSort(nums: number[]): void {
|
function bubbleSort(nums: number[]): void {
|
||||||
// 外循环:未排序区间为 [0, i]
|
// 外循环:未排序区间为 [0, i]
|
||||||
for (let i = nums.length - 1; i > 0; i--) {
|
for (let i = nums.length - 1; i > 0; i--) {
|
||||||
// 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
|
// 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
|
||||||
for (let j = 0; j < i; j++) {
|
for (let j = 0; j < i; j++) {
|
||||||
if (nums[j] > nums[j + 1]) {
|
if (nums[j] > nums[j + 1]) {
|
||||||
// 交换 nums[j] 与 nums[j + 1]
|
// 交换 nums[j] 与 nums[j + 1]
|
||||||
@ -380,7 +380,7 @@ comments: true
|
|||||||
// 外循环:未排序区间为 [0, i]
|
// 外循环:未排序区间为 [0, i]
|
||||||
for (let i = nums.length - 1; i > 0; i--) {
|
for (let i = nums.length - 1; i > 0; i--) {
|
||||||
let flag = false; // 初始化标志位
|
let flag = false; // 初始化标志位
|
||||||
// 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
|
// 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
|
||||||
for (let j = 0; j < i; j++) {
|
for (let j = 0; j < i; j++) {
|
||||||
if (nums[j] > nums[j + 1]) {
|
if (nums[j] > nums[j + 1]) {
|
||||||
// 交换 nums[j] 与 nums[j + 1]
|
// 交换 nums[j] 与 nums[j + 1]
|
||||||
@ -403,7 +403,7 @@ comments: true
|
|||||||
// 外循环:未排序区间为 [0, i]
|
// 外循环:未排序区间为 [0, i]
|
||||||
for (let i = nums.length - 1; i > 0; i--) {
|
for (let i = nums.length - 1; i > 0; i--) {
|
||||||
let flag = false; // 初始化标志位
|
let flag = false; // 初始化标志位
|
||||||
// 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
|
// 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
|
||||||
for (let j = 0; j < i; j++) {
|
for (let j = 0; j < i; j++) {
|
||||||
if (nums[j] > nums[j + 1]) {
|
if (nums[j] > nums[j + 1]) {
|
||||||
// 交换 nums[j] 与 nums[j + 1]
|
// 交换 nums[j] 与 nums[j + 1]
|
||||||
|
@ -155,17 +155,16 @@ comments: true
|
|||||||
|
|
||||||
```typescript title="binary_search_tree.ts"
|
```typescript title="binary_search_tree.ts"
|
||||||
/* 查找节点 */
|
/* 查找节点 */
|
||||||
function search(num: number): TreeNode | null {
|
search(num: number): TreeNode | null {
|
||||||
let cur = root;
|
let cur = this.root;
|
||||||
// 循环查找,越过叶节点后跳出
|
// 循环查找,越过叶节点后跳出
|
||||||
while (cur !== null) {
|
while (cur !== null) {
|
||||||
if (cur.val < num) {
|
// 目标节点在 cur 的右子树中
|
||||||
cur = cur.right; // 目标节点在 cur 的右子树中
|
if (cur.val < num) cur = cur.right;
|
||||||
} else if (cur.val > num) {
|
// 目标节点在 cur 的左子树中
|
||||||
cur = cur.left; // 目标节点在 cur 的左子树中
|
else if (cur.val > num) cur = cur.left;
|
||||||
} else {
|
// 找到目标节点,跳出循环
|
||||||
break; // 找到目标节点,跳出循环
|
else break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// 返回目标节点
|
// 返回目标节点
|
||||||
return cur;
|
return cur;
|
||||||
@ -489,7 +488,7 @@ comments: true
|
|||||||
else cur = cur.left;
|
else cur = cur.left;
|
||||||
}
|
}
|
||||||
// 插入节点
|
// 插入节点
|
||||||
let node = new TreeNode(num);
|
const node = new TreeNode(num);
|
||||||
if (pre.val < num) pre.right = node;
|
if (pre.val < num) pre.right = node;
|
||||||
else pre.left = node;
|
else pre.left = node;
|
||||||
}
|
}
|
||||||
@ -499,33 +498,28 @@ comments: true
|
|||||||
|
|
||||||
```typescript title="binary_search_tree.ts"
|
```typescript title="binary_search_tree.ts"
|
||||||
/* 插入节点 */
|
/* 插入节点 */
|
||||||
function insert(num: number): void {
|
insert(num: number): void {
|
||||||
// 若树为空,则初始化根节点
|
// 若树为空,则初始化根节点
|
||||||
if (root === null) {
|
if (this.root === null) {
|
||||||
root = new TreeNode(num);
|
this.root = new TreeNode(num);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let cur = root,
|
let cur: TreeNode | null = this.root,
|
||||||
pre: TreeNode | null = null;
|
pre: TreeNode | null = null;
|
||||||
// 循环查找,越过叶节点后跳出
|
// 循环查找,越过叶节点后跳出
|
||||||
while (cur !== null) {
|
while (cur !== null) {
|
||||||
if (cur.val === num) {
|
// 找到重复节点,直接返回
|
||||||
return; // 找到重复节点,直接返回
|
if (cur.val === num) return;
|
||||||
}
|
|
||||||
pre = cur;
|
pre = cur;
|
||||||
if (cur.val < num) {
|
// 插入位置在 cur 的右子树中
|
||||||
cur = cur.right as TreeNode; // 插入位置在 cur 的右子树中
|
if (cur.val < num) cur = cur.right;
|
||||||
} else {
|
// 插入位置在 cur 的左子树中
|
||||||
cur = cur.left as TreeNode; // 插入位置在 cur 的左子树中
|
else cur = cur.left;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// 插入节点
|
// 插入节点
|
||||||
let node = new TreeNode(num);
|
const node = new TreeNode(num);
|
||||||
if (pre!.val < num) {
|
if (pre!.val < num) pre!.right = node;
|
||||||
pre!.right = node;
|
else pre!.left = node;
|
||||||
} else {
|
|
||||||
pre!.left = node;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -1044,7 +1038,7 @@ comments: true
|
|||||||
// 子节点数量 = 0 or 1
|
// 子节点数量 = 0 or 1
|
||||||
if (cur.left === null || cur.right === null) {
|
if (cur.left === null || cur.right === null) {
|
||||||
// 当子节点数量 = 0 / 1 时, child = null / 该子节点
|
// 当子节点数量 = 0 / 1 时, child = null / 该子节点
|
||||||
let child = cur.left !== null ? cur.left : cur.right;
|
const child = cur.left !== null ? cur.left : cur.right;
|
||||||
// 删除节点 cur
|
// 删除节点 cur
|
||||||
if (cur !== this.root) {
|
if (cur !== this.root) {
|
||||||
if (pre.left === cur) pre.left = child;
|
if (pre.left === cur) pre.left = child;
|
||||||
@ -1073,57 +1067,48 @@ comments: true
|
|||||||
|
|
||||||
```typescript title="binary_search_tree.ts"
|
```typescript title="binary_search_tree.ts"
|
||||||
/* 删除节点 */
|
/* 删除节点 */
|
||||||
function remove(num: number): void {
|
remove(num: number): void {
|
||||||
// 若树为空,直接提前返回
|
// 若树为空,直接提前返回
|
||||||
if (root === null) {
|
if (this.root === null) return;
|
||||||
return;
|
let cur: TreeNode | null = this.root,
|
||||||
}
|
|
||||||
let cur = root,
|
|
||||||
pre: TreeNode | null = null;
|
pre: TreeNode | null = null;
|
||||||
// 循环查找,越过叶节点后跳出
|
// 循环查找,越过叶节点后跳出
|
||||||
while (cur !== null) {
|
while (cur !== null) {
|
||||||
// 找到待删除节点,跳出循环
|
// 找到待删除节点,跳出循环
|
||||||
if (cur.val === num) {
|
if (cur.val === num) break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
pre = cur;
|
pre = cur;
|
||||||
if (cur.val < num) {
|
// 待删除节点在 cur 的右子树中
|
||||||
cur = cur.right as TreeNode; // 待删除节点在 cur 的右子树中
|
if (cur.val < num) cur = cur.right;
|
||||||
} else {
|
// 待删除节点在 cur 的左子树中
|
||||||
cur = cur.left as TreeNode; // 待删除节点在 cur 的左子树中
|
else cur = cur.left;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// 若无待删除节点,则直接返回
|
// 若无待删除节点,则直接返回
|
||||||
if (cur === null) {
|
if (cur === null) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 子节点数量 = 0 or 1
|
// 子节点数量 = 0 or 1
|
||||||
if (cur.left === null || cur.right === null) {
|
if (cur.left === null || cur.right === null) {
|
||||||
// 当子节点数量 = 0 / 1 时, child = null / 该子节点
|
// 当子节点数量 = 0 / 1 时, child = null / 该子节点
|
||||||
let child = cur.left !== null ? cur.left : cur.right;
|
const child: TreeNode | null =
|
||||||
|
cur.left !== null ? cur.left : cur.right;
|
||||||
// 删除节点 cur
|
// 删除节点 cur
|
||||||
if (cur != root) {
|
if (cur !== this.root) {
|
||||||
if (pre!.left === cur) {
|
if (pre!.left === cur) pre!.left = child;
|
||||||
pre!.left = child;
|
else pre!.right = child;
|
||||||
} else {
|
|
||||||
pre!.right = child;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// 若删除节点为根节点,则重新指定根节点
|
// 若删除节点为根节点,则重新指定根节点
|
||||||
root = child;
|
this.root = child;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 子节点数量 = 2
|
// 子节点数量 = 2
|
||||||
else {
|
else {
|
||||||
// 获取中序遍历中 cur 的下一个节点
|
// 获取中序遍历中 cur 的下一个节点
|
||||||
let tmp = cur.right;
|
let tmp: TreeNode | null = cur.right;
|
||||||
while (tmp.left !== null) {
|
while (tmp!.left !== null) {
|
||||||
tmp = tmp.left;
|
tmp = tmp!.left;
|
||||||
}
|
}
|
||||||
// 递归删除节点 tmp
|
// 递归删除节点 tmp
|
||||||
remove(tmp!.val);
|
this.remove(tmp!.val);
|
||||||
// 用 tmp 覆盖 cur
|
// 用 tmp 覆盖 cur
|
||||||
cur.val = tmp.val;
|
cur.val = tmp!.val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
Loading…
Reference in New Issue
Block a user