From 92aa96d8f75942d47aa8e2711627c45e5ce9a906 Mon Sep 17 00:00:00 2001 From: Ming <37586974+mingXta@users.noreply.github.com> Date: Wed, 14 Dec 2022 11:03:28 +0800 Subject: [PATCH 01/11] Update array.md Add the C# code to docs ( Chapter of Array) Add the C# code to docs ( Chapter of Array) --- docs/chapter_array_and_linkedlist/array.md | 72 ++++++++++++++++++++-- 1 file changed, 67 insertions(+), 5 deletions(-) diff --git a/docs/chapter_array_and_linkedlist/array.md b/docs/chapter_array_and_linkedlist/array.md index caa7145b0..d2b8a482a 100644 --- a/docs/chapter_array_and_linkedlist/array.md +++ b/docs/chapter_array_and_linkedlist/array.md @@ -71,7 +71,11 @@ comments: true === "C#" ```csharp title="array.cs" + int[] arr = new int[5]; // { 0, 0, 0, 0, 0 } + int[] nums = { 1, 3, 2, 5, 4 }; + var arr2=new int[5]; // { 0, 0, 0, 0, 0 } + var nums2=new int[]{1,2,3,4,5}; ``` ## 数组优点 @@ -169,7 +173,14 @@ elementAddr = firtstElementAddr + elementLength * elementIndex === "C#" ```csharp title="array.cs" - + /* 随机返回一个数组元素 */ + int RandomAccess(int[] nums) + { + Random random=new(); + int randomIndex = random.Next(nums.Length); + int randomNum = nums[randomIndex]; + return randomNum; + } ``` ## 数组缺点 @@ -271,7 +282,18 @@ elementAddr = firtstElementAddr + elementLength * elementIndex === "C#" ```csharp title="array.cs" - + int[] Extend(int[] nums, int enlarge) + { + // 初始化一个扩展长度后的数组 + int[] res = new int[nums.Length + enlarge]; + // 将原数组中的所有元素复制到新数组 + for (int i = 0; i < nums.Length; i++) + { + res[i] = nums[i]; + } + // 返回扩展后的新数组 + return res; + } ``` **数组中插入或删除元素效率低下。** 假设我们想要在数组中间某位置插入一个元素,由于数组元素在内存中是 “紧挨着的” ,它们之间没有空间再放任何数据。因此,我们不得不将此索引之后的所有元素都向后移动一位,然后再把元素赋值给该索引。删除元素也是类似,需要把此索引之后的元素都向前移动一位。总体看有以下缺点: @@ -405,7 +427,24 @@ elementAddr = firtstElementAddr + elementLength * elementIndex === "C#" ```csharp title="array.cs" - + void Insert(int[] nums, int num, int index) + { + // 把索引 index 以及之后的所有元素向后移动一位 + for (int i = nums.Length - 1; i >= index; i--) + { + nums[i] = nums[i - 1]; + } + // 将 num 赋给 index 处元素 + nums[index] = num; + } + void Remove(int[] nums, int index) + { + // 把索引 index 之后的所有元素向前移动一位 + for (int i = index; i < nums.Length - 1; i++) + { + nums[i] = nums[i + 1]; + } + } ``` ## 数组常用操作 @@ -505,7 +544,21 @@ elementAddr = firtstElementAddr + elementLength * elementIndex === "C#" ```csharp title="array.cs" - + /* 遍历数组 */ + void Traverse(int[] nums) + { + int count = 0; + // 通过索引遍历数组 + for (int i = 0; i < nums.Length; i++) + { + count++; + } + // 直接遍历数组 + foreach (int num in nums) + { + count++; + } + } ``` **数组查找。** 通过遍历数组,查找数组内的指定元素,并输出对应索引。 @@ -588,7 +641,16 @@ elementAddr = firtstElementAddr + elementLength * elementIndex === "C#" ```csharp title="array.cs" - + /* 在数组中查找指定元素 */ + int Find(int[] nums, int target) + { + for (int i = 0; i < nums.Length; i++) + { + if (nums[i] == target) + return i; + } + return -1; + } ``` ## 数组典型应用 From d61196de3a0c591cede0e4a380baba0401bb3b77 Mon Sep 17 00:00:00 2001 From: Ming <37586974+mingXta@users.noreply.github.com> Date: Wed, 14 Dec 2022 11:22:14 +0800 Subject: [PATCH 02/11] Update array.md,fix md formatting errors Fix md formatting errors --- docs/chapter_array_and_linkedlist/array.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/chapter_array_and_linkedlist/array.md b/docs/chapter_array_and_linkedlist/array.md index d2b8a482a..0c9f796ab 100644 --- a/docs/chapter_array_and_linkedlist/array.md +++ b/docs/chapter_array_and_linkedlist/array.md @@ -641,7 +641,7 @@ elementAddr = firtstElementAddr + elementLength * elementIndex === "C#" ```csharp title="array.cs" - /* 在数组中查找指定元素 */ + /* 在数组中查找指定元素 */ int Find(int[] nums, int target) { for (int i = 0; i < nums.Length; i++) From 064d21a55d7e133e6ca605cacfd23913794f36ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E5=BD=A4?= <1195669834@qq.com> Date: Wed, 14 Dec 2022 13:54:49 +0800 Subject: [PATCH 03/11] Create Array.cs Add C# array code --- .../c#/chapter_array_and_linkedlist/Array.cs | 123 ++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 codes/c#/chapter_array_and_linkedlist/Array.cs diff --git a/codes/c#/chapter_array_and_linkedlist/Array.cs b/codes/c#/chapter_array_and_linkedlist/Array.cs new file mode 100644 index 000000000..5afabb46f --- /dev/null +++ b/codes/c#/chapter_array_and_linkedlist/Array.cs @@ -0,0 +1,123 @@ +namespace hello_algo.chapter_arrag_and_linkedlist +{ + public class Array + { + /* 随机返回一个数组元素 */ + + public static int RandomAccess(int[] nums) + { + Random random = new(); + int randomIndex = random.Next(nums.Length); + int randomNum = nums[randomIndex]; + return randomNum; + } + + /* 扩展数组长度 */ + + public static int[] Extend(int[] nums, int enlarge) + { + // 初始化一个扩展长度后的数组 + int[] res = new int[nums.Length + enlarge]; + // 将原数组中的所有元素复制到新数组 + for (int i = 0; i < nums.Length; i++) + { + res[i] = nums[i]; + } + // 返回扩展后的新数组 + return res; + } + + /* 在数组的索引 index 处插入元素 num */ + + public static void Insert(int[] nums, int num, int index) + { + // 把索引 index 以及之后的所有元素向后移动一位 + for (int i = nums.Length - 1; i >= index; i--) + { + nums[i] = nums[i - 1]; + } + // 将 num 赋给 index 处元素 + nums[index] = num; + } + + /* 删除索引 index 处元素 */ + + public static void Remove(int[] nums, int index) + { + // 把索引 index 之后的所有元素向前移动一位 + for (int i = index; i < nums.Length - 1; i++) + { + nums[i] = nums[i + 1]; + } + } + + /* 遍历数组 */ + + public static void Traverse(int[] nums) + { + int count = 0; + // 通过索引遍历数组 + for (int i = 0; i < nums.Length; i++) + { + count++; + } + // 直接遍历数组 + foreach (int num in nums) + { + count++; + } + } + + /* 在数组中查找指定元素 */ + + public static int Find(int[] nums, int target) + { + for (int i = 0; i < nums.Length; i++) + { + if (nums[i] == target) + return i; + } + return -1; + } + + /*辅助函数数组转字符串 */ + + public static string ToString(int[] nums) + { + return string.Join(",", nums); + } + + /* Driver Code */ + public static void Main() + { + /* 初始化数组 */ + int[] arr = new int[5]; + Console.WriteLine("数组 arr = " + ToString(arr)); + int[] nums = { 1, 3, 2, 5, 4 }; + Console.WriteLine("数组 nums = " + ToString(nums)); + + /* 随机访问 */ + int randomNum = RandomAccess(nums); + Console.WriteLine("在 nums 中获取随机元素 " + randomNum); + + /* 长度扩展 */ + nums = Extend(nums, 3); + Console.WriteLine("将数组长度扩展至 8 ,得到 nums = " + ToString(nums)); + + /* 插入元素 */ + Insert(nums, 6, 3); + Console.WriteLine("在索引 3 处插入数字 6 ,得到 nums = " + ToString(nums)); + + /* 删除元素 */ + Remove(nums, 2); + Console.WriteLine("删除索引 2 处的元素,得到 nums = " + ToString(nums)); + + /* 遍历数组 */ + Traverse(nums); + + /* 查找元素 */ + int index = Find(nums, 3); + Console.WriteLine("在 nums 中查找元素 3 ,得到索引 = " + index); + } + } +} \ No newline at end of file From 94f66d3f06557976c972bdad2203ca8c31f7abc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E5=BD=A4?= <1195669834@qq.com> Date: Wed, 14 Dec 2022 15:11:25 +0800 Subject: [PATCH 04/11] Update C# array code and doc Add some comments and make code specification --- codes/c#/chapter_array_and_linkedlist/Array.cs | 8 +++++++- docs/chapter_array_and_linkedlist/array.md | 10 +++++++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/codes/c#/chapter_array_and_linkedlist/Array.cs b/codes/c#/chapter_array_and_linkedlist/Array.cs index 5afabb46f..7aaa64acb 100644 --- a/codes/c#/chapter_array_and_linkedlist/Array.cs +++ b/codes/c#/chapter_array_and_linkedlist/Array.cs @@ -1,4 +1,10 @@ -namespace hello_algo.chapter_arrag_and_linkedlist +/* + * File: Array.cs + * Created Time: 2022-12-14 + * Author: mingXta (1195669834@qq.com) + */ + +namespace hello_algo.chapter_arrag_and_linkedlist { public class Array { diff --git a/docs/chapter_array_and_linkedlist/array.md b/docs/chapter_array_and_linkedlist/array.md index 0c9f796ab..392731639 100644 --- a/docs/chapter_array_and_linkedlist/array.md +++ b/docs/chapter_array_and_linkedlist/array.md @@ -71,6 +71,7 @@ comments: true === "C#" ```csharp title="array.cs" + /* 初始化数组 */ int[] arr = new int[5]; // { 0, 0, 0, 0, 0 } int[] nums = { 1, 3, 2, 5, 4 }; @@ -173,7 +174,7 @@ elementAddr = firtstElementAddr + elementLength * elementIndex === "C#" ```csharp title="array.cs" - /* 随机返回一个数组元素 */ + /* 随机返回一个数组元素 */ int RandomAccess(int[] nums) { Random random=new(); @@ -282,6 +283,7 @@ elementAddr = firtstElementAddr + elementLength * elementIndex === "C#" ```csharp title="array.cs" + /* 扩展数组长度 */ int[] Extend(int[] nums, int enlarge) { // 初始化一个扩展长度后的数组 @@ -386,7 +388,7 @@ elementAddr = firtstElementAddr + elementLength * elementIndex // 将 num 赋给 index 处元素 nums[index] = num; } - + /* 删除索引 index 处元素 */ function remove(nums, index) { // 把索引 index 之后的所有元素向前移动一位 @@ -427,6 +429,7 @@ elementAddr = firtstElementAddr + elementLength * elementIndex === "C#" ```csharp title="array.cs" + /* 在数组的索引 index 处插入元素 num */ void Insert(int[] nums, int num, int index) { // 把索引 index 以及之后的所有元素向后移动一位 @@ -437,6 +440,7 @@ elementAddr = firtstElementAddr + elementLength * elementIndex // 将 num 赋给 index 处元素 nums[index] = num; } + /* 删除索引 index 处元素 */ void Remove(int[] nums, int index) { // 把索引 index 之后的所有元素向前移动一位 @@ -544,7 +548,7 @@ elementAddr = firtstElementAddr + elementLength * elementIndex === "C#" ```csharp title="array.cs" - /* 遍历数组 */ + /* 遍历数组 */ void Traverse(int[] nums) { int count = 0; From f3430c059dc246f67060590171ed030ed7e49d28 Mon Sep 17 00:00:00 2001 From: Ming <37586974+mingXta@users.noreply.github.com> Date: Wed, 14 Dec 2022 19:42:39 +0800 Subject: [PATCH 05/11] Update Array.cs to remove the empty line --- .../c#/chapter_array_and_linkedlist/Array.cs | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/codes/c#/chapter_array_and_linkedlist/Array.cs b/codes/c#/chapter_array_and_linkedlist/Array.cs index 7aaa64acb..cb6115050 100644 --- a/codes/c#/chapter_array_and_linkedlist/Array.cs +++ b/codes/c#/chapter_array_and_linkedlist/Array.cs @@ -1,15 +1,14 @@ -/* - * File: Array.cs - * Created Time: 2022-12-14 - * Author: mingXta (1195669834@qq.com) - */ +/* +* File: Array.cs +* Created Time: 2022-12-14 +* Author: mingXta (1195669834@qq.com) +*/ namespace hello_algo.chapter_arrag_and_linkedlist { public class Array { /* 随机返回一个数组元素 */ - public static int RandomAccess(int[] nums) { Random random = new(); @@ -19,7 +18,6 @@ namespace hello_algo.chapter_arrag_and_linkedlist } /* 扩展数组长度 */ - public static int[] Extend(int[] nums, int enlarge) { // 初始化一个扩展长度后的数组 @@ -34,7 +32,6 @@ namespace hello_algo.chapter_arrag_and_linkedlist } /* 在数组的索引 index 处插入元素 num */ - public static void Insert(int[] nums, int num, int index) { // 把索引 index 以及之后的所有元素向后移动一位 @@ -47,7 +44,6 @@ namespace hello_algo.chapter_arrag_and_linkedlist } /* 删除索引 index 处元素 */ - public static void Remove(int[] nums, int index) { // 把索引 index 之后的所有元素向前移动一位 @@ -58,7 +54,6 @@ namespace hello_algo.chapter_arrag_and_linkedlist } /* 遍历数组 */ - public static void Traverse(int[] nums) { int count = 0; @@ -75,7 +70,6 @@ namespace hello_algo.chapter_arrag_and_linkedlist } /* 在数组中查找指定元素 */ - public static int Find(int[] nums, int target) { for (int i = 0; i < nums.Length; i++) @@ -86,8 +80,7 @@ namespace hello_algo.chapter_arrag_and_linkedlist return -1; } - /*辅助函数数组转字符串 */ - + /*辅助函数,数组转字符串 */ public static string ToString(int[] nums) { return string.Join(",", nums); @@ -126,4 +119,4 @@ namespace hello_algo.chapter_arrag_and_linkedlist Console.WriteLine("在 nums 中查找元素 3 ,得到索引 = " + index); } } -} \ No newline at end of file +} From 8435fc69f9ec2df4207e78935b25923893fc1c8f Mon Sep 17 00:00:00 2001 From: Yudong Jin Date: Wed, 14 Dec 2022 23:04:56 +0800 Subject: [PATCH 06/11] Update Array.cs --- codes/c#/chapter_array_and_linkedlist/Array.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/codes/c#/chapter_array_and_linkedlist/Array.cs b/codes/c#/chapter_array_and_linkedlist/Array.cs index cb6115050..8f836a4f1 100644 --- a/codes/c#/chapter_array_and_linkedlist/Array.cs +++ b/codes/c#/chapter_array_and_linkedlist/Array.cs @@ -4,7 +4,7 @@ * Author: mingXta (1195669834@qq.com) */ -namespace hello_algo.chapter_arrag_and_linkedlist +namespace hello_algo.chapter_array_and_linkedlist { public class Array { From 9e5389066b9343b18f33ac3b4abd0df1bac21d7d Mon Sep 17 00:00:00 2001 From: justin Date: Wed, 14 Dec 2022 23:44:58 +0800 Subject: [PATCH 07/11] Add and Update the module TypeScript code (Chapter of Tree) --- codes/typescript/module/PrintUtil.ts | 82 +++++++++++++++++++++++++++- codes/typescript/module/TreeNode.ts | 51 +++++++++++++++++ 2 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 codes/typescript/module/TreeNode.ts diff --git a/codes/typescript/module/PrintUtil.ts b/codes/typescript/module/PrintUtil.ts index c2e3f3c75..9174be159 100644 --- a/codes/typescript/module/PrintUtil.ts +++ b/codes/typescript/module/PrintUtil.ts @@ -1,11 +1,26 @@ /* * File: PrintUtil.ts - * Created Time: 2022-12-10 + * Created Time: 2022-12-13 * Author: Justin (xiefahit@gmail.com) */ import ListNode from './ListNode'; +import { TreeNode } from './TreeNode'; +class Trunk { + prev: Trunk | null; + str: string; + + constructor(prev: Trunk | null, str: string) { + this.prev = prev; + this.str = str; + } +} + +/** + * Print a linked list + * @param head + */ function printLinkedList(head: ListNode | null): void { const list: string[] = []; while (head !== null) { @@ -15,4 +30,67 @@ function printLinkedList(head: ListNode | null): void { console.log(list.join(' -> ')); } -export { printLinkedList }; +/** + * The interface of the tree printer + * This tree printer is borrowed from TECHIE DELIGHT + * https://www.techiedelight.com/c-program-print-binary-tree/ + * @param root + */ +function printTree(root: TreeNode | null) { + printTreeHelper(root, null, false); +} + +/** + * Print a binary tree + * @param root + * @param prev + * @param isLeft + */ +function printTreeHelper(root: TreeNode | null, prev: Trunk | null, isLeft: boolean) { + if (root === null) { + return; + } + + let prev_str = ' '; + const trunk = new Trunk(prev, prev_str); + + printTreeHelper(root.right, trunk, true); + + if (prev === null) { + trunk.str = '———'; + } else if (isLeft) { + trunk.str = '/———'; + prev_str = ' |'; + } else { + trunk.str = '\\———'; + prev.str = prev_str; + } + + showTrunks(trunk); + console.log(' ' + root.val); + + if (prev) { + prev.str = prev_str; + } + trunk.str = ' |'; + + printTreeHelper(root.left, trunk, false); +} + +/** + * Helper function to print branches of the binary tree + * @param p + */ +function showTrunks(p: Trunk | null) { + if (p === null) { + return; + } + + showTrunks(p.prev); + process.stdout.write(p.str); + // ts-node to execute, we need to install type definitions for node + // solve: npm i --save-dev @types/node + // restart the vscode +} + +export { printLinkedList, printTree }; diff --git a/codes/typescript/module/TreeNode.ts b/codes/typescript/module/TreeNode.ts new file mode 100644 index 000000000..0bc783aa9 --- /dev/null +++ b/codes/typescript/module/TreeNode.ts @@ -0,0 +1,51 @@ +/* + * File: TreeNode.ts + * Created Time: 2022-12-13 + * Author: Justin (xiefahit@gmail.com) + */ + +/** + * Definition for a binary tree node. + */ +class TreeNode { + val: number; + left: TreeNode | null; + right: TreeNode | null; + + constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { + this.val = val === undefined ? 0 : val; // 结点值 + this.left = left === undefined ? null : left; // 左子结点指针 + this.right = right === undefined ? null : right; // 右子结点指针 + } +} + +/** + * Generate a binary tree with an array + * @param arr + * @return + */ +function arrToTree(arr: (number | null)[]): TreeNode | null { + if (arr.length === 0) { + return null; + } + + const root = new TreeNode(arr[0] as number); + const queue = [root]; + let i = 1; + while (queue.length) { + let node = queue.shift() as TreeNode; + if (arr[i] !== null) { + node.left = new TreeNode(arr[i] as number); + queue.push(node.left); + } + i++; + if (arr[i] !== null) { + node.right = new TreeNode(arr[i] as number); + queue.push(node.right); + } + i++; + } + return root; +} + +export { TreeNode, arrToTree }; From 031c61fff3af4822e800610cb7f6f9ab431bc098 Mon Sep 17 00:00:00 2001 From: justin Date: Wed, 14 Dec 2022 23:45:54 +0800 Subject: [PATCH 08/11] Add the TypeScript code (Chapter of Tree) --- .../chapter_tree/binary_search_tree.ts | 172 ++++++++++++++++++ codes/typescript/chapter_tree/binary_tree.ts | 35 ++++ .../chapter_tree/binary_tree_bfs.ts | 39 ++++ .../chapter_tree/binary_tree_dfs.ts | 67 +++++++ 4 files changed, 313 insertions(+) create mode 100644 codes/typescript/chapter_tree/binary_search_tree.ts create mode 100644 codes/typescript/chapter_tree/binary_tree.ts create mode 100644 codes/typescript/chapter_tree/binary_tree_bfs.ts create mode 100644 codes/typescript/chapter_tree/binary_tree_dfs.ts diff --git a/codes/typescript/chapter_tree/binary_search_tree.ts b/codes/typescript/chapter_tree/binary_search_tree.ts new file mode 100644 index 000000000..6dad83421 --- /dev/null +++ b/codes/typescript/chapter_tree/binary_search_tree.ts @@ -0,0 +1,172 @@ +/** + * File: binary_search_tree.ts + * Created Time: 2022-12-14 + * Author: Justin (xiefahit@gmail.com) + */ + +import { TreeNode } from '../module/TreeNode'; +import { printTree } from '../module/PrintUtil'; + +/* 二叉搜索树 */ +let root: TreeNode | null; + +function BinarySearchTree(nums: number[]): void { + nums.sort((a, b) => a - b); // 排序数组 + root = buildTree(nums, 0, nums.length - 1); // 构建二叉搜索树 +} + +/* 获取二叉树根结点 */ +function getRoot(): TreeNode | null { + return root; +} + +/* 构建二叉搜索树 */ +function buildTree(nums: number[], i: number, j: number): TreeNode | null { + if (i > j) { + return null; + } + // 将数组中间结点作为根结点 + let mid = Math.floor((i + j) / 2); + let root = new TreeNode(nums[mid]); + // 递归建立左子树和右子树 + root.left = buildTree(nums, i, mid - 1); + root.right = buildTree(nums, mid + 1, j); + return root; +} + +/* 查找结点 */ +function search(num: number): TreeNode | null { + let cur = root; + // 循环查找,越过叶结点后跳出 + while (cur !== null) { + if (cur.val < num) { + cur = cur.right; // 目标结点在 root 的右子树中 + } else if (cur.val > num) { + cur = cur.left; // 目标结点在 root 的左子树中 + } else { + break; // 找到目标结点,跳出循环 + } + } + // 返回目标结点 + return cur; +} + +/* 插入结点 */ +function insert(num: number): TreeNode | null { + // 若树为空,直接提前返回 + if (root === null) { + return null; + } + let cur = root, + pre: TreeNode | null = null; + // 循环查找,越过叶结点后跳出 + while (cur !== null) { + if (cur.val === num) { + return null; // 找到重复结点,直接返回 + } + pre = cur; + if (cur.val < num) { + cur = cur.right as TreeNode; // 插入位置在 root 的右子树中 + } else { + cur = cur.left as TreeNode; // 插入位置在 root 的左子树中 + } + } + // 插入结点 val + let node = new TreeNode(num); + if (pre!.val < num) { + pre!.right = node; + } else { + pre!.left = node; + } + return node; +} + +/* 删除结点 */ +function remove(num: number): TreeNode | null { + // 若树为空,直接提前返回 + if (root === null) { + return null; + } + let cur = root, + pre: TreeNode | null = null; + // 循环查找,越过叶结点后跳出 + while (cur !== null) { + // 找到待删除结点,跳出循环 + if (cur.val === num) { + break; + } + pre = cur; + if (cur.val < num) { + cur = cur.right as TreeNode; // 待删除结点在 root 的右子树中 + } else { + cur = cur.left as TreeNode; // 待删除结点在 root 的左子树中 + } + } + // 若无待删除结点,则直接返回 + if (cur === null) { + return null; + } + // 子结点数量 = 0 or 1 + if (cur.left === null || cur.right === null) { + // 当子结点数量 = 0 / 1 时, child = null / 该子结点 + let child = cur.left !== null ? cur.left : cur.right; + // 删除结点 cur + if (pre!.left === cur) { + pre!.left = child; + } else { + pre!.right = child; + } + } + // 子结点数量 = 2 + else { + // 获取中序遍历中 cur 的下一个结点 + let next = min(cur.right); + let tmp = next!.val; + // 递归删除结点 nex + remove(next!.val); + // 将 nex 的值复制给 cur + cur.val = tmp; + } + return cur; +} + +/* 获取最小结点 */ +function min(root: TreeNode | null): TreeNode | null { + if (root === null) { + return null; + } + // 循环访问左子结点,直到叶结点时为最小结点,跳出 + while (root.left !== null) { + root = root.left; + } + return root; +} + +/* Driver Code */ +/* 初始化二叉搜索树 */ +const nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; +BinarySearchTree(nums); +console.log('\n初始化的二叉树为\n'); +printTree(getRoot()); + +/* 查找结点 */ +let node = search(5); +console.log('\n查找到的结点对象为 ' + node + ',结点值 = ' + node!.val); + +/* 插入结点 */ +node = insert(16); +console.log('\n插入结点 16 后,二叉树为\n'); +printTree(getRoot()); + +/* 删除结点 */ +remove(1); +console.log('\n删除结点 1 后,二叉树为\n'); +printTree(getRoot()); +remove(2); +console.log('\n删除结点 2 后,二叉树为\n'); +printTree(getRoot()); +remove(4); +console.log('\n删除结点 4 后,二叉树为\n'); +printTree(getRoot()); + +export {}; diff --git a/codes/typescript/chapter_tree/binary_tree.ts b/codes/typescript/chapter_tree/binary_tree.ts new file mode 100644 index 000000000..c7e16bd76 --- /dev/null +++ b/codes/typescript/chapter_tree/binary_tree.ts @@ -0,0 +1,35 @@ +/** + * File: binary_tree.ts + * Created Time: 2022-12-13 + * Author: Justin (xiefahit@gmail.com) + */ + +import { TreeNode } from '../module/TreeNode'; +import { printTree } from '../module/PrintUtil'; + +/* 初始化二叉树 */ +// 初始化结点 +let n1 = new TreeNode(1), + n2 = new TreeNode(2), + n3 = new TreeNode(3), + n4 = new TreeNode(4), + n5 = new TreeNode(5); +// 构建引用指向(即指针) +n1.left = n2; +n1.right = n3; +n2.left = n4; +n2.right = n5; +console.log('\n初始化二叉树\n'); +printTree(n1); + +/* 插入与删除结点 */ +const P = new TreeNode(0); +// 在 n1 -> n2 中间插入结点 P +n1.left = P; +P.left = n2; +console.log('\n插入结点 P 后\n'); +printTree(n1); +// 删除结点 P +n1.left = n2; +console.log('\n删除结点 P 后\n'); +printTree(n1); diff --git a/codes/typescript/chapter_tree/binary_tree_bfs.ts b/codes/typescript/chapter_tree/binary_tree_bfs.ts new file mode 100644 index 000000000..1e57ef62d --- /dev/null +++ b/codes/typescript/chapter_tree/binary_tree_bfs.ts @@ -0,0 +1,39 @@ +/** + * File: binary_tree_bfs.ts + * Created Time: 2022-12-14 + * Author: Justin (xiefahit@gmail.com) + */ + +import { type TreeNode } from '../module/TreeNode'; +import { arrToTree } from '../module/TreeNode'; +import { printTree } from '../module/PrintUtil'; + +/* 层序遍历 */ +function hierOrder(root: TreeNode | null): number[] { + // 初始化队列,加入根结点 + const queue = [root]; + // 初始化一个列表,用于保存遍历序列 + const list: number[] = []; + while (queue.length) { + let node = queue.shift() as TreeNode; // 队列出队 + list.push(node.val); // 保存结点 + if (node.left) { + queue.push(node.left); // 左子结点入队 + } + if (node.right) { + queue.push(node.right); // 右子结点入队 + } + } + return list; +} + +/* Driver Code */ +/* 初始化二叉树 */ +// 这里借助了一个从数组直接生成二叉树的函数 +var root = arrToTree([1, 2, 3, 4, 5, 6, 7, null, null, null, null, null, null, null, null]); +console.log('\n初始化二叉树\n'); +printTree(root); + +/* 层序遍历 */ +const list = hierOrder(root); +console.log('\n层序遍历的结点打印序列 = ' + list); diff --git a/codes/typescript/chapter_tree/binary_tree_dfs.ts b/codes/typescript/chapter_tree/binary_tree_dfs.ts new file mode 100644 index 000000000..d9e982df1 --- /dev/null +++ b/codes/typescript/chapter_tree/binary_tree_dfs.ts @@ -0,0 +1,67 @@ +/** + * File: binary_tree_dfs.ts + * Created Time: 2022-12-14 + * Author: Justin (xiefahit@gmail.com) + */ + +import { type TreeNode } from '../module/TreeNode'; +import { arrToTree } from '../module/TreeNode'; +import { printTree } from '../module/PrintUtil'; + +// 初始化列表,用于存储遍历序列 +const list: number[] = []; + +/* 前序遍历 */ +function preOrder(root: TreeNode | null): void { + if (root === null) { + return; + } + // 访问优先级:根结点 -> 左子树 -> 右子树 + list.push(root.val); + preOrder(root.left); + preOrder(root.right); +} + +/* 中序遍历 */ +function inOrder(root: TreeNode | null): void { + if (root === null) { + return; + } + // 访问优先级:左子树 -> 根结点 -> 右子树 + inOrder(root.left); + list.push(root.val); + inOrder(root.right); +} + +/* 后序遍历 */ +function postOrder(root: TreeNode | null): void { + if (root === null) { + return; + } + // 访问优先级:左子树 -> 右子树 -> 根结点 + postOrder(root.left); + postOrder(root.right); + list.push(root.val); +} + +/* Driver Code */ +/* 初始化二叉树 */ +// 这里借助了一个从数组直接生成二叉树的函数 +const root = arrToTree([1, 2, 3, 4, 5, 6, 7, null, null, null, null, null, null, null, null]); +console.log('\n初始化二叉树\n'); +printTree(root); + +/* 前序遍历 */ +list.length = 0; +preOrder(root); +console.log('\n前序遍历的结点打印序列 = ' + list); + +/* 中序遍历 */ +list.length = 0; +inOrder(root); +console.log('\n中序遍历的结点打印序列 = ' + list); + +/* 后序遍历 */ +list.length = 0; +postOrder(root); +console.log('\n后序遍历的结点打印序列 = ' + list); From 3e9c3fc34fd25dc71e67c6e85a17389115730c65 Mon Sep 17 00:00:00 2001 From: justin Date: Thu, 15 Dec 2022 00:00:40 +0800 Subject: [PATCH 09/11] Add the TypeScript code to binary tree docs (Chapter of Tree) --- docs/chapter_tree/binary_tree.md | 87 +++++++++++++++++++++++++++++--- 1 file changed, 80 insertions(+), 7 deletions(-) diff --git a/docs/chapter_tree/binary_tree.md b/docs/chapter_tree/binary_tree.md index 84270be01..81d6e17aa 100644 --- a/docs/chapter_tree/binary_tree.md +++ b/docs/chapter_tree/binary_tree.md @@ -74,7 +74,18 @@ comments: true === "TypeScript" ```typescript title="" - + /* 链表结点类 */ + class TreeNode { + val: number; + left: TreeNode | null; + right: TreeNode | null; + + constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { + this.val = val === undefined ? 0 : val; // 结点值 + this.left = left === undefined ? null : left; // 左子结点指针 + this.right = right === undefined ? null : right; // 右子结点指针 + } + } ``` === "C" @@ -215,7 +226,18 @@ comments: true === "TypeScript" ```typescript title="binary_tree.ts" - + /* 初始化二叉树 */ + // 初始化结点 + let n1 = new TreeNode(1), + n2 = new TreeNode(2), + n3 = new TreeNode(3), + n4 = new TreeNode(4), + n5 = new TreeNode(5); + // 构建引用指向(即指针) + n1.left = n2; + n1.right = n3; + n2.left = n4; + n2.right = n5; ``` === "C" @@ -273,7 +295,6 @@ comments: true p := NewTreeNode(0) n1.Left = p p.Left = n2 - // 删除结点 P n1.Left = n2 ``` @@ -286,7 +307,6 @@ comments: true // 在 n1 -> n2 中间插入结点 P n1.left = P; P.left = n2; - // 删除结点 P n1.left = n2; ``` @@ -294,7 +314,13 @@ comments: true === "TypeScript" ```typescript title="binary_tree.ts" - + /* 插入与删除结点 */ + const P = new TreeNode(0); + // 在 n1 -> n2 中间插入结点 P + n1.left = P; + P.left = n2; + // 删除结点 P + n1.left = n2; ``` === "C" @@ -423,7 +449,6 @@ comments: true queue.push(node.left); // 左子结点入队 if (node.right) queue.push(node.right); // 右子结点入队 - } return list; } @@ -432,7 +457,24 @@ comments: true === "TypeScript" ```typescript title="binary_tree_bfs.ts" - + /* 层序遍历 */ + function hierOrder(root: TreeNode | null): number[] { + // 初始化队列,加入根结点 + const queue = [root]; + // 初始化一个列表,用于保存遍历序列 + const list: number[] = []; + while (queue.length) { + let node = queue.shift() as TreeNode; // 队列出队 + list.push(node.val); // 保存结点 + if (node.left) { + queue.push(node.left); // 左子结点入队 + } + if (node.right) { + queue.push(node.right); // 右子结点入队 + } + } + return list; + } ``` === "C" @@ -606,7 +648,38 @@ comments: true === "TypeScript" ```typescript title="binary_tree_dfs.ts" + /* 前序遍历 */ + function preOrder(root: TreeNode | null): void { + if (root === null) { + return; + } + // 访问优先级:根结点 -> 左子树 -> 右子树 + list.push(root.val); + preOrder(root.left); + preOrder(root.right); + } + /* 中序遍历 */ + function inOrder(root: TreeNode | null): void { + if (root === null) { + return; + } + // 访问优先级:左子树 -> 根结点 -> 右子树 + inOrder(root.left); + list.push(root.val); + inOrder(root.right); + } + + /* 后序遍历 */ + function postOrder(root: TreeNode | null): void { + if (root === null) { + return; + } + // 访问优先级:左子树 -> 右子树 -> 根结点 + postOrder(root.left); + postOrder(root.right); + list.push(root.val); + } ``` === "C" From 490f8d6685f4566f696b79cf14738936fb44e54d Mon Sep 17 00:00:00 2001 From: justin Date: Thu, 15 Dec 2022 00:01:10 +0800 Subject: [PATCH 10/11] Add the TypeScript code to binary search tree docs (Chapter of Tree) --- docs/chapter_tree/binary_search_tree.md | 96 ++++++++++++++++++++++++- 1 file changed, 93 insertions(+), 3 deletions(-) diff --git a/docs/chapter_tree/binary_search_tree.md b/docs/chapter_tree/binary_search_tree.md index 6dac4f7d7..9ff364329 100644 --- a/docs/chapter_tree/binary_search_tree.md +++ b/docs/chapter_tree/binary_search_tree.md @@ -132,7 +132,22 @@ comments: true === "TypeScript" ```typescript title="binary_search_tree.ts" - + /* 查找结点 */ + function search(num: number): TreeNode | null { + let cur = root; + // 循环查找,越过叶结点后跳出 + while (cur !== null) { + if (cur.val < num) { + cur = cur.right; // 目标结点在 root 的右子树中 + } else if (cur.val > num) { + cur = cur.left; // 目标结点在 root 的左子树中 + } else { + break; // 找到目标结点,跳出循环 + } + } + // 返回目标结点 + return cur; + } ``` === "C" @@ -280,7 +295,35 @@ comments: true === "TypeScript" ```typescript title="binary_search_tree.ts" - + /* 插入结点 */ + function insert(num: number): TreeNode | null { + // 若树为空,直接提前返回 + if (root === null) { + return null; + } + let cur = root, + pre: TreeNode | null = null; + // 循环查找,越过叶结点后跳出 + while (cur !== null) { + if (cur.val === num) { + return null; // 找到重复结点,直接返回 + } + pre = cur; + if (cur.val < num) { + cur = cur.right as TreeNode; // 插入位置在 root 的右子树中 + } else { + cur = cur.left as TreeNode; // 插入位置在 root 的左子树中 + } + } + // 插入结点 val + let node = new TreeNode(num); + if (pre!.val < num) { + pre!.right = node; + } else { + pre!.left = node; + } + return node; + } ``` === "C" @@ -547,7 +590,54 @@ comments: true === "TypeScript" ```typescript title="binary_search_tree.ts" - + /* 删除结点 */ + function remove(num: number): TreeNode | null { + // 若树为空,直接提前返回 + if (root === null) { + return null; + } + let cur = root, + pre: TreeNode | null = null; + // 循环查找,越过叶结点后跳出 + while (cur !== null) { + // 找到待删除结点,跳出循环 + if (cur.val === num) { + break; + } + pre = cur; + if (cur.val < num) { + cur = cur.right as TreeNode; // 待删除结点在 root 的右子树中 + } else { + cur = cur.left as TreeNode; // 待删除结点在 root 的左子树中 + } + } + // 若无待删除结点,则直接返回 + if (cur === null) { + return null; + } + // 子结点数量 = 0 or 1 + if (cur.left === null || cur.right === null) { + // 当子结点数量 = 0 / 1 时, child = null / 该子结点 + let child = cur.left !== null ? cur.left : cur.right; + // 删除结点 cur + if (pre!.left === cur) { + pre!.left = child; + } else { + pre!.right = child; + } + } + // 子结点数量 = 2 + else { + // 获取中序遍历中 cur 的下一个结点 + let next = min(cur.right); + let tmp = next!.val; + // 递归删除结点 nex + remove(next!.val); + // 将 nex 的值复制给 cur + cur.val = tmp; + } + return cur; + } ``` === "C" From b3d642fa85b4f1f8da4c65c9b249529cfabe7a53 Mon Sep 17 00:00:00 2001 From: Yudong Jin Date: Thu, 15 Dec 2022 01:12:03 +0800 Subject: [PATCH 11/11] Update C# folder name. --- codes/{c# => csharp}/chapter_array_and_linkedlist/Array.cs | 0 deploy.sh | 1 + mkdocs.yml | 1 + 3 files changed, 2 insertions(+) rename codes/{c# => csharp}/chapter_array_and_linkedlist/Array.cs (100%) diff --git a/codes/c#/chapter_array_and_linkedlist/Array.cs b/codes/csharp/chapter_array_and_linkedlist/Array.cs similarity index 100% rename from codes/c#/chapter_array_and_linkedlist/Array.cs rename to codes/csharp/chapter_array_and_linkedlist/Array.cs diff --git a/deploy.sh b/deploy.sh index eea018653..96a633cba 100644 --- a/deploy.sh +++ b/deploy.sh @@ -1,3 +1,4 @@ +rm -rf ./site mkdocs build --clean cd site git init diff --git a/mkdocs.yml b/mkdocs.yml index 35fa041a1..47406412b 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -33,6 +33,7 @@ theme: # - navigation.tabs # - navigation.tabs.sticky # - navigation.top + - navigation.footer - navigation.tracking - search.highlight - search.share