From 8733557f00b413587111df9701f957bcd3587fe2 Mon Sep 17 00:00:00 2001 From: Yudong Jin Date: Sat, 24 Dec 2022 17:05:58 +0800 Subject: [PATCH] Update C# code. --- .../chapter_array_and_linkedlist/list.cs | 2 +- .../time_complexity.cs | 4 +- .../chapter_stack_and_queue/array_queue.cs | 41 ++++++++++++------- codes/csharp/chapter_tree/avl_tree.cs | 9 ---- .../linked_list.md | 4 +- docs/chapter_array_and_linkedlist/list.md | 20 ++++----- .../space_complexity.md | 12 +++--- .../time_complexity.md | 8 ++-- docs/chapter_hashing/hash_map.md | 5 --- docs/chapter_searching/binary_search.md | 2 +- docs/chapter_sorting/merge_sort.md | 4 +- docs/chapter_sorting/quick_sort.md | 12 +----- docs/chapter_stack_and_queue/queue.md | 40 ++++++++---------- docs/chapter_stack_and_queue/stack.md | 10 ----- docs/chapter_tree/avl_tree.md | 17 ++------ docs/chapter_tree/binary_tree.md | 16 +++++--- 16 files changed, 88 insertions(+), 118 deletions(-) diff --git a/codes/csharp/chapter_array_and_linkedlist/list.cs b/codes/csharp/chapter_array_and_linkedlist/list.cs index 87bb2f2a4..4f702163f 100644 --- a/codes/csharp/chapter_array_and_linkedlist/list.cs +++ b/codes/csharp/chapter_array_and_linkedlist/list.cs @@ -25,7 +25,7 @@ namespace hello_algo.chapter_array_and_linkedlist Console.WriteLine("访问索引 1 处的元素,得到 num = " + num); /* 更新元素 */ - list[1]=0; + list[1] = 0; Console.WriteLine("将索引 1 处的元素更新为 0 ,得到 list = " + string.Join(",", list)); /* 清空列表 */ diff --git a/codes/csharp/chapter_computational_complexity/time_complexity.cs b/codes/csharp/chapter_computational_complexity/time_complexity.cs index 2bbd01763..ac7b405a9 100644 --- a/codes/csharp/chapter_computational_complexity/time_complexity.cs +++ b/codes/csharp/chapter_computational_complexity/time_complexity.cs @@ -14,7 +14,7 @@ namespace hello_algo.chapter_computational_complexity { int a = 1; // +0(技巧 1) a = a + n; // +0(技巧 1) - // +n(技巧 2) + // +n(技巧 2) for (int i = 0; i < 5 * n + 1; i++) { Console.WriteLine(0); @@ -101,7 +101,7 @@ namespace hello_algo.chapter_computational_complexity static int bubbleSort(int[] nums) { int count = 0; // 计数器 - // 外循环:待排序元素数量为 n-1, n-2, ..., 1 + // 外循环:待排序元素数量为 n-1, n-2, ..., 1 for (int i = nums.Length - 1; i > 0; i--) { // 内循环:冒泡操作 diff --git a/codes/csharp/chapter_stack_and_queue/array_queue.cs b/codes/csharp/chapter_stack_and_queue/array_queue.cs index 5ad6115ec..81085a368 100644 --- a/codes/csharp/chapter_stack_and_queue/array_queue.cs +++ b/codes/csharp/chapter_stack_and_queue/array_queue.cs @@ -10,36 +10,43 @@ namespace hello_algo.chapter_stack_and_queue { /* 基于环形数组实现的队列 */ - class ArrayQueue { + class ArrayQueue + { private int[] nums; // 用于存储队列元素的数组 private int front = 0; // 头指针,指向队首 private int rear = 0; // 尾指针,指向队尾 + 1 - public ArrayQueue(int capacity) { + public ArrayQueue(int capacity) + { // 初始化数组 nums = new int[capacity]; } /* 获取队列的容量 */ - public int capacity() { + public int capacity() + { return nums.Length; } /* 获取队列的长度 */ - public int size() { + public int size() + { int capacity = this.capacity(); // 由于将数组看作为环形,可能 rear < front ,因此需要取余数 return (capacity + rear - front) % capacity; } /* 判断队列是否为空 */ - public bool isEmpty() { + public bool isEmpty() + { return rear - front == 0; } /* 入队 */ - public void offer(int num) { - if (size() == capacity()) { + public void offer(int num) + { + if (size() == capacity()) + { Console.WriteLine("队列已满"); return; } @@ -50,7 +57,8 @@ namespace hello_algo.chapter_stack_and_queue } /* 出队 */ - public int poll() { + public int poll() + { int num = peek(); // 队头指针向后移动一位,若越过尾部则返回到数组头部 front = (front + 1) % capacity(); @@ -58,26 +66,30 @@ namespace hello_algo.chapter_stack_and_queue } /* 访问队首元素 */ - public int peek() { + public int peek() + { if (isEmpty()) throw new Exception(); return nums[front]; } /* 返回数组 */ - public int[] toArray() { + public int[] toArray() + { int size = this.size(); int capacity = this.capacity(); // 仅转换有效长度范围内的列表元素 int[] res = new int[size]; - for (int i = 0, j = front; i < size; i++, j++) { + for (int i = 0, j = front; i < size; i++, j++) + { res[i] = nums[j % capacity]; } return res; } } - public class array_queue { + public class array_queue + { [Test] public void Test() { @@ -91,7 +103,7 @@ namespace hello_algo.chapter_stack_and_queue queue.offer(2); queue.offer(5); queue.offer(4); - Console.WriteLine("队列 queue = " + string.Join(",",queue.toArray())); + Console.WriteLine("队列 queue = " + string.Join(",", queue.toArray())); /* 访问队首元素 */ int peek = queue.peek(); @@ -110,7 +122,8 @@ namespace hello_algo.chapter_stack_and_queue Console.WriteLine("队列是否为空 = " + isEmpty); /* 测试环形数组 */ - for (int i = 0; i < 10; i++) { + for (int i = 0; i < 10; i++) + { queue.offer(i); queue.poll(); Console.WriteLine("第 " + i + " 轮入队 + 出队后 queue = " + string.Join(",", queue.toArray())); diff --git a/codes/csharp/chapter_tree/avl_tree.cs b/codes/csharp/chapter_tree/avl_tree.cs index f2dcde219..99ec17f63 100644 --- a/codes/csharp/chapter_tree/avl_tree.cs +++ b/codes/csharp/chapter_tree/avl_tree.cs @@ -40,9 +40,6 @@ namespace hello_algo.chapter_tree /* 右旋操作 */ TreeNode? rightRotate(TreeNode? node) { - if (node == null) - return null; - TreeNode? child = node.left; TreeNode? grandChild = child?.right; // 以 child 为原点,将 node 向右旋转 @@ -58,9 +55,6 @@ namespace hello_algo.chapter_tree /* 左旋操作 */ TreeNode? leftRotate(TreeNode? node) { - if (node == null) - return null; - TreeNode? child = node.right; TreeNode? grandChild = child?.left; // 以 child 为原点,将 node 向左旋转 @@ -76,9 +70,6 @@ namespace hello_algo.chapter_tree /* 执行旋转操作,使该子树重新恢复平衡 */ TreeNode? rotate(TreeNode? node) { - if (node == null) - return node; - // 获取结点 node 的平衡因子 int balanceFactorInt = balanceFactor(node); // 左偏树 diff --git a/docs/chapter_array_and_linkedlist/linked_list.md b/docs/chapter_array_and_linkedlist/linked_list.md index afff4b13f..33cfdd346 100644 --- a/docs/chapter_array_and_linkedlist/linked_list.md +++ b/docs/chapter_array_and_linkedlist/linked_list.md @@ -91,7 +91,7 @@ comments: true === "C#" ```csharp title="" - // 链表结点类 + /* 链表结点类 */ class ListNode { int val; // 结点值 @@ -675,7 +675,7 @@ comments: true === "C#" ```csharp title="" - // 双向链表结点类 + /* 双向链表结点类 */ class ListNode { int val; // 结点值 ListNode next; // 指向后继结点的指针(引用) diff --git a/docs/chapter_array_and_linkedlist/list.md b/docs/chapter_array_and_linkedlist/list.md index 0868b3eee..749b19482 100644 --- a/docs/chapter_array_and_linkedlist/list.md +++ b/docs/chapter_array_and_linkedlist/list.md @@ -137,20 +137,20 @@ comments: true ```js title="list.js" /* 访问元素 */ - const num = list[1]; + const num = list[1]; // 访问索引 1 处的元素 /* 更新元素 */ - list[1] = 0; + list[1] = 0; // 将索引 1 处的元素更新为 0 ``` === "TypeScript" ```typescript title="list.ts" /* 访问元素 */ - const num: number = list[1]; + const num: number = list[1]; // 访问索引 1 处的元素 /* 更新元素 */ - list[1] = 0; + list[1] = 0; // 将索引 1 处的元素更新为 0 ``` === "C" @@ -163,10 +163,10 @@ comments: true ```csharp title="list.cs" /* 访问元素 */ - int num = list[1]; + int num = list[1]; // 访问索引 1 处的元素 /* 更新元素 */ - list[1]=0; + list[1] = 0; // 将索引 1 处的元素更新为 0 ``` **在列表中添加、插入、删除元素。** 相对于数组,列表可以自由地添加与删除元素。在列表尾部添加元素的时间复杂度为 $O(1)$ ,但是插入与删除元素的效率仍与数组一样低,时间复杂度为 $O(N)$ 。 @@ -477,7 +477,7 @@ comments: true ```js title="list.js" /* 拼接两个列表 */ const list1 = [6, 8, 7, 10, 9]; - list.push(...list1); + list.push(...list1); // 将列表 list1 拼接到 list 之后 ``` === "TypeScript" @@ -485,7 +485,7 @@ comments: true ```typescript title="list.ts" /* 拼接两个列表 */ const list1: number[] = [6, 8, 7, 10, 9]; - list.push(...list1); + list.push(...list1); // 将列表 list1 拼接到 list 之后 ``` === "C" @@ -499,7 +499,7 @@ comments: true ```csharp title="list.cs" /* 拼接两个列表 */ List list1 = new() { 6, 8, 7, 10, 9 }; - list.AddRange(list1); + list.AddRange(list1); // 将列表 list1 拼接到 list 之后 ``` **排序列表。** 排序也是常用的方法之一,完成列表排序后,我们就可以使用在数组类算法题中经常考察的「二分查找」和「双指针」算法了。 @@ -536,7 +536,7 @@ comments: true ```js title="list.js" /* 排序列表 */ - list.sort((a, b) => a - b); + list.sort((a, b) => a - b); // 排序后,列表元素从小到大排列 ``` === "TypeScript" diff --git a/docs/chapter_computational_complexity/space_complexity.md b/docs/chapter_computational_complexity/space_complexity.md index 8ea15a2e8..50f2698ff 100644 --- a/docs/chapter_computational_complexity/space_complexity.md +++ b/docs/chapter_computational_complexity/space_complexity.md @@ -164,9 +164,9 @@ comments: true return 0; } - int algorithm(int n) - { // 输入数据 - int a = 0; // 暂存数据(常量) + int algorithm(int n) // 输入数据 + { + int a = 0; // 暂存数据(常量) int b = 0; // 暂存数据(变量) Node node = new Node(0); // 暂存数据(对象) int c = function(); // 栈帧空间(调用函数) @@ -606,7 +606,7 @@ $$ nodes = append(nodes, newNode(i)) } // 长度为 n 的哈希表占用 O(n) 空间 - m := make(map[int]string, n) + m := make(map[int]string, n) for i := 0; i < n; i++ { m[i] = strconv.Itoa(i) } @@ -883,8 +883,8 @@ $$ if n <= 0 { return 0 } + // 数组 nums 长度为 n, n-1, ..., 2, 1 nums := make([]int, n) - fmt.Printf("递归 n = %d 中的 nums 长度 = %d \n", n, len(nums)) return spaceQuadraticRecur(n - 1) } ``` @@ -914,8 +914,8 @@ $$ int quadraticRecur(int n) { if (n <= 0) return 0; + // 数组 nums 长度为 n, n-1, ..., 2, 1 int[] nums = new int[n]; - Console.WriteLine("递归 n = " + n + " 中的 nums 长度 = " + nums.Length); return quadraticRecur(n - 1); } diff --git a/docs/chapter_computational_complexity/time_complexity.md b/docs/chapter_computational_complexity/time_complexity.md index cdd444eb6..8841a613c 100644 --- a/docs/chapter_computational_complexity/time_complexity.md +++ b/docs/chapter_computational_complexity/time_complexity.md @@ -103,7 +103,7 @@ $$ int a = 2; // 1 ns a = a + 1; // 1 ns a = a * 2; // 10 ns - // 循环 n 次 + // 循环 n 次 for (int i = 0; i < n; i++) { // 1 ns ,每轮都要执行 i++ Console.WriteLine(0); // 5 ns @@ -347,7 +347,7 @@ $$ a = a * 2; // +1 // 循环 n 次 for (int i = 0; i < n; i++) { // +1(每轮都执行 i ++) - Console.WriteLine(0); // +1 + Console.WriteLine(0); // +1 } } ``` @@ -500,7 +500,7 @@ $$ { int a = 1; // +0(技巧 1) a = a + n; // +0(技巧 1) - // +n(技巧 2) + // +n(技巧 2) for (int i = 0; i < 5 * n + 1; i++) { Console.WriteLine(0); @@ -1422,7 +1422,7 @@ $$ === "C#" ```csharp title="time_complexity.cs" - /* 对数阶(递归实现) */ + /* 对数阶(递归实现) */ int logRecur(float n) { if (n <= 1) return 0; diff --git a/docs/chapter_hashing/hash_map.md b/docs/chapter_hashing/hash_map.md index cb439546a..b51a1da91 100644 --- a/docs/chapter_hashing/hash_map.md +++ b/docs/chapter_hashing/hash_map.md @@ -543,14 +543,12 @@ $$ bucket.Add(null); } } - /* 哈希函数 */ private int hashFunc(int key) { int index = key % 100; return index; } - /* 查询操作 */ public String? get(int key) { @@ -559,7 +557,6 @@ $$ if (pair == null) return null; return pair.val; } - /* 添加操作 */ public void put(int key, String val) { @@ -567,7 +564,6 @@ $$ int index = hashFunc(key); bucket[index]=pair; } - /* 删除操作 */ public void remove(int key) { @@ -576,7 +572,6 @@ $$ bucket[index]=null; } } - ``` ## 哈希冲突 diff --git a/docs/chapter_searching/binary_search.md b/docs/chapter_searching/binary_search.md index bdaaadc5d..a74c07aaf 100644 --- a/docs/chapter_searching/binary_search.md +++ b/docs/chapter_searching/binary_search.md @@ -419,7 +419,7 @@ $$ === "C#" ```csharp title="" - // (i + j) 有可能超出 int 的取值范围 + // (i + j) 有可能超出 int 的取值范围 int m = (i + j) / 2; // 更换为此写法则不会越界 int m = i + (j - i) / 2; diff --git a/docs/chapter_sorting/merge_sort.md b/docs/chapter_sorting/merge_sort.md index 62ec5e47e..9ee984271 100644 --- a/docs/chapter_sorting/merge_sort.md +++ b/docs/chapter_sorting/merge_sort.md @@ -379,11 +379,11 @@ comments: true { // 终止条件 if (left >= right) return; // 当子数组长度为 1 时终止递归 - // 划分阶段 + // 划分阶段 int mid = (left + right) / 2; // 计算中点 mergeSort(nums, left, mid); // 递归左子数组 mergeSort(nums, mid + 1, right); // 递归右子数组 - // 合并阶段 + // 合并阶段 merge(nums, left, mid, right); } ``` diff --git a/docs/chapter_sorting/quick_sort.md b/docs/chapter_sorting/quick_sort.md index 4ec7b9ff9..b7b607f27 100644 --- a/docs/chapter_sorting/quick_sort.md +++ b/docs/chapter_sorting/quick_sort.md @@ -570,17 +570,7 @@ comments: true // 将中位数交换至数组最左端 swap(nums, left, med); // 以 nums[left] 作为基准数 - int i = left, j = right; - while (i < j) - { - while (i < j && nums[j] >= nums[left]) - j--; // 从右向左找首个小于基准数的元素 - while (i < j && nums[i] <= nums[left]) - i++; // 从左向右找首个大于基准数的元素 - swap(nums, i, j); // 交换这两个元素 - } - swap(nums, i, left); // 将基准数交换至两子数组的分界线 - return i; // 返回基准数的索引 + // 下同省略... } ``` diff --git a/docs/chapter_stack_and_queue/queue.md b/docs/chapter_stack_and_queue/queue.md index f8c864fad..3c5c0528d 100644 --- a/docs/chapter_stack_and_queue/queue.md +++ b/docs/chapter_stack_and_queue/queue.md @@ -557,25 +557,21 @@ comments: true { private ListNode? front, rear; // 头结点 front ,尾结点 rear private int queSize = 0; - public LinkedListQueue() { front = null; rear = null; } - /* 获取队列的长度 */ public int size() { return queSize; } - /* 判断队列是否为空 */ public bool isEmpty() { return size() == 0; } - /* 入队 */ public void offer(int num) { @@ -595,7 +591,6 @@ comments: true } queSize++; } - /* 出队 */ public int poll() { @@ -605,7 +600,6 @@ comments: true queSize--; return num; } - /* 访问队首元素 */ public int peek() { @@ -962,36 +956,38 @@ comments: true ```csharp title="array_queue.cs" /* 基于环形数组实现的队列 */ - class ArrayQueue { + class ArrayQueue + { private int[] nums; // 用于存储队列元素的数组 private int front = 0; // 头指针,指向队首 private int rear = 0; // 尾指针,指向队尾 + 1 - - public ArrayQueue(int capacity) { + public ArrayQueue(int capacity) + { // 初始化数组 nums = new int[capacity]; } - /* 获取队列的容量 */ - public int capacity() { + public int capacity() + { return nums.Length; } - /* 获取队列的长度 */ - public int size() { + public int size() + { int capacity = this.capacity(); // 由于将数组看作为环形,可能 rear < front ,因此需要取余数 return (capacity + rear - front) % capacity; } - /* 判断队列是否为空 */ - public bool isEmpty() { + public bool isEmpty() + { return rear - front == 0; } - /* 入队 */ - public void offer(int num) { - if (size() == capacity()) { + public void offer(int num) + { + if (size() == capacity()) + { Console.WriteLine("队列已满"); return; } @@ -1000,17 +996,17 @@ comments: true // 尾指针向后移动一位,越过尾部后返回到数组头部 rear = (rear + 1) % capacity(); } - /* 出队 */ - public int poll() { + public int poll() + { int num = peek(); // 队头指针向后移动一位,若越过尾部则返回到数组头部 front = (front + 1) % capacity(); return num; } - /* 访问队首元素 */ - public int peek() { + public int peek() + { if (isEmpty()) throw new Exception(); return nums[front]; diff --git a/docs/chapter_stack_and_queue/stack.md b/docs/chapter_stack_and_queue/stack.md index 74f5516e7..b0d577bce 100644 --- a/docs/chapter_stack_and_queue/stack.md +++ b/docs/chapter_stack_and_queue/stack.md @@ -549,19 +549,16 @@ comments: true { stackPeek = null; } - /* 获取栈的长度 */ public int size() { return stkSize; } - /* 判断栈是否为空 */ public bool isEmpty() { return size() == 0; } - /* 入栈 */ public void push(int num) { @@ -570,7 +567,6 @@ comments: true stackPeek = node; stkSize++; } - /* 出栈 */ public int pop() { @@ -579,7 +575,6 @@ comments: true stkSize--; return num; } - /* 访问栈顶元素 */ public int peek() { @@ -836,25 +831,21 @@ comments: true // 初始化列表(动态数组) stack = new(); } - /* 获取栈的长度 */ public int size() { return stack.Count(); } - /* 判断栈是否为空 */ public bool isEmpty() { return size() == 0; } - /* 入栈 */ public void push(int num) { stack.Add(num); } - /* 出栈 */ public int pop() { @@ -864,7 +855,6 @@ comments: true stack.RemoveAt(size() - 1); return val; } - /* 访问栈顶元素 */ public int peek() { diff --git a/docs/chapter_tree/avl_tree.md b/docs/chapter_tree/avl_tree.md index ab3574263..2b1ad08f0 100644 --- a/docs/chapter_tree/avl_tree.md +++ b/docs/chapter_tree/avl_tree.md @@ -80,10 +80,10 @@ G. M. Adelson-Velsky 和 E. M. Landis 在其 1962 年发表的论文 "An algorit ```csharp title="avl_tree.cs" /* AVL 树结点类 */ class TreeNode { - public int val; // 结点值 - public int height; // 结点高度 - public TreeNode left; // 左子结点 - public TreeNode right; // 右子结点 + public int val; // 结点值 + public int height; // 结点高度 + public TreeNode? left; // 左子结点 + public TreeNode? right; // 右子结点 public TreeNode(int x) { val = x; } } ``` @@ -314,9 +314,6 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影 /* 右旋操作 */ TreeNode? rightRotate(TreeNode? node) { - if (node == null) - return null; - TreeNode? child = node.left; TreeNode? grandChild = child?.right; // 以 child 为原点,将 node 向右旋转 @@ -399,9 +396,6 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影 /* 左旋操作 */ TreeNode? leftRotate(TreeNode? node) { - if (node == null) - return null; - TreeNode? child = node.right; TreeNode? grandChild = child?.left; // 以 child 为原点,将 node 向左旋转 @@ -524,9 +518,6 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影 /* 执行旋转操作,使该子树重新恢复平衡 */ TreeNode? rotate(TreeNode? node) { - if (node == null) - return node; - // 获取结点 node 的平衡因子 int balanceFactorInt = balanceFactor(node); // 左偏树 diff --git a/docs/chapter_tree/binary_tree.md b/docs/chapter_tree/binary_tree.md index e88077276..e4fb7da1c 100644 --- a/docs/chapter_tree/binary_tree.md +++ b/docs/chapter_tree/binary_tree.md @@ -99,9 +99,9 @@ comments: true ```csharp title="" /* 链表结点类 */ class TreeNode { - int val; // 结点值 - TreeNode left; // 左子结点指针 - TreeNode right; // 右子结点指针 + int val; // 结点值 + TreeNode? left; // 左子结点指针 + TreeNode? right; // 右子结点指针 TreeNode(int x) { val = x; } } ``` @@ -451,13 +451,17 @@ comments: true === "JavaScript" ```js title="" - + /* 二叉树的数组表示 */ + // 直接使用 null 来表示空位 + let tree = [1, 2, 3, 4, 5, 6, 7, null, null, null, null, null, null, null, null] ``` === "TypeScript" ```typescript title="" - + /* 二叉树的数组表示 */ + // 直接使用 null 来表示空位 + let tree = [1, 2, 3, 4, 5, 6, 7, null, null, null, null, null, null, null, null] ``` === "C" @@ -470,7 +474,7 @@ comments: true ```csharp title="" /* 二叉树的数组表示 */ - // 使用 int?可空类型 ,就可以使用 null 来标记空位 + // 使用 int? 可空类型 ,就可以使用 null 来标记空位 int?[] tree = { 1, 2, 3, 4, null, 6, 7, 8, 9, null, null, 12, null, null, 15 }; ```