diff --git a/codes/csharp/.editorconfig b/codes/csharp/.editorconfig new file mode 100644 index 00000000..681df863 --- /dev/null +++ b/codes/csharp/.editorconfig @@ -0,0 +1,6 @@ +# CSharp formatting rules +[*.cs] +csharp_new_line_before_open_brace = none +csharp_new_line_before_else = false +csharp_new_line_before_catch = false +csharp_new_line_before_finally = false diff --git a/codes/csharp/chapter_array_and_linkedlist/array.cs b/codes/csharp/chapter_array_and_linkedlist/array.cs index 25b2afc7..292a8aa4 100644 --- a/codes/csharp/chapter_array_and_linkedlist/array.cs +++ b/codes/csharp/chapter_array_and_linkedlist/array.cs @@ -6,11 +6,9 @@ using NUnit.Framework; namespace hello_algo.chapter_array_and_linkedlist; -public class array -{ +public class array { /* 随机返回一个数组元素 */ - public static int randomAccess(int[] nums) - { + public static int randomAccess(int[] nums) { Random random = new(); // 在区间 [0, nums.Length) 中随机抽取一个数字 int randomIndex = random.Next(nums.Length); @@ -20,13 +18,11 @@ public class array } /* 扩展数组长度 */ - public static int[] extend(int[] nums, int enlarge) - { + public static int[] extend(int[] nums, int enlarge) { // 初始化一个扩展长度后的数组 int[] res = new int[nums.Length + enlarge]; // 将原数组中的所有元素复制到新数组 - for (int i = 0; i < nums.Length; i++) - { + for (int i = 0; i < nums.Length; i++) { res[i] = nums[i]; } // 返回扩展后的新数组 @@ -34,11 +30,9 @@ public class array } /* 在数组的索引 index 处插入元素 num */ - public static void insert(int[] nums, int num, int index) - { + public static void insert(int[] nums, int num, int index) { // 把索引 index 以及之后的所有元素向后移动一位 - for (int i = nums.Length - 1; i > index; i--) - { + for (int i = nums.Length - 1; i > index; i--) { nums[i] = nums[i - 1]; } // 将 num 赋给 index 处元素 @@ -46,36 +40,29 @@ public class array } /* 删除索引 index 处元素 */ - public static void remove(int[] nums, int index) - { + public static void remove(int[] nums, int index) { // 把索引 index 之后的所有元素向前移动一位 - for (int i = index; i < nums.Length - 1; i++) - { + for (int i = index; i < nums.Length - 1; i++) { nums[i] = nums[i + 1]; } } /* 遍历数组 */ - public static void traverse(int[] nums) - { + public static void traverse(int[] nums) { int count = 0; // 通过索引遍历数组 - for (int i = 0; i < nums.Length; i++) - { + for (int i = 0; i < nums.Length; i++) { count++; } // 直接遍历数组 - foreach (int num in nums) - { + foreach (int num in nums) { count++; } } /* 在数组中查找指定元素 */ - public static int find(int[] nums, int target) - { - for (int i = 0; i < nums.Length; i++) - { + public static int find(int[] nums, int target) { + for (int i = 0; i < nums.Length; i++) { if (nums[i] == target) return i; } @@ -83,15 +70,13 @@ public class array } /* 辅助函数,数组转字符串 */ - public static string toString(int[] nums) - { + public static string toString(int[] nums) { return string.Join(",", nums); } [Test] - public static void Test() - { + public static void Test() { // 初始化数组 int[] arr = new int[5]; Console.WriteLine("数组 arr = " + toString(arr)); diff --git a/codes/csharp/chapter_array_and_linkedlist/linked_list.cs b/codes/csharp/chapter_array_and_linkedlist/linked_list.cs index 1b616dd6..8ac98635 100644 --- a/codes/csharp/chapter_array_and_linkedlist/linked_list.cs +++ b/codes/csharp/chapter_array_and_linkedlist/linked_list.cs @@ -7,19 +7,16 @@ using NUnit.Framework; namespace hello_algo.chapter_array_and_linkedlist; -public class linked_list -{ +public class linked_list { /* 在链表的节点 n0 之后插入节点 P */ - public static void insert(ListNode n0, ListNode P) - { + public static void insert(ListNode n0, ListNode P) { ListNode? n1 = n0.next; P.next = n1; n0.next = P; } /* 删除链表的节点 n0 之后的首个节点 */ - public static void remove(ListNode n0) - { + public static void remove(ListNode n0) { if (n0.next == null) return; // n0 -> P -> n1 @@ -29,10 +26,8 @@ public class linked_list } /* 访问链表中索引为 index 的节点 */ - public static ListNode? access(ListNode head, int index) - { - for (int i = 0; i < index; i++) - { + public static ListNode? access(ListNode head, int index) { + for (int i = 0; i < index; i++) { if (head == null) return null; head = head.next; @@ -41,11 +36,9 @@ public class linked_list } /* 在链表中查找值为 target 的首个节点 */ - public static int find(ListNode head, int target) - { + public static int find(ListNode head, int target) { int index = 0; - while (head != null) - { + while (head != null) { if (head.val == target) return index; head = head.next; @@ -56,8 +49,7 @@ public class linked_list [Test] - public void Test() - { + public void Test() { // 初始化链表 // 初始化各个节点 ListNode n0 = new ListNode(1); diff --git a/codes/csharp/chapter_array_and_linkedlist/list.cs b/codes/csharp/chapter_array_and_linkedlist/list.cs index dab11d7b..1fdde944 100644 --- a/codes/csharp/chapter_array_and_linkedlist/list.cs +++ b/codes/csharp/chapter_array_and_linkedlist/list.cs @@ -8,11 +8,9 @@ using NUnit.Framework; namespace hello_algo.chapter_array_and_linkedlist; -public class list -{ +public class list { [Test] - public void Test() - { + public void Test() { /* 初始化列表 */ int[] numbers = new int[] { 1, 3, 2, 5, 4 }; @@ -49,15 +47,13 @@ public class list /* 通过索引遍历列表 */ int count = 0; - for (int i = 0; i < list.Count(); i++) - { + for (int i = 0; i < list.Count(); i++) { count++; } /* 直接遍历列表元素 */ count = 0; - foreach (int n in list) - { + foreach (int n in list) { count++; } diff --git a/codes/csharp/chapter_array_and_linkedlist/my_list.cs b/codes/csharp/chapter_array_and_linkedlist/my_list.cs index e415e08d..10b1b4c0 100644 --- a/codes/csharp/chapter_array_and_linkedlist/my_list.cs +++ b/codes/csharp/chapter_array_and_linkedlist/my_list.cs @@ -9,34 +9,29 @@ using NUnit.Framework; namespace hello_algo.chapter_array_and_linkedlist; /* 列表类简易实现 */ -class MyList -{ +class MyList { private int[] nums; // 数组(存储列表元素) private int numsCapacity = 10; // 列表容量 private int numsSize = 0; // 列表长度(即当前元素数量) private int extendRatio = 2; // 每次列表扩容的倍数 /* 构造方法 */ - public MyList() - { + public MyList() { nums = new int[numsCapacity]; } /* 获取列表长度(即当前元素数量)*/ - public int size() - { + public int size() { return numsSize; } /* 获取列表容量 */ - public int capacity() - { + public int capacity() { return numsCapacity; } /* 访问元素 */ - public int get(int index) - { + public int get(int index) { // 索引如果越界则抛出异常,下同 if (index < 0 || index >= numsSize) throw new IndexOutOfRangeException("索引越界"); @@ -44,16 +39,14 @@ class MyList } /* 更新元素 */ - public void set(int index, int num) - { + public void set(int index, int num) { if (index < 0 || index >= numsSize) throw new IndexOutOfRangeException("索引越界"); nums[index] = num; } /* 尾部添加元素 */ - public void add(int num) - { + public void add(int num) { // 元素数量超出容量时,触发扩容机制 if (numsSize == numsCapacity) extendCapacity(); @@ -63,16 +56,14 @@ class MyList } /* 中间插入元素 */ - public void insert(int index, int num) - { + public void insert(int index, int num) { if (index < 0 || index >= numsSize) throw new IndexOutOfRangeException("索引越界"); // 元素数量超出容量时,触发扩容机制 if (numsSize == numsCapacity) extendCapacity(); // 将索引 index 以及之后的元素都向后移动一位 - for (int j = numsSize - 1; j >= index; j--) - { + for (int j = numsSize - 1; j >= index; j--) { nums[j + 1] = nums[j]; } nums[index] = num; @@ -81,14 +72,12 @@ class MyList } /* 删除元素 */ - public int remove(int index) - { + public int remove(int index) { if (index < 0 || index >= numsSize) throw new IndexOutOfRangeException("索引越界"); int num = nums[index]; // 将索引 index 之后的元素都向前移动一位 - for (int j = index; j < numsSize - 1; j++) - { + for (int j = index; j < numsSize - 1; j++) { nums[j] = nums[j + 1]; } // 更新元素数量 @@ -98,8 +87,7 @@ class MyList } /* 列表扩容 */ - public void extendCapacity() - { + public void extendCapacity() { // 新建一个长度为 numsCapacity * extendRatio 的数组,并将原数组拷贝到新数组 System.Array.Resize(ref nums, numsCapacity * extendRatio); // 更新列表容量 @@ -107,23 +95,19 @@ class MyList } /* 将列表转换为数组 */ - public int[] toArray() - { + public int[] toArray() { // 仅转换有效长度范围内的列表元素 int[] nums = new int[numsSize]; - for (int i = 0; i < numsSize; i++) - { + for (int i = 0; i < numsSize; i++) { nums[i] = get(i); } return nums; } } -public class my_list -{ +public class my_list { [Test] - public void Test() - { + public void Test() { /* 初始化列表 */ MyList list = new MyList(); /* 尾部添加元素 */ @@ -152,8 +136,7 @@ public class my_list Console.WriteLine("将索引 1 处的元素更新为 0 ,得到 list = " + string.Join(",", list.toArray())); /* 测试扩容机制 */ - for (int i = 0; i < 10; i++) - { + for (int i = 0; i < 10; i++) { // 在 i = 5 时,列表长度将超出列表容量,此时触发扩容机制 list.add(i); } diff --git a/codes/csharp/chapter_backtracking/preorder_traversal_i_compact.cs b/codes/csharp/chapter_backtracking/preorder_traversal_i_compact.cs index 0312051a..096b6bd6 100644 --- a/codes/csharp/chapter_backtracking/preorder_traversal_i_compact.cs +++ b/codes/csharp/chapter_backtracking/preorder_traversal_i_compact.cs @@ -10,19 +10,15 @@ using System.IO; namespace hello_algo.chapter_backtracking; -public class preorder_traversal_i_compact -{ +public class preorder_traversal_i_compact { static List res; /* 前序遍历:例题一 */ - static void preOrder(TreeNode root) - { - if (root == null) - { + static void preOrder(TreeNode root) { + if (root == null) { return; } - if (root.val == 7) - { + if (root.val == 7) { // 记录解 res.Add(root); } @@ -31,8 +27,7 @@ public class preorder_traversal_i_compact } [Test] - public void Test() - { + public void Test() { TreeNode root = TreeNode.ListToTree(new List { 1, 7, 3, 4, 5, 6, 7 }); Console.WriteLine("\n初始化二叉树"); PrintUtil.PrintTree(root); @@ -44,4 +39,4 @@ public class preorder_traversal_i_compact Console.WriteLine("\n输出所有值为 7 的节点"); PrintUtil.PrintList(res.Select(p => p.val).ToList()); } -} \ No newline at end of file +} diff --git a/codes/csharp/chapter_backtracking/preorder_traversal_ii_compact.cs b/codes/csharp/chapter_backtracking/preorder_traversal_ii_compact.cs index b35cfd5a..647cd378 100644 --- a/codes/csharp/chapter_backtracking/preorder_traversal_ii_compact.cs +++ b/codes/csharp/chapter_backtracking/preorder_traversal_ii_compact.cs @@ -9,22 +9,18 @@ using NUnit.Framework; namespace hello_algo.chapter_backtracking; -public class preorder_traversal_ii_compact -{ +public class preorder_traversal_ii_compact { static List path; static List> res; /* 前序遍历:例题二 */ - static void preOrder(TreeNode root) - { - if (root == null) - { + static void preOrder(TreeNode root) { + if (root == null) { return; } // 尝试 path.Add(root); - if (root.val == 7) - { + if (root.val == 7) { // 记录解 res.Add(new List(path)); } @@ -35,8 +31,7 @@ public class preorder_traversal_ii_compact } [Test] - public void Test() - { + public void Test() { TreeNode root = TreeNode.ListToTree(new List { 1, 7, 3, 4, 5, 6, 7 }); Console.WriteLine("\n初始化二叉树"); PrintUtil.PrintTree(root); @@ -47,9 +42,8 @@ public class preorder_traversal_ii_compact preOrder(root); Console.WriteLine("\n输出所有根节点到节点 7 的路径"); - foreach (List path in res) - { + foreach (List path in res) { PrintUtil.PrintList(path.Select(p => p.val).ToList()); } } -} \ No newline at end of file +} diff --git a/codes/csharp/chapter_backtracking/preorder_traversal_iii_compact.cs b/codes/csharp/chapter_backtracking/preorder_traversal_iii_compact.cs index 09df632d..af202ffd 100644 --- a/codes/csharp/chapter_backtracking/preorder_traversal_iii_compact.cs +++ b/codes/csharp/chapter_backtracking/preorder_traversal_iii_compact.cs @@ -9,23 +9,19 @@ using NUnit.Framework; namespace hello_algo.chapter_backtracking; -public class preorder_traversal_iii_compact -{ +public class preorder_traversal_iii_compact { static List path; static List> res; /* 前序遍历:例题三 */ - static void preOrder(TreeNode root) - { + static void preOrder(TreeNode root) { // 剪枝 - if (root == null || root.val == 3) - { + if (root == null || root.val == 3) { return; } // 尝试 path.Add(root); - if (root.val == 7) - { + if (root.val == 7) { // 记录解 res.Add(new List(path)); } @@ -36,8 +32,7 @@ public class preorder_traversal_iii_compact } [Test] - public void Test() - { + public void Test() { TreeNode root = TreeNode.ListToTree(new List { 1, 7, 3, 4, 5, 6, 7 }); Console.WriteLine("\n初始化二叉树"); PrintUtil.PrintTree(root); @@ -48,9 +43,8 @@ public class preorder_traversal_iii_compact preOrder(root); Console.WriteLine("\n输出所有根节点到节点 7 的路径,且路径中不包含值为 3 的节点"); - foreach (List path in res) - { + foreach (List path in res) { PrintUtil.PrintList(path.Select(p => p.val).ToList()); } } -} \ No newline at end of file +} diff --git a/codes/csharp/chapter_backtracking/preorder_traversal_iii_template.cs b/codes/csharp/chapter_backtracking/preorder_traversal_iii_template.cs index dd5015e6..74da92a8 100644 --- a/codes/csharp/chapter_backtracking/preorder_traversal_iii_template.cs +++ b/codes/csharp/chapter_backtracking/preorder_traversal_iii_template.cs @@ -9,54 +9,44 @@ using NUnit.Framework; namespace hello_algo.chapter_backtracking; -public class preorder_traversal_iii_template -{ +public class preorder_traversal_iii_template { /* 判断当前状态是否为解 */ - static bool isSolution(List state) - { + static bool isSolution(List state) { return state.Count != 0 && state[^1].val == 7; } /* 记录解 */ - static void recordSolution(List state, List> res) - { + static void recordSolution(List state, List> res) { res.Add(new List(state)); } /* 判断在当前状态下,该选择是否合法 */ - static bool isValid(List state, TreeNode choice) - { + static bool isValid(List state, TreeNode choice) { return choice != null && choice.val != 3; } /* 更新状态 */ - static void makeChoice(List state, TreeNode choice) - { + static void makeChoice(List state, TreeNode choice) { state.Add(choice); } /* 恢复状态 */ - static void undoChoice(List state, TreeNode choice) - { + static void undoChoice(List state, TreeNode choice) { state.RemoveAt(state.Count - 1); } /* 回溯算法:例题三 */ - static void backtrack(List state, List choices, List> res) - { + static void backtrack(List state, List choices, List> res) { // 检查是否为解 - if (isSolution(state)) - { + if (isSolution(state)) { // 记录解 recordSolution(state, res); return; } // 遍历所有选择 - foreach (TreeNode choice in choices) - { + foreach (TreeNode choice in choices) { // 剪枝:检查选择是否合法 - if (isValid(state, choice)) - { + if (isValid(state, choice)) { // 尝试:做出选择,更新状态 makeChoice(state, choice); List nextChoices = new List() { choice.left, choice.right }; @@ -68,8 +58,7 @@ public class preorder_traversal_iii_template } [Test] - public void Test() - { + public void Test() { TreeNode root = TreeNode.ListToTree(new List { 1, 7, 3, 4, 5, 6, 7 }); Console.WriteLine("\n初始化二叉树"); PrintUtil.PrintTree(root); @@ -80,9 +69,8 @@ public class preorder_traversal_iii_template backtrack(new List(), choices, res); Console.WriteLine("\n输出所有根节点到节点 7 的路径,要求路径中不包含值为 3 的节点"); - foreach (List path in res) - { + foreach (List path in res) { PrintUtil.PrintList(path.Select(p => p.val).ToList()); } } -} \ No newline at end of file +} diff --git a/codes/csharp/chapter_binary_search/binary_search.cs b/codes/csharp/chapter_binary_search/binary_search.cs index 0820399f..6e9bbc97 100644 --- a/codes/csharp/chapter_binary_search/binary_search.cs +++ b/codes/csharp/chapter_binary_search/binary_search.cs @@ -8,16 +8,13 @@ using NUnit.Framework; namespace hello_algo.chapter_binary_search; -public class binary_search -{ +public class binary_search { /* 二分查找(双闭区间) */ - static int binarySearch(int[] nums, int target) - { + static int binarySearch(int[] nums, int target) { // 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素 int i = 0, j = nums.Length - 1; // 循环,当搜索区间为空时跳出(当 i > j 时为空) - while (i <= j) - { + while (i <= j) { int m = (i + j) / 2; // 计算中点索引 m if (nums[m] < target) // 此情况说明 target 在区间 [m+1, j] 中 i = m + 1; @@ -31,13 +28,11 @@ public class binary_search } /* 二分查找(左闭右开) */ - static int binarySearch1(int[] nums, int target) - { + static int binarySearch1(int[] nums, int target) { // 初始化左闭右开 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1 int i = 0, j = nums.Length; // 循环,当搜索区间为空时跳出(当 i = j 时为空) - while (i < j) - { + while (i < j) { int m = (i + j) / 2; // 计算中点索引 m if (nums[m] < target) // 此情况说明 target 在区间 [m+1, j) 中 i = m + 1; @@ -51,8 +46,7 @@ public class binary_search } [Test] - public void Test() - { + public void Test() { int target = 6; int[] nums = { 1, 3, 6, 8, 12, 15, 23, 67, 70, 92 }; diff --git a/codes/csharp/chapter_computational_complexity/space_complexity.cs b/codes/csharp/chapter_computational_complexity/space_complexity.cs index f24df022..49d272c8 100644 --- a/codes/csharp/chapter_computational_complexity/space_complexity.cs +++ b/codes/csharp/chapter_computational_complexity/space_complexity.cs @@ -9,74 +9,62 @@ using NUnit.Framework; namespace hello_algo.chapter_computational_complexity; -public class space_complexity -{ +public class space_complexity { /* 函数 */ - static int function() - { + static int function() { // do something return 0; } /* 常数阶 */ - static void constant(int n) - { + static void constant(int n) { // 常量、变量、对象占用 O(1) 空间 int a = 0; int b = 0; int[] nums = new int[10000]; ListNode node = new ListNode(0); // 循环中的变量占用 O(1) 空间 - for (int i = 0; i < n; i++) - { + for (int i = 0; i < n; i++) { int c = 0; } // 循环中的函数占用 O(1) 空间 - for (int i = 0; i < n; i++) - { + for (int i = 0; i < n; i++) { function(); } } /* 线性阶 */ - static void linear(int n) - { + static void linear(int n) { // 长度为 n 的数组占用 O(n) 空间 int[] nums = new int[n]; // 长度为 n 的列表占用 O(n) 空间 List nodes = new(); - for (int i = 0; i < n; i++) - { + for (int i = 0; i < n; i++) { nodes.Add(new ListNode(i)); } // 长度为 n 的哈希表占用 O(n) 空间 Dictionary map = new(); - for (int i = 0; i < n; i++) - { + for (int i = 0; i < n; i++) { map.Add(i, i.ToString()); } } /* 线性阶(递归实现) */ - static void linearRecur(int n) - { + static void linearRecur(int n) { Console.WriteLine("递归 n = " + n); if (n == 1) return; linearRecur(n - 1); } /* 平方阶 */ - static void quadratic(int n) - { + static void quadratic(int n) { // 矩阵占用 O(n^2) 空间 int[,] numMatrix = new int[n, n]; // 二维列表占用 O(n^2) 空间 List> numList = new(); - for (int i = 0; i < n; i++) - { + for (int i = 0; i < n; i++) { List tmp = new(); - for (int j = 0; j < n; j++) - { + for (int j = 0; j < n; j++) { tmp.Add(0); } numList.Add(tmp); @@ -84,8 +72,7 @@ public class space_complexity } /* 平方阶(递归实现) */ - static int quadraticRecur(int n) - { + static int quadraticRecur(int n) { if (n <= 0) return 0; int[] nums = new int[n]; Console.WriteLine("递归 n = " + n + " 中的 nums 长度 = " + nums.Length); @@ -93,8 +80,7 @@ public class space_complexity } /* 指数阶(建立满二叉树) */ - static TreeNode? buildTree(int n) - { + static TreeNode? buildTree(int n) { if (n == 0) return null; TreeNode root = new TreeNode(0); root.left = buildTree(n - 1); @@ -103,8 +89,7 @@ public class space_complexity } [Test] - public void Test() - { + public void Test() { int n = 5; // 常数阶 constant(n); diff --git a/codes/csharp/chapter_computational_complexity/time_complexity.cs b/codes/csharp/chapter_computational_complexity/time_complexity.cs index 4b33bd92..f0bcb3ba 100644 --- a/codes/csharp/chapter_computational_complexity/time_complexity.cs +++ b/codes/csharp/chapter_computational_complexity/time_complexity.cs @@ -8,52 +8,41 @@ using NUnit.Framework; namespace hello_algo.chapter_computational_complexity; -public class time_complexity -{ - void algorithm(int n) - { +public class time_complexity { + void algorithm(int n) { int a = 1; // +0(技巧 1) a = a + n; // +0(技巧 1) // +n(技巧 2) - for (int i = 0; i < 5 * n + 1; i++) - { + for (int i = 0; i < 5 * n + 1; i++) { Console.WriteLine(0); } // +n*n(技巧 3) - for (int i = 0; i < 2 * n; i++) - { - for (int j = 0; j < n + 1; j++) - { + for (int i = 0; i < 2 * n; i++) { + for (int j = 0; j < n + 1; j++) { Console.WriteLine(0); } } } // 算法 A 时间复杂度:常数阶 - void algorithm_A(int n) - { + void algorithm_A(int n) { Console.WriteLine(0); } // 算法 B 时间复杂度:线性阶 - void algorithm_B(int n) - { - for (int i = 0; i < n; i++) - { + void algorithm_B(int n) { + for (int i = 0; i < n; i++) { Console.WriteLine(0); } } // 算法 C 时间复杂度:常数阶 - void algorithm_C(int n) - { - for (int i = 0; i < 1000000; i++) - { + void algorithm_C(int n) { + for (int i = 0; i < 1000000; i++) { Console.WriteLine(0); } } /* 常数阶 */ - static int constant(int n) - { + static int constant(int n) { int count = 0; int size = 100000; for (int i = 0; i < size; i++) @@ -62,8 +51,7 @@ public class time_complexity } /* 线性阶 */ - static int linear(int n) - { + static int linear(int n) { int count = 0; for (int i = 0; i < n; i++) count++; @@ -71,26 +59,21 @@ public class time_complexity } /* 线性阶(遍历数组) */ - static int arrayTraversal(int[] nums) - { + static int arrayTraversal(int[] nums) { int count = 0; // 循环次数与数组长度成正比 - foreach (int num in nums) - { + foreach (int num in nums) { count++; } return count; } /* 平方阶 */ - static int quadratic(int n) - { + static int quadratic(int n) { int count = 0; // 循环次数与数组长度成平方关系 - for (int i = 0; i < n; i++) - { - for (int j = 0; j < n; j++) - { + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { count++; } } @@ -98,17 +81,13 @@ public class time_complexity } /* 平方阶(冒泡排序) */ - static int bubbleSort(int[] nums) - { + static int bubbleSort(int[] nums) { int count = 0; // 计数器 // 外循环:待排序元素数量为 n-1, n-2, ..., 1 - for (int i = nums.Length - 1; i > 0; i--) - { + for (int i = nums.Length - 1; i > 0; i--) { // 内循环:冒泡操作 - for (int j = 0; j < i; j++) - { - if (nums[j] > nums[j + 1]) - { + for (int j = 0; j < i; j++) { + if (nums[j] > nums[j + 1]) { // 交换 nums[j] 与 nums[j + 1] int tmp = nums[j]; nums[j] = nums[j + 1]; @@ -121,14 +100,11 @@ public class time_complexity } /* 指数阶(循环实现) */ - static int exponential(int n) - { + static int exponential(int n) { int count = 0, bas = 1; // cell 每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1) - for (int i = 0; i < n; i++) - { - for (int j = 0; j < bas; j++) - { + for (int i = 0; i < n; i++) { + for (int j = 0; j < bas; j++) { count++; } bas *= 2; @@ -138,18 +114,15 @@ public class time_complexity } /* 指数阶(递归实现) */ - static int expRecur(int n) - { + static int expRecur(int n) { if (n == 1) return 1; return expRecur(n - 1) + expRecur(n - 1) + 1; } /* 对数阶(循环实现) */ - static int logarithmic(float n) - { + static int logarithmic(float n) { int count = 0; - while (n > 1) - { + while (n > 1) { n = n / 2; count++; } @@ -157,41 +130,35 @@ public class time_complexity } /* 对数阶(递归实现) */ - static int logRecur(float n) - { + static int logRecur(float n) { if (n <= 1) return 0; return logRecur(n / 2) + 1; } /* 线性对数阶 */ - static int linearLogRecur(float n) - { + static int linearLogRecur(float n) { if (n <= 1) return 1; int count = linearLogRecur(n / 2) + linearLogRecur(n / 2); - for (int i = 0; i < n; i++) - { + for (int i = 0; i < n; i++) { count++; } return count; } /* 阶乘阶(递归实现) */ - static int factorialRecur(int n) - { + static int factorialRecur(int n) { if (n == 0) return 1; int count = 0; // 从 1 个分裂出 n 个 - for (int i = 0; i < n; i++) - { + for (int i = 0; i < n; i++) { count += factorialRecur(n - 1); } return count; } [Test] - public void Test() - { + public void Test() { // 可以修改 n 运行,体会一下各种复杂度的操作数量变化趋势 int n = 8; Console.WriteLine("输入数据大小 n = " + n); diff --git a/codes/csharp/chapter_computational_complexity/worst_best_time_complexity.cs b/codes/csharp/chapter_computational_complexity/worst_best_time_complexity.cs index 86d9c489..67328d19 100644 --- a/codes/csharp/chapter_computational_complexity/worst_best_time_complexity.cs +++ b/codes/csharp/chapter_computational_complexity/worst_best_time_complexity.cs @@ -8,21 +8,17 @@ using NUnit.Framework; namespace hello_algo.chapter_computational_complexity; -public class worst_best_time_complexity -{ +public class worst_best_time_complexity { /* 生成一个数组,元素为 { 1, 2, ..., n },顺序被打乱 */ - static int[] randomNumbers(int n) - { + static int[] randomNumbers(int n) { int[] nums = new int[n]; // 生成数组 nums = { 1, 2, 3, ..., n } - for (int i = 0; i < n; i++) - { + for (int i = 0; i < n; i++) { nums[i] = i + 1; } // 随机打乱数组元素 - for (int i = 0; i < nums.Length; i++) - { + for (int i = 0; i < nums.Length; i++) { var index = new Random().Next(i, nums.Length); var tmp = nums[i]; var ran = nums[index]; @@ -33,10 +29,8 @@ public class worst_best_time_complexity } /* 查找数组 nums 中数字 1 所在索引 */ - static int findOne(int[] nums) - { - for (int i = 0; i < nums.Length; i++) - { + static int findOne(int[] nums) { + for (int i = 0; i < nums.Length; i++) { // 当元素 1 在数组头部时,达到最佳时间复杂度 O(1) // 当元素 1 在数组尾部时,达到最差时间复杂度 O(n) if (nums[i] == 1) @@ -48,10 +42,8 @@ public class worst_best_time_complexity /* Driver Code */ [Test] - public void Test() - { - for (int i = 0; i < 10; i++) - { + public void Test() { + for (int i = 0; i < 10; i++) { int n = 100; int[] nums = randomNumbers(n); int index = findOne(nums); diff --git a/codes/csharp/chapter_graph/graph_adjacency_list.cs b/codes/csharp/chapter_graph/graph_adjacency_list.cs index bd36b37e..1a5a4b2f 100644 --- a/codes/csharp/chapter_graph/graph_adjacency_list.cs +++ b/codes/csharp/chapter_graph/graph_adjacency_list.cs @@ -10,18 +10,15 @@ using NUnit.Framework; namespace hello_algo.chapter_graph; /* 基于邻接表实现的无向图类 */ -public class GraphAdjList -{ +public class GraphAdjList { // 邻接表,key: 顶点,value:该顶点的所有邻接顶点 public Dictionary> adjList; /* 构造函数 */ - public GraphAdjList(Vertex[][] edges) - { + public GraphAdjList(Vertex[][] edges) { this.adjList = new Dictionary>(); // 添加所有顶点和边 - foreach (Vertex[] edge in edges) - { + foreach (Vertex[] edge in edges) { addVertex(edge[0]); addVertex(edge[1]); addEdge(edge[0], edge[1]); @@ -29,14 +26,12 @@ public class GraphAdjList } /* 获取顶点数量 */ - public int size() - { + public int size() { return adjList.Count; } /* 添加边 */ - public void addEdge(Vertex vet1, Vertex vet2) - { + public void addEdge(Vertex vet1, Vertex vet2) { if (!adjList.ContainsKey(vet1) || !adjList.ContainsKey(vet2) || vet1 == vet2) throw new InvalidOperationException(); // 添加边 vet1 - vet2 @@ -45,8 +40,7 @@ public class GraphAdjList } /* 删除边 */ - public void removeEdge(Vertex vet1, Vertex vet2) - { + public void removeEdge(Vertex vet1, Vertex vet2) { if (!adjList.ContainsKey(vet1) || !adjList.ContainsKey(vet2) || vet1 == vet2) throw new InvalidOperationException(); // 删除边 vet1 - vet2 @@ -55,8 +49,7 @@ public class GraphAdjList } /* 添加顶点 */ - public void addVertex(Vertex vet) - { + public void addVertex(Vertex vet) { if (adjList.ContainsKey(vet)) return; // 在邻接表中添加一个新链表 @@ -64,25 +57,21 @@ public class GraphAdjList } /* 删除顶点 */ - public void removeVertex(Vertex vet) - { + public void removeVertex(Vertex vet) { if (!adjList.ContainsKey(vet)) throw new InvalidOperationException(); // 在邻接表中删除顶点 vet 对应的链表 adjList.Remove(vet); // 遍历其他顶点的链表,删除所有包含 vet 的边 - foreach (List list in adjList.Values) - { + foreach (List list in adjList.Values) { list.Remove(vet); } } /* 打印邻接表 */ - public void print() - { + public void print() { Console.WriteLine("邻接表 ="); - foreach (KeyValuePair> entry in adjList) - { + foreach (KeyValuePair> entry in adjList) { List tmp = new List(); foreach (Vertex vertex in entry.Value) tmp.Add(vertex.val); @@ -91,11 +80,9 @@ public class GraphAdjList } } -public class graph_adjacency_list -{ +public class graph_adjacency_list { [Test] - public void Test() - { + public void Test() { /* 初始化无向图 */ Vertex[] v = Vertex.ValsToVets(new int[] { 1, 3, 2, 5, 4 }); Vertex[][] edges = new Vertex[][] { new Vertex[] { v[0], v[1] }, new Vertex[] { v[0], v[3] }, diff --git a/codes/csharp/chapter_graph/graph_adjacency_matrix.cs b/codes/csharp/chapter_graph/graph_adjacency_matrix.cs index ee688765..f9f75cbb 100644 --- a/codes/csharp/chapter_graph/graph_adjacency_matrix.cs +++ b/codes/csharp/chapter_graph/graph_adjacency_matrix.cs @@ -10,58 +10,49 @@ using NUnit.Framework; namespace hello_algo.chapter_graph; /* 基于邻接矩阵实现的无向图类 */ -class GraphAdjMat -{ +class GraphAdjMat { List vertices; // 顶点列表,元素代表“顶点值”,索引代表“顶点索引” List> adjMat; // 邻接矩阵,行列索引对应“顶点索引” /* 构造函数 */ - public GraphAdjMat(int[] vertices, int[][] edges) - { + public GraphAdjMat(int[] vertices, int[][] edges) { this.vertices = new List(); this.adjMat = new List>(); // 添加顶点 - foreach (int val in vertices) - { + foreach (int val in vertices) { addVertex(val); } // 添加边 // 请注意,edges 元素代表顶点索引,即对应 vertices 元素索引 - foreach (int[] e in edges) - { + foreach (int[] e in edges) { addEdge(e[0], e[1]); } } /* 获取顶点数量 */ - public int size() - { + public int size() { return vertices.Count; } /* 添加顶点 */ - public void addVertex(int val) - { + public void addVertex(int val) { int n = size(); // 向顶点列表中添加新顶点的值 vertices.Add(val); // 在邻接矩阵中添加一行 List newRow = new List(n); - for (int j = 0; j < n; j++) - { + for (int j = 0; j < n; j++) { newRow.Add(0); } adjMat.Add(newRow); // 在邻接矩阵中添加一列 - foreach (List row in adjMat) - { + foreach (List row in adjMat) { row.Add(0); } } /* 删除顶点 */ - public void removeVertex(int index) - { + public void removeVertex(int index) { if (index >= size()) throw new IndexOutOfRangeException(); // 在顶点列表中移除索引 index 的顶点 @@ -69,16 +60,14 @@ class GraphAdjMat // 在邻接矩阵中删除索引 index 的行 adjMat.RemoveAt(index); // 在邻接矩阵中删除索引 index 的列 - foreach (List row in adjMat) - { + foreach (List row in adjMat) { row.RemoveAt(index); } } /* 添加边 */ // 参数 i, j 对应 vertices 元素索引 - public void addEdge(int i, int j) - { + public void addEdge(int i, int j) { // 索引越界与相等处理 if (i < 0 || j < 0 || i >= size() || j >= size() || i == j) throw new IndexOutOfRangeException(); @@ -89,18 +78,16 @@ class GraphAdjMat /* 删除边 */ // 参数 i, j 对应 vertices 元素索引 - public void removeEdge(int i, int j) - { + public void removeEdge(int i, int j) { // 索引越界与相等处理 if (i < 0 || j < 0 || i >= size() || j >= size() || i == j) throw new IndexOutOfRangeException(); adjMat[i][j] = 0; adjMat[j][i] = 0; } - + /* 打印邻接矩阵 */ - public void print() - { + public void print() { Console.Write("顶点列表 = "); PrintUtil.PrintList(vertices); Console.WriteLine("邻接矩阵 ="); @@ -108,11 +95,9 @@ class GraphAdjMat } } -public class graph_adjacency_matrix -{ +public class graph_adjacency_matrix { [Test] - public void Test() - { + public void Test() { /* 初始化无向图 */ // 请注意,edges 元素代表顶点索引,即对应 vertices 元素索引 int[] vertices = { 1, 3, 2, 5, 4 }; diff --git a/codes/csharp/chapter_graph/graph_bfs.cs b/codes/csharp/chapter_graph/graph_bfs.cs index daf2cb9e..9d11d95b 100644 --- a/codes/csharp/chapter_graph/graph_bfs.cs +++ b/codes/csharp/chapter_graph/graph_bfs.cs @@ -9,12 +9,10 @@ using NUnit.Framework; namespace hello_algo.chapter_graph; -public class graph_bfs -{ +public class graph_bfs { /* 广度优先遍历 BFS */ // 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点 - public static List graphBFS(GraphAdjList graph, Vertex startVet) - { + public static List graphBFS(GraphAdjList graph, Vertex startVet) { // 顶点遍历序列 List res = new List(); // 哈希表,用于记录已被访问过的顶点 @@ -23,14 +21,11 @@ public class graph_bfs Queue que = new Queue(); que.Enqueue(startVet); // 以顶点 vet 为起点,循环直至访问完所有顶点 - while (que.Count > 0) - { + while (que.Count > 0) { Vertex vet = que.Dequeue(); // 队首顶点出队 res.Add(vet); // 记录访问顶点 - foreach (Vertex adjVet in graph.adjList[vet]) - { - if (visited.Contains(adjVet)) - { + foreach (Vertex adjVet in graph.adjList[vet]) { + if (visited.Contains(adjVet)) { continue; // 跳过已被访问过的顶点 } que.Enqueue(adjVet); // 只入队未访问的顶点 @@ -43,8 +38,7 @@ public class graph_bfs } [Test] - public void Test() - { + public void Test() { /* 初始化无向图 */ Vertex[] v = Vertex.ValsToVets(new int[10] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); Vertex[][] edges = new Vertex[12][] @@ -64,4 +58,4 @@ public class graph_bfs Console.WriteLine("\n广度优先遍历(BFS)顶点序列为"); Console.WriteLine(string.Join(" ", Vertex.VetsToVals(res))); } -} \ No newline at end of file +} diff --git a/codes/csharp/chapter_graph/graph_dfs.cs b/codes/csharp/chapter_graph/graph_dfs.cs index cf13d9a0..63eba655 100644 --- a/codes/csharp/chapter_graph/graph_dfs.cs +++ b/codes/csharp/chapter_graph/graph_dfs.cs @@ -9,18 +9,14 @@ using NUnit.Framework; namespace hello_algo.chapter_graph; -public class graph_dfs -{ +public class graph_dfs { /* 深度优先遍历 DFS 辅助函数 */ - public void dfs(GraphAdjList graph, HashSet visited, List res, Vertex vet) - { + public void dfs(GraphAdjList graph, HashSet visited, List res, Vertex vet) { res.Add(vet); // 记录访问顶点 visited.Add(vet); // 标记该顶点已被访问 // 遍历该顶点的所有邻接顶点 - foreach (Vertex adjVet in graph.adjList[vet]) - { - if (visited.Contains(adjVet)) - { + foreach (Vertex adjVet in graph.adjList[vet]) { + if (visited.Contains(adjVet)) { continue; // 跳过已被访问过的顶点 } // 递归访问邻接顶点 @@ -30,8 +26,7 @@ public class graph_dfs /* 深度优先遍历 DFS */ // 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点 - public List graphDFS(GraphAdjList graph, Vertex startVet) - { + public List graphDFS(GraphAdjList graph, Vertex startVet) { // 顶点遍历序列 List res = new List(); // 哈希表,用于记录已被访问过的顶点 @@ -41,8 +36,7 @@ public class graph_dfs } [Test] - public void Test() - { + public void Test() { /* 初始化无向图 */ Vertex[] v = Vertex.ValsToVets(new int[7] { 0, 1, 2, 3, 4, 5, 6 }); Vertex[][] edges = new Vertex[6][] @@ -60,4 +54,4 @@ public class graph_dfs Console.WriteLine("\n深度优先遍历(DFS)顶点序列为"); Console.WriteLine(string.Join(" ", Vertex.VetsToVals(res))); } -} \ No newline at end of file +} diff --git a/codes/csharp/chapter_hashing/array_hash_map.cs b/codes/csharp/chapter_hashing/array_hash_map.cs index b84be972..c92dd098 100644 --- a/codes/csharp/chapter_hashing/array_hash_map.cs +++ b/codes/csharp/chapter_hashing/array_hash_map.cs @@ -9,41 +9,34 @@ using NUnit.Framework; namespace hello_algo.chapter_hashing; /* 键值对 int->string */ -class Entry -{ +class Entry { public int key; public string val; - public Entry(int key, string val) - { + public Entry(int key, string val) { this.key = key; this.val = val; } } /* 基于数组简易实现的哈希表 */ -class ArrayHashMap -{ +class ArrayHashMap { private List buckets; - public ArrayHashMap() - { + public ArrayHashMap() { // 初始化数组,包含 100 个桶 buckets = new(); - for (int i = 0; i < 100; i++) - { + for (int i = 0; i < 100; i++) { buckets.Add(null); } } /* 哈希函数 */ - private int hashFunc(int key) - { + private int hashFunc(int key) { int index = key % 100; return index; } /* 查询操作 */ - public string? get(int key) - { + public string? get(int key) { int index = hashFunc(key); Entry? pair = buckets[index]; if (pair == null) return null; @@ -51,27 +44,23 @@ class ArrayHashMap } /* 添加操作 */ - public void put(int key, string val) - { + public void put(int key, string val) { Entry pair = new Entry(key, val); int index = hashFunc(key); buckets[index] = pair; } /* 删除操作 */ - public void remove(int key) - { + public void remove(int key) { int index = hashFunc(key); // 置为 null ,代表删除 buckets[index] = null; } /* 获取所有键值对 */ - public List entrySet() - { + public List entrySet() { List entrySet = new(); - foreach (Entry? pair in buckets) - { + foreach (Entry? pair in buckets) { if (pair != null) entrySet.Add(pair); } @@ -79,11 +68,9 @@ class ArrayHashMap } /* 获取所有键 */ - public List keySet() - { + public List keySet() { List keySet = new(); - foreach (Entry? pair in buckets) - { + foreach (Entry? pair in buckets) { if (pair != null) keySet.Add(pair.key); } @@ -91,11 +78,9 @@ class ArrayHashMap } /* 获取所有值 */ - public List valueSet() - { + public List valueSet() { List valueSet = new(); - foreach (Entry? pair in buckets) - { + foreach (Entry? pair in buckets) { if (pair != null) valueSet.Add(pair.val); } @@ -103,21 +88,17 @@ class ArrayHashMap } /* 打印哈希表 */ - public void print() - { - foreach (Entry kv in entrySet()) - { + public void print() { + foreach (Entry kv in entrySet()) { Console.WriteLine(kv.key + " -> " + kv.val); } } } -public class array_hash_map -{ +public class array_hash_map { [Test] - public void Test() - { + public void Test() { /* 初始化哈希表 */ ArrayHashMap map = new ArrayHashMap(); @@ -144,18 +125,15 @@ public class array_hash_map /* 遍历哈希表 */ Console.WriteLine("\n遍历键值对 Key->Value"); - foreach (Entry kv in map.entrySet()) - { + foreach (Entry kv in map.entrySet()) { Console.WriteLine(kv.key + " -> " + kv.val); } Console.WriteLine("\n单独遍历键 Key"); - foreach (int key in map.keySet()) - { + foreach (int key in map.keySet()) { Console.WriteLine(key); } Console.WriteLine("\n单独遍历值 Value"); - foreach (string val in map.valueSet()) - { + foreach (string val in map.valueSet()) { Console.WriteLine(val); } } diff --git a/codes/csharp/chapter_hashing/hash_map.cs b/codes/csharp/chapter_hashing/hash_map.cs index d51f14ff..eef618bd 100644 --- a/codes/csharp/chapter_hashing/hash_map.cs +++ b/codes/csharp/chapter_hashing/hash_map.cs @@ -10,11 +10,9 @@ using NUnit.Framework; namespace hello_algo.chapter_hashing; -public class hash_map -{ +public class hash_map { [Test] - public void Test() - { + public void Test() { /* 初始化哈希表 */ Dictionary map = new(); @@ -41,18 +39,15 @@ public class hash_map /* 遍历哈希表 */ Console.WriteLine("\n遍历键值对 Key->Value"); - foreach (var kv in map) - { + foreach (var kv in map) { Console.WriteLine(kv.Key + " -> " + kv.Value); } Console.WriteLine("\n单独遍历键 Key"); - foreach (int key in map.Keys) - { + foreach (int key in map.Keys) { Console.WriteLine(key); } Console.WriteLine("\n单独遍历值 Value"); - foreach (string val in map.Values) - { + foreach (string val in map.Values) { Console.WriteLine(val); } } diff --git a/codes/csharp/chapter_heap/heap.cs b/codes/csharp/chapter_heap/heap.cs index 2b714711..b21e1038 100644 --- a/codes/csharp/chapter_heap/heap.cs +++ b/codes/csharp/chapter_heap/heap.cs @@ -9,24 +9,20 @@ using NUnit.Framework; namespace hello_algo.chapter_heap; -public class heap -{ - public void testPush(PriorityQueue heap, int val) - { +public class heap { + public void testPush(PriorityQueue heap, int val) { heap.Enqueue(val, val); // 元素入堆 Console.WriteLine($"\n元素 {val} 入堆后\n"); PrintUtil.PrintHeap(heap); } - public void testPop(PriorityQueue heap) - { + public void testPop(PriorityQueue heap) { int val = heap.Dequeue(); // 堆顶元素出堆 Console.WriteLine($"\n堆顶元素 {val} 出堆后\n"); PrintUtil.PrintHeap(heap); } [Test] - public void Test() - { + public void Test() { /* 初始化堆 */ // 初始化小顶堆 PriorityQueue minHeap = new PriorityQueue(); diff --git a/codes/csharp/chapter_heap/my_heap.cs b/codes/csharp/chapter_heap/my_heap.cs index 363ee601..25690d0e 100644 --- a/codes/csharp/chapter_heap/my_heap.cs +++ b/codes/csharp/chapter_heap/my_heap.cs @@ -10,57 +10,48 @@ using NUnit.Framework; namespace hello_algo.chapter_heap; /* 大顶堆 */ -class MaxHeap -{ +class MaxHeap { // 使用列表而非数组,这样无需考虑扩容问题 private readonly List maxHeap; /* 构造函数,建立空堆 */ - public MaxHeap() - { + public MaxHeap() { maxHeap = new List(); } /* 构造函数,根据输入列表建堆 */ - public MaxHeap(IEnumerable nums) - { + public MaxHeap(IEnumerable nums) { // 将列表元素原封不动添加进堆 maxHeap = new List(nums); // 堆化除叶节点以外的其他所有节点 var size = parent(this.size() - 1); - for (int i = size; i >= 0; i--) - { + for (int i = size; i >= 0; i--) { siftDown(i); } } /* 获取左子节点索引 */ - int left(int i) - { + int left(int i) { return 2 * i + 1; } /* 获取右子节点索引 */ - int right(int i) - { + int right(int i) { return 2 * i + 2; } /* 获取父节点索引 */ - int parent(int i) - { + int parent(int i) { return (i - 1) / 2; // 向下整除 } /* 访问堆顶元素 */ - public int peek() - { + public int peek() { return maxHeap[0]; } /* 元素入堆 */ - public void push(int val) - { + public void push(int val) { // 添加节点 maxHeap.Add(val); // 从底至顶堆化 @@ -68,22 +59,18 @@ class MaxHeap } /* 获取堆大小 */ - public int size() - { + public int size() { return maxHeap.Count; } /* 判断堆是否为空 */ - public bool isEmpty() - { + public bool isEmpty() { return size() == 0; } /* 从节点 i 开始,从底至顶堆化 */ - void siftUp(int i) - { - while (true) - { + void siftUp(int i) { + while (true) { // 获取节点 i 的父节点 int p = parent(i); // 若“越过根节点”或“节点无需修复”,则结束堆化 @@ -97,8 +84,7 @@ class MaxHeap } /* 元素出堆 */ - public int pop() - { + public int pop() { // 判空处理 if (isEmpty()) throw new IndexOutOfRangeException(); @@ -114,10 +100,8 @@ class MaxHeap } /* 从节点 i 开始,从顶至底堆化 */ - void siftDown(int i) - { - while (true) - { + void siftDown(int i) { + while (true) { // 判断节点 i, l, r 中值最大的节点,记为 ma int l = left(i), r = right(i), ma = i; if (l < size() && maxHeap[l] > maxHeap[ma]) @@ -134,24 +118,20 @@ class MaxHeap } /* 交换元素 */ - void swap(int i, int p) - { + void swap(int i, int p) { (maxHeap[i], maxHeap[p]) = (maxHeap[p], maxHeap[i]); } /* 打印堆(二叉树) */ - public void print() - { + public void print() { var queue = new Queue(maxHeap); PrintUtil.PrintHeap(queue); } } -public class my_heap -{ +public class my_heap { [Test] - public void Test() - { + public void Test() { /* 初始化大顶堆 */ MaxHeap maxHeap = new MaxHeap(new int[] { 9, 8, 6, 6, 7, 5, 2, 1, 4, 3, 6, 2 }); Console.WriteLine("\n输入列表并建堆后"); diff --git a/codes/csharp/chapter_searching/hashing_search.cs b/codes/csharp/chapter_searching/hashing_search.cs index c0f7eb57..3e471237 100644 --- a/codes/csharp/chapter_searching/hashing_search.cs +++ b/codes/csharp/chapter_searching/hashing_search.cs @@ -9,19 +9,16 @@ using NUnit.Framework; namespace hello_algo.chapter_searching; -public class hashing_search -{ +public class hashing_search { /* 哈希查找(数组) */ - static int hashingSearchArray(Dictionary map, int target) - { + static int hashingSearchArray(Dictionary map, int target) { // 哈希表的 key: 目标元素,value: 索引 // 若哈希表中无此 key ,返回 -1 return map.GetValueOrDefault(target, -1); } /* 哈希查找(链表) */ - static ListNode? hashingSearchLinkedList(Dictionary map, int target) - { + static ListNode? hashingSearchLinkedList(Dictionary map, int target) { // 哈希表的 key: 目标节点值,value: 节点对象 // 若哈希表中无此 key ,返回 null @@ -29,16 +26,14 @@ public class hashing_search } [Test] - public void Test() - { + public void Test() { int target = 3; /* 哈希查找(数组) */ int[] nums = { 1, 5, 3, 2, 4, 7, 5, 9, 10, 8 }; // 初始化哈希表 Dictionary map = new(); - for (int i = 0; i < nums.Length; i++) - { + for (int i = 0; i < nums.Length; i++) { map[nums[i]] = i; // key: 元素,value: 索引 } int index = hashingSearchArray(map, target); @@ -48,8 +43,7 @@ public class hashing_search ListNode? head = ListNode.ArrToLinkedList(nums); // 初始化哈希表 Dictionary map1 = new(); - while (head != null) - { + while (head != null) { map1[head.val] = head; // key: 节点值,value: 节点 head = head.next; } diff --git a/codes/csharp/chapter_searching/leetcode_two_sum.cs b/codes/csharp/chapter_searching/leetcode_two_sum.cs index e2557508..9e614c8c 100644 --- a/codes/csharp/chapter_searching/leetcode_two_sum.cs +++ b/codes/csharp/chapter_searching/leetcode_two_sum.cs @@ -8,17 +8,13 @@ using NUnit.Framework; namespace hello_algo.chapter_searching; -public class leetcode_two_sum -{ +public class leetcode_two_sum { /* 方法一:暴力枚举 */ - public static int[] twoSumBruteForce(int[] nums, int target) - { + public static int[] twoSumBruteForce(int[] nums, int target) { int size = nums.Length; // 两层循环,时间复杂度 O(n^2) - for (int i = 0; i < size - 1; i++) - { - for (int j = i + 1; j < size; j++) - { + for (int i = 0; i < size - 1; i++) { + for (int j = i + 1; j < size; j++) { if (nums[i] + nums[j] == target) return new int[] { i, j }; } @@ -27,16 +23,13 @@ public class leetcode_two_sum } /* 方法二:辅助哈希表 */ - public static int[] twoSumHashTable(int[] nums, int target) - { + public static int[] twoSumHashTable(int[] nums, int target) { int size = nums.Length; // 辅助哈希表,空间复杂度 O(n) Dictionary dic = new(); // 单层循环,时间复杂度 O(n) - for (int i = 0; i < size; i++) - { - if (dic.ContainsKey(target - nums[i])) - { + for (int i = 0; i < size; i++) { + if (dic.ContainsKey(target - nums[i])) { return new int[] { dic[target - nums[i]], i }; } dic.Add(nums[i], i); @@ -45,8 +38,7 @@ public class leetcode_two_sum } [Test] - public void Test() - { + public void Test() { // ======= Test Case ======= int[] nums = { 2, 7, 11, 15 }; int target = 9; diff --git a/codes/csharp/chapter_searching/linear_search.cs b/codes/csharp/chapter_searching/linear_search.cs index 0d99287b..bd7f3eac 100644 --- a/codes/csharp/chapter_searching/linear_search.cs +++ b/codes/csharp/chapter_searching/linear_search.cs @@ -9,14 +9,11 @@ using NUnit.Framework; namespace hello_algo.chapter_searching; -public class linear_search -{ +public class linear_search { /* 线性查找(数组) */ - static int linearSearchArray(int[] nums, int target) - { + static int linearSearchArray(int[] nums, int target) { // 遍历数组 - for (int i = 0; i < nums.Length; i++) - { + for (int i = 0; i < nums.Length; i++) { // 找到目标元素,返回其索引 if (nums[i] == target) return i; @@ -26,11 +23,9 @@ public class linear_search } /* 线性查找(链表) */ - static ListNode? linearSearchLinkedList(ListNode head, int target) - { + static ListNode? linearSearchLinkedList(ListNode head, int target) { // 遍历链表 - while (head != null) - { + while (head != null) { // 找到目标节点,返回之 if (head.val == target) return head; @@ -41,8 +36,7 @@ public class linear_search } [Test] - public void Test() - { + public void Test() { int target = 3; /* 在数组中执行线性查找 */ diff --git a/codes/csharp/chapter_sorting/bubble_sort.cs b/codes/csharp/chapter_sorting/bubble_sort.cs index 7272564f..5ed88362 100644 --- a/codes/csharp/chapter_sorting/bubble_sort.cs +++ b/codes/csharp/chapter_sorting/bubble_sort.cs @@ -8,19 +8,14 @@ using NUnit.Framework; namespace hello_algo.chapter_sorting; -public class bubble_sort -{ +public class bubble_sort { /* 冒泡排序 */ - static void bubbleSort(int[] nums) - { + static void bubbleSort(int[] nums) { // 外循环:待排序元素数量为 n-1, n-2, ..., 1 - for (int i = nums.Length - 1; i > 0; i--) - { + for (int i = nums.Length - 1; i > 0; i--) { // 内循环:冒泡操作 - for (int j = 0; j < i; j++) - { - if (nums[j] > nums[j + 1]) - { + for (int j = 0; j < i; j++) { + if (nums[j] > nums[j + 1]) { // 交换 nums[j] 与 nums[j + 1] int tmp = nums[j]; nums[j] = nums[j + 1]; @@ -31,17 +26,13 @@ public class bubble_sort } /* 冒泡排序(标志优化)*/ - static void bubbleSortWithFlag(int[] nums) - { + static void bubbleSortWithFlag(int[] nums) { // 外循环:待排序元素数量为 n-1, n-2, ..., 1 - for (int i = nums.Length - 1; i > 0; i--) - { + for (int i = nums.Length - 1; i > 0; i--) { bool flag = false; // 初始化标志位 // 内循环:冒泡操作 - for (int j = 0; j < i; j++) - { - if (nums[j] > nums[j + 1]) - { + for (int j = 0; j < i; j++) { + if (nums[j] > nums[j + 1]) { // 交换 nums[j] 与 nums[j + 1] int tmp = nums[j]; nums[j] = nums[j + 1]; @@ -54,8 +45,7 @@ public class bubble_sort } [Test] - public void Test() - { + public void Test() { int[] nums = { 4, 1, 3, 1, 5, 2 }; bubbleSort(nums); Console.WriteLine("冒泡排序完成后 nums = " + string.Join(",", nums)); diff --git a/codes/csharp/chapter_sorting/bucket_sort.cs b/codes/csharp/chapter_sorting/bucket_sort.cs index 43fe7358..8a1aac4f 100644 --- a/codes/csharp/chapter_sorting/bucket_sort.cs +++ b/codes/csharp/chapter_sorting/bucket_sort.cs @@ -8,49 +8,41 @@ using NUnit.Framework; namespace hello_algo.chapter_sorting; -public class bucket_sort -{ +public class bucket_sort { /* 桶排序 */ - public static void bucketSort(float[] nums) - { + public static void bucketSort(float[] nums) { // 初始化 k = n/2 个桶,预期向每个桶分配 2 个元素 int k = nums.Length / 2; List> buckets = new List>(); - for (int i = 0; i < k; i++) - { + for (int i = 0; i < k; i++) { buckets.Add(new List()); } // 1. 将数组元素分配到各个桶中 - foreach (float num in nums) - { + foreach (float num in nums) { // 输入数据范围 [0, 1),使用 num * k 映射到索引范围 [0, k-1] int i = (int)num * k; // 将 num 添加进桶 i buckets[i].Add(num); } // 2. 对各个桶执行排序 - foreach (List bucket in buckets) - { + foreach (List bucket in buckets) { // 使用内置排序函数,也可以替换成其他排序算法 bucket.Sort(); } // 3. 遍历桶合并结果 int j = 0; - foreach (List bucket in buckets) - { - foreach (float num in bucket) - { + foreach (List bucket in buckets) { + foreach (float num in bucket) { nums[j++] = num; } } } [Test] - public void Test() - { + public void Test() { // 设输入数据为浮点数,范围为 [0, 1) float[] nums = { 0.49f, 0.96f, 0.82f, 0.09f, 0.57f, 0.43f, 0.91f, 0.75f, 0.15f, 0.37f }; bucketSort(nums); Console.WriteLine("桶排序完成后 nums = " + string.Join(" ", nums)); } -} \ No newline at end of file +} diff --git a/codes/csharp/chapter_sorting/counting_sort.cs b/codes/csharp/chapter_sorting/counting_sort.cs index 0e7daa40..19b5815a 100644 --- a/codes/csharp/chapter_sorting/counting_sort.cs +++ b/codes/csharp/chapter_sorting/counting_sort.cs @@ -8,31 +8,25 @@ using NUnit.Framework; namespace hello_algo.chapter_sorting; -public class counting_sort -{ +public class counting_sort { /* 计数排序 */ // 简单实现,无法用于排序对象 - public static void countingSortNaive(int[] nums) - { + public static void countingSortNaive(int[] nums) { // 1. 统计数组最大元素 m int m = 0; - foreach (int num in nums) - { + foreach (int num in nums) { m = Math.Max(m, num); } // 2. 统计各数字的出现次数 // counter[num] 代表 num 的出现次数 int[] counter = new int[m + 1]; - foreach (int num in nums) - { + foreach (int num in nums) { counter[num]++; } // 3. 遍历 counter ,将各元素填入原数组 nums int i = 0; - for (int num = 0; num < m + 1; num++) - { - for (int j = 0; j < counter[num]; j++, i++) - { + for (int num = 0; num < m + 1; num++) { + for (int j = 0; j < counter[num]; j++, i++) { nums[i] = num; } } @@ -40,47 +34,40 @@ public class counting_sort /* 计数排序 */ // 完整实现,可排序对象,并且是稳定排序 - static void countingSort(int[] nums) - { + static void countingSort(int[] nums) { // 1. 统计数组最大元素 m int m = 0; - foreach (int num in nums) - { + foreach (int num in nums) { m = Math.Max(m, num); } // 2. 统计各数字的出现次数 // counter[num] 代表 num 的出现次数 int[] counter = new int[m + 1]; - foreach (int num in nums) - { + foreach (int num in nums) { counter[num]++; } // 3. 求 counter 的前缀和,将“出现次数”转换为“尾索引” // 即 counter[num]-1 是 num 在 res 中最后一次出现的索引 - for (int i = 0; i < m; i++) - { + for (int i = 0; i < m; i++) { counter[i + 1] += counter[i]; } // 4. 倒序遍历 nums ,将各元素填入结果数组 res // 初始化数组 res 用于记录结果 int n = nums.Length; int[] res = new int[n]; - for (int i = n - 1; i >= 0; i--) - { + for (int i = n - 1; i >= 0; i--) { int num = nums[i]; res[counter[num] - 1] = num; // 将 num 放置到对应索引处 counter[num]--; // 令前缀和自减 1 ,得到下次放置 num 的索引 } // 使用结果数组 res 覆盖原数组 nums - for (int i = 0; i < n; i++) - { + for (int i = 0; i < n; i++) { nums[i] = res[i]; } } [Test] - public void Test() - { + public void Test() { int[] nums = { 1, 0, 1, 2, 0, 4, 0, 2, 2, 4 }; countingSortNaive(nums); Console.WriteLine("计数排序(无法排序对象)完成后 nums = " + string.Join(" ", nums)); @@ -89,4 +76,4 @@ public class counting_sort countingSort(nums1); Console.WriteLine("计数排序完成后 nums1 = " + string.Join(" ", nums)); } -} \ No newline at end of file +} diff --git a/codes/csharp/chapter_sorting/insertion_sort.cs b/codes/csharp/chapter_sorting/insertion_sort.cs index 171bc3c3..ea5f014f 100644 --- a/codes/csharp/chapter_sorting/insertion_sort.cs +++ b/codes/csharp/chapter_sorting/insertion_sort.cs @@ -8,18 +8,14 @@ using NUnit.Framework; namespace hello_algo.chapter_sorting; -public class insertion_sort -{ +public class insertion_sort { /* 插入排序 */ - static void insertionSort(int[] nums) - { + static void insertionSort(int[] nums) { // 外循环:base = nums[1], nums[2], ..., nums[n-1] - for (int i = 1; i < nums.Length; i++) - { + for (int i = 1; i < nums.Length; i++) { int bas = nums[i], j = i - 1; // 内循环:将 base 插入到左边的正确位置 - while (j >= 0 && nums[j] > bas) - { + while (j >= 0 && nums[j] > bas) { nums[j + 1] = nums[j]; // 1. 将 nums[j] 向右移动一位 j--; } @@ -28,8 +24,7 @@ public class insertion_sort } [Test] - public void Test() - { + public void Test() { int[] nums = { 4, 1, 3, 1, 5, 2 }; insertionSort(nums); Console.WriteLine("插入排序完成后 nums = " + string.Join(",", nums)); diff --git a/codes/csharp/chapter_sorting/merge_sort.cs b/codes/csharp/chapter_sorting/merge_sort.cs index 899dad99..fc84e6c5 100644 --- a/codes/csharp/chapter_sorting/merge_sort.cs +++ b/codes/csharp/chapter_sorting/merge_sort.cs @@ -8,13 +8,11 @@ using NUnit.Framework; namespace hello_algo.chapter_sorting; -public class merge_sort -{ +public class merge_sort { /* 合并左子数组和右子数组 */ // 左子数组区间 [left, mid] // 右子数组区间 [mid + 1, right] - static void merge(int[] nums, int left, int mid, int right) - { + static void merge(int[] nums, int left, int mid, int right) { // 初始化辅助数组 int[] tmp = nums[left..(right + 1)]; // 左子数组的起始索引和结束索引 @@ -24,8 +22,7 @@ public class merge_sort // i, j 分别指向左子数组、右子数组的首元素 int i = leftStart, j = rightStart; // 通过覆盖原数组 nums 来合并左子数组和右子数组 - for (int k = left; k <= right; k++) - { + for (int k = left; k <= right; k++) { // 若“左子数组已全部合并完”,则选取右子数组元素,并且 j++ if (i > leftEnd) nums[k] = tmp[j++]; @@ -39,8 +36,7 @@ public class merge_sort } /* 归并排序 */ - static void mergeSort(int[] nums, int left, int right) - { + static void mergeSort(int[] nums, int left, int right) { // 终止条件 if (left >= right) return; // 当子数组长度为 1 时终止递归 // 划分阶段 @@ -52,8 +48,7 @@ public class merge_sort } [Test] - public void Test() - { + public void Test() { /* 归并排序 */ int[] nums = { 7, 3, 2, 6, 0, 1, 5, 4 }; mergeSort(nums, 0, nums.Length - 1); diff --git a/codes/csharp/chapter_sorting/quick_sort.cs b/codes/csharp/chapter_sorting/quick_sort.cs index 666ad73d..c1a4929c 100644 --- a/codes/csharp/chapter_sorting/quick_sort.cs +++ b/codes/csharp/chapter_sorting/quick_sort.cs @@ -8,23 +8,19 @@ using NUnit.Framework; namespace hello_algo.chapter_sorting; -class QuickSort -{ +class QuickSort { /* 元素交换 */ - static void swap(int[] nums, int i, int j) - { + static void swap(int[] nums, int i, int j) { int tmp = nums[i]; nums[i] = nums[j]; nums[j] = tmp; } /* 哨兵划分 */ - static int partition(int[] nums, int left, int right) - { + static int partition(int[] nums, int left, int right) { // 以 nums[left] 作为基准数 int i = left, j = right; - while (i < j) - { + while (i < j) { while (i < j && nums[j] >= nums[left]) j--; // 从右向左找首个小于基准数的元素 while (i < j && nums[i] <= nums[left]) @@ -36,8 +32,7 @@ class QuickSort } /* 快速排序 */ - public static void quickSort(int[] nums, int left, int right) - { + public static void quickSort(int[] nums, int left, int right) { // 子数组长度为 1 时终止递归 if (left >= right) return; @@ -50,19 +45,16 @@ class QuickSort } /* 快速排序类(中位基准数优化) */ -class QuickSortMedian -{ +class QuickSortMedian { /* 元素交换 */ - static void swap(int[] nums, int i, int j) - { + static void swap(int[] nums, int i, int j) { int tmp = nums[i]; nums[i] = nums[j]; nums[j] = tmp; } /* 选取三个元素的中位数 */ - static int medianThree(int[] nums, int left, int mid, int right) - { + static int medianThree(int[] nums, int left, int mid, int right) { // 此处使用异或运算来简化代码 // 异或规则为 0 ^ 0 = 1 ^ 1 = 0, 0 ^ 1 = 1 ^ 0 = 1 if ((nums[left] < nums[mid]) ^ (nums[left] < nums[right])) @@ -74,16 +66,14 @@ class QuickSortMedian } /* 哨兵划分(三数取中值) */ - static int partition(int[] nums, int left, int right) - { + static int partition(int[] nums, int left, int right) { // 选取三个候选元素的中位数 int med = medianThree(nums, left, (left + right) / 2, right); // 将中位数交换至数组最左端 swap(nums, left, med); // 以 nums[left] 作为基准数 int i = left, j = right; - while (i < j) - { + while (i < j) { while (i < j && nums[j] >= nums[left]) j--; // 从右向左找首个小于基准数的元素 while (i < j && nums[i] <= nums[left]) @@ -95,8 +85,7 @@ class QuickSortMedian } /* 快速排序 */ - public static void quickSort(int[] nums, int left, int right) - { + public static void quickSort(int[] nums, int left, int right) { // 子数组长度为 1 时终止递归 if (left >= right) return; @@ -109,23 +98,19 @@ class QuickSortMedian } /* 快速排序类(尾递归优化) */ -class QuickSortTailCall -{ +class QuickSortTailCall { /* 元素交换 */ - static void swap(int[] nums, int i, int j) - { + static void swap(int[] nums, int i, int j) { int tmp = nums[i]; nums[i] = nums[j]; nums[j] = tmp; } /* 哨兵划分 */ - static int partition(int[] nums, int left, int right) - { + static int partition(int[] nums, int left, int right) { // 以 nums[left] 作为基准数 int i = left, j = right; - while (i < j) - { + while (i < j) { while (i < j && nums[j] >= nums[left]) j--; // 从右向左找首个小于基准数的元素 while (i < j && nums[i] <= nums[left]) @@ -137,21 +122,16 @@ class QuickSortTailCall } /* 快速排序(尾递归优化) */ - public static void quickSort(int[] nums, int left, int right) - { + public static void quickSort(int[] nums, int left, int right) { // 子数组长度为 1 时终止 - while (left < right) - { + while (left < right) { // 哨兵划分操作 int pivot = partition(nums, left, right); // 对两个子数组中较短的那个执行快排 - if (pivot - left < right - pivot) - { + if (pivot - left < right - pivot) { quickSort(nums, left, pivot - 1); // 递归排序左子数组 left = pivot + 1; // 剩余待排序区间为 [pivot + 1, right] - } - else - { + } else { quickSort(nums, pivot + 1, right); // 递归排序右子数组 right = pivot - 1; // 剩余待排序区间为 [left, pivot - 1] } @@ -159,11 +139,9 @@ class QuickSortTailCall } } -public class quick_sort -{ +public class quick_sort { [Test] - public void Test() - { + public void Test() { /* 快速排序 */ int[] nums = { 2, 4, 1, 0, 3, 5 }; QuickSort.quickSort(nums, 0, nums.Length - 1); diff --git a/codes/csharp/chapter_sorting/radix_sort.cs b/codes/csharp/chapter_sorting/radix_sort.cs index fbcce579..8421fdc8 100644 --- a/codes/csharp/chapter_sorting/radix_sort.cs +++ b/codes/csharp/chapter_sorting/radix_sort.cs @@ -8,60 +8,50 @@ using NUnit.Framework; namespace hello_algo.chapter_sorting; -public class radix_sort -{ +public class radix_sort { /* 获取元素 num 的第 k 位,其中 exp = 10^(k-1) */ - static int digit(int num, int exp) - { + static int digit(int num, int exp) { // 传入 exp 而非 k 可以避免在此重复执行昂贵的次方计算 return (num / exp) % 10; } /* 计数排序(根据 nums 第 k 位排序) */ - static void countingSortDigit(int[] nums, int exp) - { + static void countingSortDigit(int[] nums, int exp) { // 十进制的位范围为 0~9 ,因此需要长度为 10 的桶 int[] counter = new int[10]; int n = nums.Length; // 统计 0~9 各数字的出现次数 - for (int i = 0; i < n; i++) - { + for (int i = 0; i < n; i++) { int d = digit(nums[i], exp); // 获取 nums[i] 第 k 位,记为 d counter[d]++; // 统计数字 d 的出现次数 } // 求前缀和,将“出现个数”转换为“数组索引” - for (int i = 1; i < 10; i++) - { + for (int i = 1; i < 10; i++) { counter[i] += counter[i - 1]; } // 倒序遍历,根据桶内统计结果,将各元素填入 res int[] res = new int[n]; - for (int i = n - 1; i >= 0; i--) - { + for (int i = n - 1; i >= 0; i--) { int d = digit(nums[i], exp); int j = counter[d] - 1; // 获取 d 在数组中的索引 j res[j] = nums[i]; // 将当前元素填入索引 j counter[d]--; // 将 d 的数量减 1 } // 使用结果覆盖原数组 nums - for (int i = 0; i < n; i++) - { + for (int i = 0; i < n; i++) { nums[i] = res[i]; } } /* 基数排序 */ - static void radixSort(int[] nums) - { + static void radixSort(int[] nums) { // 获取数组的最大元素,用于判断最大位数 int m = int.MinValue; - foreach (int num in nums) - { + foreach (int num in nums) { if (num > m) m = num; - } + } // 按照从低位到高位的顺序遍历 - for (int exp = 1; exp <= m; exp *= 10) - { + for (int exp = 1; exp <= m; exp *= 10) { // 对数组元素的第 k 位执行计数排序 // k = 1 -> exp = 1 // k = 2 -> exp = 10 @@ -71,12 +61,11 @@ public class radix_sort } [Test] - public void Test() - { + public void Test() { // 基数排序 - int[] nums = { 10546151, 35663510, 42865989, 34862445, 81883077, + int[] nums = { 10546151, 35663510, 42865989, 34862445, 81883077, 88906420, 72429244, 30524779, 82060337, 63832996 }; radixSort(nums); Console.WriteLine("基数排序完成后 nums = " + string.Join(" ", nums)); } -} \ No newline at end of file +} diff --git a/codes/csharp/chapter_stack_and_queue/array_deque.cs b/codes/csharp/chapter_stack_and_queue/array_deque.cs index c9a05098..083c477d 100644 --- a/codes/csharp/chapter_stack_and_queue/array_deque.cs +++ b/codes/csharp/chapter_stack_and_queue/array_deque.cs @@ -6,43 +6,36 @@ using NUnit.Framework; -namespace hello_algo.chapter_stack_and_queue -{ +namespace hello_algo.chapter_stack_and_queue { /* 基于环形数组实现的双向队列 */ - public class ArrayDeque - { + public class ArrayDeque { private readonly int[] nums; // 用于存储双向队列元素的数组 private int front; // 队首指针,指向队首元素 private int queSize; // 双向队列长度 /* 构造方法 */ - public ArrayDeque(int capacity) - { + public ArrayDeque(int capacity) { this.nums = new int[capacity]; front = queSize = 0; } /* 获取双向队列的容量 */ - public int capacity() - { + public int capacity() { return nums.Length; } /* 获取双向队列的长度 */ - public int size() - { + public int size() { return queSize; } /* 判断双向队列是否为空 */ - public bool isEmpty() - { + public bool isEmpty() { return queSize == 0; } /* 计算环形数组索引 */ - private int index(int i) - { + private int index(int i) { // 通过取余操作实现数组首尾相连 // 当 i 越过数组尾部后,回到头部 // 当 i 越过数组头部后,回到尾部 @@ -50,10 +43,8 @@ namespace hello_algo.chapter_stack_and_queue } /* 队首入队 */ - public void pushFirst(int num) - { - if (queSize == capacity()) - { + public void pushFirst(int num) { + if (queSize == capacity()) { Console.WriteLine("双向队列已满"); return; } @@ -66,10 +57,8 @@ namespace hello_algo.chapter_stack_and_queue } /* 队尾入队 */ - public void pushLast(int num) - { - if (queSize == capacity()) - { + public void pushLast(int num) { + if (queSize == capacity()) { Console.WriteLine("双向队列已满"); return; } @@ -81,8 +70,7 @@ namespace hello_algo.chapter_stack_and_queue } /* 队首出队 */ - public int popFirst() - { + public int popFirst() { int num = peekFirst(); // 队首指针向后移动一位 front = index(front + 1); @@ -91,53 +79,44 @@ namespace hello_algo.chapter_stack_and_queue } /* 队尾出队 */ - public int popLast() - { + public int popLast() { int num = peekLast(); queSize--; return num; } /* 访问队首元素 */ - public int peekFirst() - { - if (isEmpty()) - { + public int peekFirst() { + if (isEmpty()) { throw new InvalidOperationException(); - } + } return nums[front]; } /* 访问队尾元素 */ - public int peekLast() - { - if (isEmpty()) - { + public int peekLast() { + if (isEmpty()) { throw new InvalidOperationException(); - } + } // 计算尾元素索引 int last = index(front + queSize - 1); return nums[last]; } /* 返回数组用于打印 */ - public int[] toArray() - { + public int[] toArray() { // 仅转换有效长度范围内的列表元素 int[] res = new int[queSize]; - for (int i = 0, j = front; i < queSize; i++, j++) - { + for (int i = 0, j = front; i < queSize; i++, j++) { res[i] = nums[index(j)]; } return res; } } - public class array_deque - { + public class array_deque { [Test] - public void Test() - { + public void Test() { /* 初始化双向队列 */ ArrayDeque deque = new ArrayDeque(10); deque.pushLast(3); diff --git a/codes/csharp/chapter_stack_and_queue/array_queue.cs b/codes/csharp/chapter_stack_and_queue/array_queue.cs index 5e9e8347..e296b2e8 100644 --- a/codes/csharp/chapter_stack_and_queue/array_queue.cs +++ b/codes/csharp/chapter_stack_and_queue/array_queue.cs @@ -9,41 +9,34 @@ using NUnit.Framework; namespace hello_algo.chapter_stack_and_queue; /* 基于环形数组实现的队列 */ -class ArrayQueue -{ +class ArrayQueue { private int[] nums; // 用于存储队列元素的数组 private int front; // 队首指针,指向队首元素 private int queSize; // 队列长度 - public ArrayQueue(int capacity) - { + public ArrayQueue(int capacity) { nums = new int[capacity]; front = queSize = 0; } /* 获取队列的容量 */ - public int capacity() - { + public int capacity() { return nums.Length; } /* 获取队列的长度 */ - public int size() - { + public int size() { return queSize; } /* 判断队列是否为空 */ - public bool isEmpty() - { + public bool isEmpty() { return queSize == 0; } /* 入队 */ - public void push(int num) - { - if (queSize == capacity()) - { + public void push(int num) { + if (queSize == capacity()) { Console.WriteLine("队列已满"); return; } @@ -56,8 +49,7 @@ class ArrayQueue } /* 出队 */ - public int pop() - { + public int pop() { int num = peek(); // 队首指针向后移动一位,若越过尾部则返回到数组头部 front = (front + 1) % capacity(); @@ -66,31 +58,26 @@ class ArrayQueue } /* 访问队首元素 */ - public int peek() - { + public int peek() { if (isEmpty()) throw new Exception(); return nums[front]; } /* 返回数组 */ - public int[] toArray() - { + public int[] toArray() { // 仅转换有效长度范围内的列表元素 int[] res = new int[queSize]; - for (int i = 0, j = front; i < queSize; i++, j++) - { + for (int i = 0, j = front; i < queSize; i++, j++) { res[i] = nums[j % this.capacity()]; } return res; } } -public class array_queue -{ +public class array_queue { [Test] - public void Test() - { + public void Test() { /* 初始化队列 */ int capacity = 10; ArrayQueue queue = new ArrayQueue(capacity); @@ -120,8 +107,7 @@ public class array_queue Console.WriteLine("队列是否为空 = " + isEmpty); /* 测试环形数组 */ - for (int i = 0; i < 10; i++) - { + for (int i = 0; i < 10; i++) { queue.push(i); queue.pop(); Console.WriteLine("第 " + i + " 轮入队 + 出队后 queue = " + string.Join(",", queue.toArray())); diff --git a/codes/csharp/chapter_stack_and_queue/array_stack.cs b/codes/csharp/chapter_stack_and_queue/array_stack.cs index 3b556d5b..b74f922d 100644 --- a/codes/csharp/chapter_stack_and_queue/array_stack.cs +++ b/codes/csharp/chapter_stack_and_queue/array_stack.cs @@ -9,36 +9,30 @@ using NUnit.Framework; namespace hello_algo.chapter_stack_and_queue; /* 基于数组实现的栈 */ -class ArrayStack -{ +class ArrayStack { private List stack; - public ArrayStack() - { + public ArrayStack() { // 初始化列表(动态数组) stack = new(); } /* 获取栈的长度 */ - public int size() - { + public int size() { return stack.Count(); } /* 判断栈是否为空 */ - public bool isEmpty() - { + public bool isEmpty() { return size() == 0; } /* 入栈 */ - public void push(int num) - { + public void push(int num) { stack.Add(num); } /* 出栈 */ - public int pop() - { + public int pop() { if (isEmpty()) throw new Exception(); var val = peek(); @@ -47,25 +41,21 @@ class ArrayStack } /* 访问栈顶元素 */ - public int peek() - { + public int peek() { if (isEmpty()) throw new Exception(); return stack[size() - 1]; } /* 将 List 转化为 Array 并返回 */ - public int[] toArray() - { + public int[] toArray() { return stack.ToArray(); } } -public class array_stack -{ +public class array_stack { [Test] - public void Test() - { + public void Test() { /* 初始化栈 */ ArrayStack stack = new ArrayStack(); diff --git a/codes/csharp/chapter_stack_and_queue/deque.cs b/codes/csharp/chapter_stack_and_queue/deque.cs index 41933d69..f55f3667 100644 --- a/codes/csharp/chapter_stack_and_queue/deque.cs +++ b/codes/csharp/chapter_stack_and_queue/deque.cs @@ -8,11 +8,9 @@ using NUnit.Framework; namespace hello_algo.chapter_stack_and_queue; -public class deque -{ +public class deque { [Test] - public void Test() - { + public void Test() { /* 初始化双向队列 */ // 在 C# 中,将链表 LinkedList 看作双向队列来使用 LinkedList deque = new LinkedList(); diff --git a/codes/csharp/chapter_stack_and_queue/linkedlist_deque.cs b/codes/csharp/chapter_stack_and_queue/linkedlist_deque.cs index 5badc7fa..87f81819 100644 --- a/codes/csharp/chapter_stack_and_queue/linkedlist_deque.cs +++ b/codes/csharp/chapter_stack_and_queue/linkedlist_deque.cs @@ -6,17 +6,14 @@ using NUnit.Framework; -namespace hello_algo.chapter_stack_and_queue -{ +namespace hello_algo.chapter_stack_and_queue { /* 双向链表节点 */ - public class ListNode - { + public class ListNode { public int val; // 节点值 public ListNode? next; // 后继节点引用(指针) public ListNode? prev; // 前驱节点引用(指针) - public ListNode(int val) - { + public ListNode(int val) { this.val = val; prev = null; next = null; @@ -24,50 +21,42 @@ namespace hello_algo.chapter_stack_and_queue } /* 基于双向链表实现的双向队列 */ - public class LinkedListDeque - { + public class LinkedListDeque { private ListNode? front, rear; // 头节点 front, 尾节点 rear private int queSize = 0; // 双向队列的长度 - public LinkedListDeque() - { + public LinkedListDeque() { front = null; rear = null; } /* 获取双向队列的长度 */ - public int size() - { + public int size() { return queSize; } /* 判断双向队列是否为空 */ - public bool isEmpty() - { + public bool isEmpty() { return size() == 0; } /* 入队操作 */ - private void push(int num, bool isFront) - { + private void push(int num, bool isFront) { ListNode node = new ListNode(num); // 若链表为空,则令 front, rear 都指向 node - if (isEmpty()) - { + if (isEmpty()) { front = node; rear = node; } // 队首入队操作 - else if (isFront) - { + else if (isFront) { // 将 node 添加至链表头部 front.prev = node; node.next = front; front = node; // 更新头节点 } // 队尾入队操作 - else - { + else { // 将 node 添加至链表尾部 rear.next = node; node.prev = rear; @@ -78,35 +67,29 @@ namespace hello_algo.chapter_stack_and_queue } /* 队首入队 */ - public void pushFirst(int num) - { + public void pushFirst(int num) { push(num, true); } /* 队尾入队 */ - public void pushLast(int num) - { + public void pushLast(int num) { push(num, false); } /* 出队操作 */ - private int? pop(bool isFront) - { + private int? pop(bool isFront) { // 若队列为空,直接返回 null - if (isEmpty()) - { + if (isEmpty()) { return null; } int val; // 队首出队操作 - if (isFront) - { + if (isFront) { val = front.val; // 暂存头节点值 // 删除头节点 ListNode fNext = front.next; - if (fNext != null) - { + if (fNext != null) { fNext.prev = null; front.next = null; } @@ -114,13 +97,11 @@ namespace hello_algo.chapter_stack_and_queue front = fNext; // 更新头节点 } // 队尾出队操作 - else - { + else { val = rear.val; // 暂存尾节点值 // 删除尾节点 ListNode rPrev = rear.prev; - if (rPrev != null) - { + if (rPrev != null) { rPrev.next = null; rear.prev = null; } @@ -133,36 +114,30 @@ namespace hello_algo.chapter_stack_and_queue } /* 队首出队 */ - public int? popFirst() - { + public int? popFirst() { return pop(true); } /* 队尾出队 */ - public int? popLast() - { + public int? popLast() { return pop(false); } /* 访问队首元素 */ - public int? peekFirst() - { + public int? peekFirst() { return isEmpty() ? null : front.val; } /* 访问队尾元素 */ - public int? peekLast() - { + public int? peekLast() { return isEmpty() ? null : rear.val; } /* 返回数组用于打印 */ - public int[] toArray() - { + public int[] toArray() { ListNode node = front; int[] res = new int[size()]; - for (int i = 0; i < res.Length; i++) - { + for (int i = 0; i < res.Length; i++) { res[i] = node.val; node = node.next; } @@ -171,11 +146,9 @@ namespace hello_algo.chapter_stack_and_queue } } - public class linkedlist_deque - { + public class linkedlist_deque { [Test] - public void Test() - { + public void Test() { /* 初始化双向队列 */ LinkedListDeque deque = new LinkedListDeque(); deque.pushLast(3); diff --git a/codes/csharp/chapter_stack_and_queue/linkedlist_queue.cs b/codes/csharp/chapter_stack_and_queue/linkedlist_queue.cs index d5fd8af2..d2a6c70a 100644 --- a/codes/csharp/chapter_stack_and_queue/linkedlist_queue.cs +++ b/codes/csharp/chapter_stack_and_queue/linkedlist_queue.cs @@ -10,43 +10,35 @@ using NUnit.Framework; namespace hello_algo.chapter_stack_and_queue; /* 基于链表实现的队列 */ -class LinkedListQueue -{ +class LinkedListQueue { private ListNode? front, rear; // 头节点 front ,尾节点 rear private int queSize = 0; - public LinkedListQueue() - { + public LinkedListQueue() { front = null; rear = null; } /* 获取队列的长度 */ - public int size() - { + public int size() { return queSize; } /* 判断队列是否为空 */ - public bool isEmpty() - { + public bool isEmpty() { return size() == 0; } /* 入队 */ - public void push(int num) - { + public void push(int num) { // 尾节点后添加 num ListNode node = new ListNode(num); // 如果队列为空,则令头、尾节点都指向该节点 - if (front == null) - { + if (front == null) { front = node; rear = node; // 如果队列不为空,则将该节点添加到尾节点后 - } - else if (rear != null) - { + } else if (rear != null) { rear.next = node; rear = node; } @@ -54,8 +46,7 @@ class LinkedListQueue } /* 出队 */ - public int pop() - { + public int pop() { int num = peek(); // 删除头节点 front = front?.next; @@ -64,23 +55,20 @@ class LinkedListQueue } /* 访问队首元素 */ - public int peek() - { + public int peek() { if (size() == 0 || front == null) throw new Exception(); return front.val; } /* 将链表转化为 Array 并返回 */ - public int[] toArray() - { + public int[] toArray() { if (front == null) return Array.Empty(); ListNode node = front; int[] res = new int[size()]; - for (int i = 0; i < res.Length; i++) - { + for (int i = 0; i < res.Length; i++) { res[i] = node.val; node = node.next; } @@ -88,11 +76,9 @@ class LinkedListQueue } } -public class linkedlist_queue -{ +public class linkedlist_queue { [Test] - public void Test() - { + public void Test() { /* 初始化队列 */ LinkedListQueue queue = new LinkedListQueue(); diff --git a/codes/csharp/chapter_stack_and_queue/linkedlist_stack.cs b/codes/csharp/chapter_stack_and_queue/linkedlist_stack.cs index edd8f46f..4f534181 100644 --- a/codes/csharp/chapter_stack_and_queue/linkedlist_stack.cs +++ b/codes/csharp/chapter_stack_and_queue/linkedlist_stack.cs @@ -10,31 +10,26 @@ using NUnit.Framework; namespace hello_algo.chapter_stack_and_queue; /* 基于链表实现的栈 */ -class LinkedListStack -{ +class LinkedListStack { private ListNode? stackPeek; // 将头节点作为栈顶 private int stkSize = 0; // 栈的长度 - public LinkedListStack() - { + public LinkedListStack() { stackPeek = null; } /* 获取栈的长度 */ - public int size() - { + public int size() { return stkSize; } /* 判断栈是否为空 */ - public bool isEmpty() - { + public bool isEmpty() { return size() == 0; } /* 入栈 */ - public void push(int num) - { + public void push(int num) { ListNode node = new ListNode(num); node.next = stackPeek; stackPeek = node; @@ -42,8 +37,7 @@ class LinkedListStack } /* 出栈 */ - public int pop() - { + public int pop() { if (stackPeek == null) throw new Exception(); @@ -54,23 +48,20 @@ class LinkedListStack } /* 访问栈顶元素 */ - public int peek() - { + public int peek() { if (size() == 0 || stackPeek == null) throw new Exception(); return stackPeek.val; } /* 将 List 转化为 Array 并返回 */ - public int[] toArray() - { + public int[] toArray() { if (stackPeek == null) return Array.Empty(); ListNode node = stackPeek; int[] res = new int[size()]; - for (int i = res.Length - 1; i >= 0; i--) - { + for (int i = res.Length - 1; i >= 0; i--) { res[i] = node.val; node = node.next; } @@ -78,11 +69,9 @@ class LinkedListStack } } -public class linkedlist_stack -{ +public class linkedlist_stack { [Test] - public void Test() - { + public void Test() { /* 初始化栈 */ LinkedListStack stack = new LinkedListStack(); diff --git a/codes/csharp/chapter_stack_and_queue/queue.cs b/codes/csharp/chapter_stack_and_queue/queue.cs index a3a55944..a6bfce74 100644 --- a/codes/csharp/chapter_stack_and_queue/queue.cs +++ b/codes/csharp/chapter_stack_and_queue/queue.cs @@ -8,11 +8,9 @@ using NUnit.Framework; namespace hello_algo.chapter_stack_and_queue; -public class queue -{ +public class queue { [Test] - public void Test() - { + public void Test() { /* 初始化队列 */ Queue queue = new(); diff --git a/codes/csharp/chapter_stack_and_queue/stack.cs b/codes/csharp/chapter_stack_and_queue/stack.cs index e917dafa..f6643407 100644 --- a/codes/csharp/chapter_stack_and_queue/stack.cs +++ b/codes/csharp/chapter_stack_and_queue/stack.cs @@ -8,11 +8,9 @@ using NUnit.Framework; namespace hello_algo.chapter_stack_and_queue; -public class stack -{ +public class stack { [Test] - public void Test() - { + public void Test() { /* 初始化栈 */ Stack stack = new(); diff --git a/codes/csharp/chapter_tree/avl_tree.cs b/codes/csharp/chapter_tree/avl_tree.cs index 64b7cf37..ccf6a38a 100644 --- a/codes/csharp/chapter_tree/avl_tree.cs +++ b/codes/csharp/chapter_tree/avl_tree.cs @@ -10,27 +10,23 @@ using NUnit.Framework; namespace hello_algo.chapter_tree; /* AVL 树 */ -class AVLTree -{ +class AVLTree { public TreeNode? root; // 根节点 /* 获取节点高度 */ - public int height(TreeNode? node) - { + public int height(TreeNode? node) { // 空节点高度为 -1 ,叶节点高度为 0 return node == null ? -1 : node.height; } /* 更新节点高度 */ - private void updateHeight(TreeNode node) - { + private void updateHeight(TreeNode node) { // 节点高度等于最高子树高度 + 1 node.height = Math.Max(height(node.left), height(node.right)) + 1; } /* 获取平衡因子 */ - public int balanceFactor(TreeNode? node) - { + public int balanceFactor(TreeNode? node) { // 空节点平衡因子为 0 if (node == null) return 0; // 节点平衡因子 = 左子树高度 - 右子树高度 @@ -38,8 +34,7 @@ class AVLTree } /* 右旋操作 */ - TreeNode? rightRotate(TreeNode? node) - { + TreeNode? rightRotate(TreeNode? node) { TreeNode? child = node.left; TreeNode? grandChild = child?.right; // 以 child 为原点,将 node 向右旋转 @@ -53,8 +48,7 @@ class AVLTree } /* 左旋操作 */ - TreeNode? leftRotate(TreeNode? node) - { + TreeNode? leftRotate(TreeNode? node) { TreeNode? child = node.right; TreeNode? grandChild = child?.left; // 以 child 为原点,将 node 向左旋转 @@ -68,35 +62,26 @@ class AVLTree } /* 执行旋转操作,使该子树重新恢复平衡 */ - TreeNode? rotate(TreeNode? node) - { + TreeNode? rotate(TreeNode? node) { // 获取节点 node 的平衡因子 int balanceFactorInt = balanceFactor(node); // 左偏树 - if (balanceFactorInt > 1) - { - if (balanceFactor(node.left) >= 0) - { + if (balanceFactorInt > 1) { + if (balanceFactor(node.left) >= 0) { // 右旋 return rightRotate(node); - } - else - { + } else { // 先左旋后右旋 node.left = leftRotate(node?.left); return rightRotate(node); } } // 右偏树 - if (balanceFactorInt < -1) - { - if (balanceFactor(node.right) <= 0) - { + if (balanceFactorInt < -1) { + if (balanceFactor(node.right) <= 0) { // 左旋 return leftRotate(node); - } - else - { + } else { // 先右旋后左旋 node.right = rightRotate(node?.right); return leftRotate(node); @@ -107,14 +92,12 @@ class AVLTree } /* 插入节点 */ - public void insert(int val) - { + public void insert(int val) { root = insertHelper(root, val); } /* 递归插入节点(辅助方法) */ - private TreeNode? insertHelper(TreeNode? node, int val) - { + private TreeNode? insertHelper(TreeNode? node, int val) { if (node == null) return new TreeNode(val); /* 1. 查找插入位置,并插入节点 */ if (val < node.val) @@ -131,24 +114,20 @@ class AVLTree } /* 删除节点 */ - public void remove(int val) - { + public void remove(int val) { root = removeHelper(root, val); } /* 递归删除节点(辅助方法) */ - private TreeNode? removeHelper(TreeNode? node, int val) - { + private TreeNode? removeHelper(TreeNode? node, int val) { if (node == null) return null; /* 1. 查找节点,并删除之 */ if (val < node.val) node.left = removeHelper(node.left, val); else if (val > node.val) node.right = removeHelper(node.right, val); - else - { - if (node.left == null || node.right == null) - { + else { + if (node.left == null || node.right == null) { TreeNode? child = node.left != null ? node.left : node.right; // 子节点数量 = 0 ,直接删除 node 并返回 if (child == null) @@ -156,13 +135,10 @@ class AVLTree // 子节点数量 = 1 ,直接删除 node else node = child; - } - else - { + } else { // 子节点数量 = 2 ,则将中序遍历的下个节点删除,并用该节点替换当前节点 TreeNode? temp = node.right; - while (temp.left != null) - { + while (temp.left != null) { temp = temp.left; } node.right = removeHelper(node.right, temp.val); @@ -177,12 +153,10 @@ class AVLTree } /* 查找节点 */ - public TreeNode? search(int val) - { + public TreeNode? search(int val) { TreeNode? cur = root; // 循环查找,越过叶节点后跳出 - while (cur != null) - { + while (cur != null) { // 目标节点在 cur 的右子树中 if (cur.val < val) cur = cur.right; @@ -198,25 +172,21 @@ class AVLTree } } -public class avl_tree -{ - static void testInsert(AVLTree tree, int val) - { +public class avl_tree { + static void testInsert(AVLTree tree, int val) { tree.insert(val); Console.WriteLine("\n插入节点 " + val + " 后,AVL 树为"); PrintUtil.PrintTree(tree.root); } - static void testRemove(AVLTree tree, int val) - { + static void testRemove(AVLTree tree, int val) { tree.remove(val); Console.WriteLine("\n删除节点 " + val + " 后,AVL 树为"); PrintUtil.PrintTree(tree.root); } [Test] - public void Test() - { + public void Test() { /* 初始化空 AVL 树 */ AVLTree avlTree = new AVLTree(); diff --git a/codes/csharp/chapter_tree/binary_search_tree.cs b/codes/csharp/chapter_tree/binary_search_tree.cs index f3a56d3f..43830a1a 100644 --- a/codes/csharp/chapter_tree/binary_search_tree.cs +++ b/codes/csharp/chapter_tree/binary_search_tree.cs @@ -9,25 +9,21 @@ using NUnit.Framework; namespace hello_algo.chapter_tree; -class BinarySearchTree -{ +class BinarySearchTree { TreeNode? root; - public BinarySearchTree(int[] nums) - { + public BinarySearchTree(int[] nums) { Array.Sort(nums); // 排序数组 root = buildTree(nums, 0, nums.Length - 1); // 构建二叉搜索树 } /* 获取二叉树根节点 */ - public TreeNode? getRoot() - { + public TreeNode? getRoot() { return root; } /* 构建二叉搜索树 */ - public TreeNode? buildTree(int[] nums, int i, int j) - { + public TreeNode? buildTree(int[] nums, int i, int j) { if (i > j) return null; // 将数组中间节点作为根节点 int mid = (i + j) / 2; @@ -39,12 +35,10 @@ class BinarySearchTree } /* 查找节点 */ - public TreeNode? search(int num) - { + public TreeNode? search(int num) { TreeNode? cur = root; // 循环查找,越过叶节点后跳出 - while (cur != null) - { + while (cur != null) { // 目标节点在 cur 的右子树中 if (cur.val < num) cur = cur.right; // 目标节点在 cur 的左子树中 @@ -57,14 +51,12 @@ class BinarySearchTree } /* 插入节点 */ - public void insert(int num) - { + public void insert(int num) { // 若树为空,直接提前返回 if (root == null) return; TreeNode? cur = root, pre = null; // 循环查找,越过叶节点后跳出 - while (cur != null) - { + while (cur != null) { // 找到重复节点,直接返回 if (cur.val == num) return; pre = cur; @@ -76,8 +68,7 @@ class BinarySearchTree // 插入节点 val TreeNode node = new TreeNode(num); - if (pre != null) - { + if (pre != null) { if (pre.val < num) pre.right = node; else pre.left = node; } @@ -85,14 +76,12 @@ class BinarySearchTree /* 删除节点 */ - public void remove(int num) - { + public void remove(int num) { // 若树为空,直接提前返回 if (root == null) return; TreeNode? cur = root, pre = null; // 循环查找,越过叶节点后跳出 - while (cur != null) - { + while (cur != null) { // 找到待删除节点,跳出循环 if (cur.val == num) break; pre = cur; @@ -104,27 +93,21 @@ class BinarySearchTree // 若无待删除节点,则直接返回 if (cur == null || pre == null) return; // 子节点数量 = 0 or 1 - if (cur.left == null || cur.right == null) - { + if (cur.left == null || cur.right == null) { // 当子节点数量 = 0 / 1 时, child = null / 该子节点 TreeNode? child = cur.left != null ? cur.left : cur.right; // 删除节点 cur - if (pre.left == cur) - { + if (pre.left == cur) { pre.left = child; - } - else - { + } else { pre.right = child; } } // 子节点数量 = 2 - else - { + else { // 获取中序遍历中 cur 的下一个节点 TreeNode? tmp = cur.right; - while (tmp.left != null) - { + while (tmp.left != null) { tmp = tmp.left; } // 递归删除节点 tmp @@ -135,11 +118,9 @@ class BinarySearchTree } } -public class binary_search_tree -{ +public class binary_search_tree { [Test] - public void Test() - { + public void Test() { /* 初始化二叉搜索树 */ int[] nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; BinarySearchTree bst = new BinarySearchTree(nums); diff --git a/codes/csharp/chapter_tree/binary_tree.cs b/codes/csharp/chapter_tree/binary_tree.cs index c1a0292e..d94b8789 100644 --- a/codes/csharp/chapter_tree/binary_tree.cs +++ b/codes/csharp/chapter_tree/binary_tree.cs @@ -9,11 +9,9 @@ using NUnit.Framework; namespace hello_algo.chapter_tree; -public class binary_tree -{ +public class binary_tree { [Test] - public void Test() - { + public void Test() { /* 初始化二叉树 */ // 初始化节点 TreeNode n1 = new TreeNode(1); diff --git a/codes/csharp/chapter_tree/binary_tree_bfs.cs b/codes/csharp/chapter_tree/binary_tree_bfs.cs index 6ee2fa33..18b2810b 100644 --- a/codes/csharp/chapter_tree/binary_tree_bfs.cs +++ b/codes/csharp/chapter_tree/binary_tree_bfs.cs @@ -9,19 +9,16 @@ using NUnit.Framework; namespace hello_algo.chapter_tree; -public class binary_tree_bfs -{ +public class binary_tree_bfs { /* 层序遍历 */ - public List levelOrder(TreeNode root) - { + public List levelOrder(TreeNode root) { // 初始化队列,加入根节点 Queue queue = new(); queue.Enqueue(root); // 初始化一个列表,用于保存遍历序列 List list = new(); - while (queue.Count != 0) - { + while (queue.Count != 0) { TreeNode node = queue.Dequeue(); // 队列出队 list.Add(node.val); // 保存节点值 if (node.left != null) @@ -33,8 +30,7 @@ public class binary_tree_bfs } [Test] - public void Test() - { + public void Test() { /* 初始化二叉树 */ // 这里借助了一个从数组直接生成二叉树的函数 TreeNode? root = TreeNode.ListToTree(new List { 1, 2, 3, 4, 5, 6, 7 }); diff --git a/codes/csharp/chapter_tree/binary_tree_dfs.cs b/codes/csharp/chapter_tree/binary_tree_dfs.cs index b82bb86f..9af19eab 100644 --- a/codes/csharp/chapter_tree/binary_tree_dfs.cs +++ b/codes/csharp/chapter_tree/binary_tree_dfs.cs @@ -9,13 +9,11 @@ using NUnit.Framework; namespace hello_algo.chapter_tree; -public class binary_tree_dfs -{ +public class binary_tree_dfs { List list = new(); /* 前序遍历 */ - void preOrder(TreeNode? root) - { + void preOrder(TreeNode? root) { if (root == null) return; // 访问优先级:根节点 -> 左子树 -> 右子树 list.Add(root.val); @@ -24,8 +22,7 @@ public class binary_tree_dfs } /* 中序遍历 */ - void inOrder(TreeNode? root) - { + void inOrder(TreeNode? root) { if (root == null) return; // 访问优先级:左子树 -> 根节点 -> 右子树 inOrder(root.left); @@ -34,8 +31,7 @@ public class binary_tree_dfs } /* 后序遍历 */ - void postOrder(TreeNode? root) - { + void postOrder(TreeNode? root) { if (root == null) return; // 访问优先级:左子树 -> 右子树 -> 根节点 postOrder(root.left); @@ -44,8 +40,7 @@ public class binary_tree_dfs } [Test] - public void Test() - { + public void Test() { /* 初始化二叉树 */ // 这里借助了一个从数组直接生成二叉树的函数 TreeNode? root = TreeNode.ListToTree(new List { 1, 2, 3, 4, 5, 6, 7 }); diff --git a/codes/csharp/include/ListNode.cs b/codes/csharp/include/ListNode.cs index eb724b67..8bc8acf2 100644 --- a/codes/csharp/include/ListNode.cs +++ b/codes/csharp/include/ListNode.cs @@ -4,61 +4,38 @@ namespace hello_algo.include; -/// -/// Definition for a singly-linked list node -/// -public class ListNode -{ +/* Definition for a singly-linked list node */ +public class ListNode { public int val; public ListNode? next; - /// - /// Generate a linked list with an array - /// - /// - public ListNode(int x) - { + public ListNode(int x) { val = x; } - /// - /// Generate a linked list with an array - /// - /// - /// - public static ListNode? ArrToLinkedList(int[] arr) - { + /* Generate a linked list with an array */ + public static ListNode? ArrToLinkedList(int[] arr) { ListNode dum = new ListNode(0); ListNode head = dum; - foreach (int val in arr) - { + foreach (int val in arr) { head.next = new ListNode(val); head = head.next; } return dum.next; } - /// - /// Get a list node with specific value from a linked list - /// - /// - /// - /// - public static ListNode? GetListNode(ListNode? head, int val) - { - while (head != null && head.val != val) - { + /* Get a list node with specific value from a linked list */ + public static ListNode? GetListNode(ListNode? head, int val) { + while (head != null && head.val != val) { head = head.next; } return head; } - public override string? ToString() - { + public override string? ToString() { List list = new(); var head = this; - while (head != null) - { + while (head != null) { list.Add(head.val.ToString()); head = head.next; } diff --git a/codes/csharp/include/PrintUtil.cs b/codes/csharp/include/PrintUtil.cs index b258c0a3..e64b555a 100644 --- a/codes/csharp/include/PrintUtil.cs +++ b/codes/csharp/include/PrintUtil.cs @@ -6,60 +6,44 @@ namespace hello_algo.include; -public class Trunk -{ +public class Trunk { public Trunk? prev; public string str; - public Trunk(Trunk? prev, string str) - { + public Trunk(Trunk? prev, string str) { this.prev = prev; this.str = str; } }; -public class PrintUtil -{ - /** - * Print a list - * @param list - */ - public static void PrintList(List list) - { +public class PrintUtil { + /* Print a list */ + public static void PrintList(List list) { Console.WriteLine("[" + string.Join(", ", list) + "]"); } /* Print a matrix (Array) */ - public static void PrintMatrix(T[][] matrix) - { + public static void PrintMatrix(T[][] matrix) { Console.WriteLine("["); - foreach (T[] row in matrix) - { + foreach (T[] row in matrix) { Console.WriteLine(" " + string.Join(", ", row) + ","); } Console.WriteLine("]"); } /* Print a matrix (List) */ - public static void PrintMatrix(List> matrix) - { + public static void PrintMatrix(List> matrix) { Console.WriteLine("["); - foreach (List row in matrix) - { + foreach (List row in matrix) { Console.WriteLine(" " + string.Join(", ", row) + ","); } Console.WriteLine("]"); } - /** - * Print a linked list - * @param head - */ - public static void PrintLinkedList(ListNode head) - { + /* Print a linked list */ + public static void PrintLinkedList(ListNode head) { List list = new(); - while (head != null) - { + while (head != null) { list.Add(head.val.ToString()); head = head.next; } @@ -70,23 +54,14 @@ public class PrintUtil * 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 */ - public static void PrintTree(TreeNode? root) - { + public static void PrintTree(TreeNode? root) { PrintTree(root, null, false); } - /** - * Print a binary tree - * @param root - * @param prev - * @param isLeft - */ - public static void PrintTree(TreeNode? root, Trunk? prev, bool isLeft) - { - if (root == null) - { + /* Print a binary tree */ + public static void PrintTree(TreeNode? root, Trunk? prev, bool isLeft) { + if (root == null) { return; } @@ -95,17 +70,12 @@ public class PrintUtil PrintTree(root.right, trunk, true); - if (prev == null) - { + if (prev == null) { trunk.str = "———"; - } - else if (isLeft) - { + } else if (isLeft) { trunk.str = "/———"; prev_str = " |"; - } - else - { + } else { trunk.str = "\\———"; prev.str = prev_str; } @@ -113,8 +83,7 @@ public class PrintUtil ShowTrunks(trunk); Console.WriteLine(" " + root.val); - if (prev != null) - { + if (prev != null) { prev.str = prev_str; } trunk.str = " |"; @@ -122,14 +91,9 @@ public class PrintUtil PrintTree(root.left, trunk, false); } - /** - * Helper function to print branches of the binary tree - * @param p - */ - public static void ShowTrunks(Trunk? p) - { - if (p == null) - { + /* Helper function to print branches of the binary tree */ + public static void ShowTrunks(Trunk? p) { + if (p == null) { return; } @@ -137,22 +101,15 @@ public class PrintUtil Console.Write(p.str); } - /** - * Print a hash map - * @param - * @param - * @param map - */ - public static void PrintHashMap(Dictionary map) where K : notnull - { - foreach (var kv in map.Keys) - { + /* Print a hash map */ + public static void PrintHashMap(Dictionary map) where K : notnull { + foreach (var kv in map.Keys) { Console.WriteLine(kv.ToString() + " -> " + map[kv]?.ToString()); } } - public static void PrintHeap(Queue queue) - { + /* Print a heap */ + public static void PrintHeap(Queue queue) { Console.Write("堆的数组表示:"); List list = queue.ToList(); Console.WriteLine(string.Join(',', list)); @@ -161,13 +118,12 @@ public class PrintUtil PrintTree(tree); } - public static void PrintHeap(PriorityQueue queue) - { + /* Print a PriorityQueue */ + public static void PrintHeap(PriorityQueue queue) { var newQueue = new PriorityQueue(queue.UnorderedItems, queue.Comparer); - Console.Write("堆的数组表示:"); + Console.Write("堆的数组表示:"); List list = new List(); - while (newQueue.TryDequeue(out int element, out int priority)) - { + while (newQueue.TryDequeue(out int element, out int priority)) { list.Add(element); } Console.WriteLine("堆的树状表示:"); diff --git a/codes/csharp/include/TreeNode.cs b/codes/csharp/include/TreeNode.cs index d76aef27..bd810a8c 100644 --- a/codes/csharp/include/TreeNode.cs +++ b/codes/csharp/include/TreeNode.cs @@ -6,25 +6,19 @@ namespace hello_algo.include; -public class TreeNode -{ +/* 二叉树节点类 */ +public class TreeNode { public int val; // 节点值 public int height; // 节点高度 public TreeNode? left; // 左子节点引用 public TreeNode? right; // 右子节点引用 - public TreeNode(int x) - { + public TreeNode(int x) { val = x; } - /** - * Generate a binary tree given an array - * @param arr - * @return - */ - public static TreeNode? ListToTree(List arr) - { + /* Generate a binary tree given an array */ + public static TreeNode? ListToTree(List arr) { if (arr.Count == 0 || arr[0] == null) return null; @@ -32,18 +26,15 @@ public class TreeNode Queue queue = new Queue(); queue.Enqueue(root); int i = 0; - while (queue.Count != 0) - { + while (queue.Count != 0) { TreeNode node = queue.Dequeue(); if (++i >= arr.Count) break; - if (arr[i] != null) - { + if (arr[i] != null) { node.left = new TreeNode((int)arr[i]); queue.Enqueue(node.left); } if (++i >= arr.Count) break; - if (arr[i] != null) - { + if (arr[i] != null) { node.right = new TreeNode((int)arr[i]); queue.Enqueue(node.right); } @@ -51,41 +42,26 @@ public class TreeNode return root; } - /** - * Serialize a binary tree to a list - * @param root - * @return - */ - public static List TreeToList(TreeNode root) - { + /* Serialize a binary tree to a list */ + public static List TreeToList(TreeNode root) { List list = new(); if (root == null) return list; Queue queue = new(); - while (queue.Count != 0) - { + while (queue.Count != 0) { TreeNode? node = queue.Dequeue(); - if (node != null) - { + if (node != null) { list.Add(node.val); queue.Enqueue(node.left); queue.Enqueue(node.right); - } - else - { + } else { list.Add(null); } } return list; } - /** - * Get a tree node with specific value in a binary tree - * @param root - * @param val - * @return - */ - public static TreeNode? GetTreeNode(TreeNode? root, int val) - { + /* Get a tree node with specific value in a binary tree */ + public static TreeNode? GetTreeNode(TreeNode? root, int val) { if (root == null) return null; if (root.val == val) diff --git a/codes/csharp/include/Vertex.cs b/codes/csharp/include/Vertex.cs index 4d74a930..19b89e8d 100644 --- a/codes/csharp/include/Vertex.cs +++ b/codes/csharp/include/Vertex.cs @@ -7,31 +7,25 @@ namespace hello_algo.include; /* 顶点类 */ -public class Vertex -{ +public class Vertex { public int val; - public Vertex(int val) - { + public Vertex(int val) { this.val = val; } /* 输入值列表 vals ,返回顶点列表 vets */ - public static Vertex[] ValsToVets(int[] vals) - { + public static Vertex[] ValsToVets(int[] vals) { Vertex[] vets = new Vertex[vals.Length]; - for (int i = 0; i < vals.Length; i++) - { + for (int i = 0; i < vals.Length; i++) { vets[i] = new Vertex(vals[i]); } return vets; } /* 输入顶点列表 vets ,返回值列表 vals */ - public static List VetsToVals(List vets) - { + public static List VetsToVals(List vets) { List vals = new List(); - foreach (Vertex vet in vets) - { + foreach (Vertex vet in vets) { vals.Add(vet.val); } return vals;