From b1645c7d7ee9b12d0ac1cd35f48ade20fe4f3488 Mon Sep 17 00:00:00 2001 From: Yudong Jin Date: Sat, 24 Dec 2022 16:15:41 +0800 Subject: [PATCH] Fine tune --- .../chapter_array_and_linkedlist/Array.cs | 4 +- .../{LinkedList.cs => linked_list.cs} | 10 +- .../chapter_array_and_linkedlist/my_list.cs | 50 ++++----- .../space_complexity.cs | 2 +- .../worst_best_time_complexity.cs | 5 +- .../chapter_searching/hashing_search.cs | 2 +- codes/csharp/chapter_sorting/bubble_sort.cs | 2 +- .../csharp/chapter_sorting/insertion_sort.cs | 2 +- codes/csharp/chapter_sorting/merge_sort.cs | 2 +- codes/csharp/chapter_stack_and_queue/stack.cs | 1 + codes/csharp/chapter_tree/avl_tree.cs | 10 +- .../csharp/chapter_tree/binary_search_tree.cs | 101 +++++++++--------- codes/csharp/chapter_tree/binary_tree.cs | 6 +- codes/csharp/chapter_tree/binary_tree_bfs.cs | 94 +++------------- codes/csharp/chapter_tree/binary_tree_dfs.cs | 78 ++++++++++++++ codes/csharp/include/PrintUtil.cs | 14 +-- codes/csharp/include/TreeNode.cs | 22 ++-- docs/chapter_array_and_linkedlist/list.md | 37 +++---- docs/chapter_sorting/bubble_sort.md | 2 +- docs/chapter_sorting/insertion_sort.md | 2 +- docs/chapter_sorting/merge_sort.md | 2 +- docs/chapter_tree/avl_tree.md | 7 +- docs/chapter_tree/binary_search_tree.md | 7 +- docs/chapter_tree/binary_tree_traversal.md | 6 +- 24 files changed, 235 insertions(+), 233 deletions(-) rename codes/csharp/chapter_array_and_linkedlist/{LinkedList.cs => linked_list.cs} (95%) create mode 100644 codes/csharp/chapter_tree/binary_tree_dfs.cs diff --git a/codes/csharp/chapter_array_and_linkedlist/Array.cs b/codes/csharp/chapter_array_and_linkedlist/Array.cs index cc6b79dd4..95479574f 100644 --- a/codes/csharp/chapter_array_and_linkedlist/Array.cs +++ b/codes/csharp/chapter_array_and_linkedlist/Array.cs @@ -1,4 +1,4 @@ -// File: Array.cs +// File: array.cs // Created Time: 2022-12-14 // Author: mingXta (1195669834@qq.com) @@ -134,4 +134,4 @@ namespace hello_algo.chapter_array_and_linkedlist Console.WriteLine("在 nums 中查找元素 3 ,得到索引 = " + index); } } -} \ No newline at end of file +} diff --git a/codes/csharp/chapter_array_and_linkedlist/LinkedList.cs b/codes/csharp/chapter_array_and_linkedlist/linked_list.cs similarity index 95% rename from codes/csharp/chapter_array_and_linkedlist/LinkedList.cs rename to codes/csharp/chapter_array_and_linkedlist/linked_list.cs index ecc7aabc3..d700a5ae7 100644 --- a/codes/csharp/chapter_array_and_linkedlist/LinkedList.cs +++ b/codes/csharp/chapter_array_and_linkedlist/linked_list.cs @@ -1,4 +1,4 @@ -// File: LinkedList.cs +// File: linked_list.cs // Created Time: 2022-12-16 // Author: mingXta (1195669834@qq.com) @@ -7,14 +7,14 @@ using NUnit.Framework; namespace hello_algo.chapter_array_and_linkedlist { - public class LinkedList + public class linked_list { /// /// 在链表的结点 n0 之后插入结点 P /// public static void Insert(ListNode n0, ListNode P) { - ListNode n1 = n0.next; + ListNode? n1 = n0.next; n0.next = P; P.next = n1; } @@ -28,7 +28,7 @@ namespace hello_algo.chapter_array_and_linkedlist return; // n0 -> P -> n1 ListNode P = n0.next; - ListNode n1 = P.next; + ListNode? n1 = P.next; n0.next = n1; } @@ -97,4 +97,4 @@ namespace hello_algo.chapter_array_and_linkedlist Console.WriteLine($"链表中值为 2 的结点的索引 = {index}"); } } -} \ No newline at end of file +} diff --git a/codes/csharp/chapter_array_and_linkedlist/my_list.cs b/codes/csharp/chapter_array_and_linkedlist/my_list.cs index 7ea09cf04..327180625 100644 --- a/codes/csharp/chapter_array_and_linkedlist/my_list.cs +++ b/codes/csharp/chapter_array_and_linkedlist/my_list.cs @@ -34,7 +34,7 @@ namespace hello_algo.chapter_array_and_linkedlist } /* 访问元素 */ - public int get(int index) + public int Get(int index) { // 索引如果越界则抛出异常,下同 if (index >= size) @@ -43,7 +43,7 @@ namespace hello_algo.chapter_array_and_linkedlist } /* 更新元素 */ - public void set(int index, int num) + public void Set(int index, int num) { if (index >= size) throw new IndexOutOfRangeException("索引越界"); @@ -51,24 +51,24 @@ namespace hello_algo.chapter_array_and_linkedlist } /* 尾部添加元素 */ - public void add(int num) + public void Add(int num) { // 元素数量超出容量时,触发扩容机制 if (size == Capacity()) - extendCapacity(); + ExtendCapacity(); nums[size] = num; // 更新元素数量 size++; } /* 中间插入元素 */ - public void insert(int index, int num) + public void Insert(int index, int num) { if (index >= size) throw new IndexOutOfRangeException("索引越界"); // 元素数量超出容量时,触发扩容机制 if (size == Capacity()) - extendCapacity(); + ExtendCapacity(); // 将索引 index 以及之后的元素都向后移动一位 for (int j = size - 1; j >= index; j--) { @@ -80,7 +80,7 @@ namespace hello_algo.chapter_array_and_linkedlist } /* 删除元素 */ - public int remove(int index) + public int Remove(int index) { if (index >= size) throw new IndexOutOfRangeException("索引越界"); @@ -97,7 +97,7 @@ namespace hello_algo.chapter_array_and_linkedlist } /* 列表扩容 */ - public void extendCapacity() + public void ExtendCapacity() { // 新建一个长度为 size 的数组,并将原数组拷贝到新数组 System.Array.Resize(ref nums, Capacity() * extendRatio); @@ -106,14 +106,14 @@ namespace hello_algo.chapter_array_and_linkedlist } /* 将列表转换为数组 */ - public int[] toArray() + public int[] ToArray() { int size = Size(); // 仅转换有效长度范围内的列表元素 int[] nums = new int[size]; for (int i = 0; i < size; i++) { - nums[i] = get(i); + nums[i] = Get(i); } return nums; } @@ -127,37 +127,37 @@ namespace hello_algo.chapter_array_and_linkedlist /* 初始化列表 */ MyList list = new MyList(); /* 尾部添加元素 */ - list.add(1); - list.add(3); - list.add(2); - list.add(5); - list.add(4); - Console.WriteLine("列表 list = " + string.Join(",", list.toArray()) + + list.Add(1); + list.Add(3); + list.Add(2); + list.Add(5); + list.Add(4); + Console.WriteLine("列表 list = " + string.Join(",", list.ToArray()) + " ,容量 = " + list.Capacity() + " ,长度 = " + list.Size()); /* 中间插入元素 */ - list.insert(3, 6); - Console.WriteLine("在索引 3 处插入数字 6 ,得到 list = " + string.Join(",", list.toArray())); + list.Insert(3, 6); + Console.WriteLine("在索引 3 处插入数字 6 ,得到 list = " + string.Join(",", list.ToArray())); /* 删除元素 */ - list.remove(3); - Console.WriteLine("删除索引 3 处的元素,得到 list = " + string.Join(",", list.toArray())); + list.Remove(3); + Console.WriteLine("删除索引 3 处的元素,得到 list = " + string.Join(",", list.ToArray())); /* 访问元素 */ - int num = list.get(1); + int num = list.Get(1); Console.WriteLine("访问索引 1 处的元素,得到 num = " + num); /* 更新元素 */ - list.set(1, 0); - Console.WriteLine("将索引 1 处的元素更新为 0 ,得到 list = " + string.Join(",", list.toArray())); + list.Set(1, 0); + Console.WriteLine("将索引 1 处的元素更新为 0 ,得到 list = " + string.Join(",", list.ToArray())); /* 测试扩容机制 */ for (int i = 0; i < 10; i++) { // 在 i = 5 时,列表长度将超出列表容量,此时触发扩容机制 - list.add(i); + list.Add(i); } - Console.WriteLine("扩容后的列表 list = " + string.Join(",", list.toArray()) + + Console.WriteLine("扩容后的列表 list = " + string.Join(",", list.ToArray()) + " ,容量 = " + list.Capacity() + " ,长度 = " + list.Size()); } } diff --git a/codes/csharp/chapter_computational_complexity/space_complexity.cs b/codes/csharp/chapter_computational_complexity/space_complexity.cs index 6148bf1b7..c534c81b2 100644 --- a/codes/csharp/chapter_computational_complexity/space_complexity.cs +++ b/codes/csharp/chapter_computational_complexity/space_complexity.cs @@ -116,7 +116,7 @@ namespace hello_algo.chapter_computational_complexity quadraticRecur(n); // 指数阶 TreeNode? root = buildTree(n); - PrintUtil.printTree(root); + PrintUtil.PrintTree(root); } } } 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 67d9b4efb..9759cd584 100644 --- a/codes/csharp/chapter_computational_complexity/worst_best_time_complexity.cs +++ b/codes/csharp/chapter_computational_complexity/worst_best_time_complexity.cs @@ -4,6 +4,8 @@ * Author: haptear (haptear@hotmail.com) */ +using NUnit.Framework; + namespace hello_algo.chapter_computational_complexity { public class worst_best_time_complexity @@ -43,7 +45,8 @@ namespace hello_algo.chapter_computational_complexity /* Driver Code */ - public static void main(String[] args) + [Test] + public void Test() { for (int i = 0; i < 10; i++) { diff --git a/codes/csharp/chapter_searching/hashing_search.cs b/codes/csharp/chapter_searching/hashing_search.cs index e4c2f2f2b..33d5fe9dc 100644 --- a/codes/csharp/chapter_searching/hashing_search.cs +++ b/codes/csharp/chapter_searching/hashing_search.cs @@ -45,7 +45,7 @@ namespace hello_algo.chapter_searching Console.WriteLine("目标元素 3 的索引 = " + index); /* 哈希查找(链表) */ - ListNode head = ListNode.ArrToLinkedList(nums); + ListNode? head = ListNode.ArrToLinkedList(nums); // 初始化哈希表 Dictionary map1 = new(); while (head != null) diff --git a/codes/csharp/chapter_sorting/bubble_sort.cs b/codes/csharp/chapter_sorting/bubble_sort.cs index 9506f7973..b3304df04 100644 --- a/codes/csharp/chapter_sorting/bubble_sort.cs +++ b/codes/csharp/chapter_sorting/bubble_sort.cs @@ -37,7 +37,7 @@ namespace hello_algo.chapter_sorting 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]) diff --git a/codes/csharp/chapter_sorting/insertion_sort.cs b/codes/csharp/chapter_sorting/insertion_sort.cs index b5f87acf0..0f674c9fc 100644 --- a/codes/csharp/chapter_sorting/insertion_sort.cs +++ b/codes/csharp/chapter_sorting/insertion_sort.cs @@ -20,7 +20,7 @@ namespace hello_algo.chapter_sorting // 内循环:将 base 插入到左边的正确位置 while (j >= 0 && nums[j] > bas) { - nums[j + 1] = nums[j]; // 1. 将 nums[j] 向右移动一位 + nums[j + 1] = nums[j]; // 1. 将 nums[j] 向右移动一位 j--; } nums[j + 1] = bas; // 2. 将 base 赋值到正确位置 diff --git a/codes/csharp/chapter_sorting/merge_sort.cs b/codes/csharp/chapter_sorting/merge_sort.cs index d7f9ff985..04ac8acdd 100644 --- a/codes/csharp/chapter_sorting/merge_sort.cs +++ b/codes/csharp/chapter_sorting/merge_sort.cs @@ -18,7 +18,7 @@ namespace hello_algo.chapter_sorting static void merge(int[] nums, int left, int mid, int right) { // 初始化辅助数组 - int[] tmp = nums[left..(right + 1)];//Array.CopyOfRange(nums, left, right + 1); + int[] tmp = nums[left..(right + 1)]; // 左子数组的起始索引和结束索引 int leftStart = left - left, leftEnd = mid - left; // 右子数组的起始索引和结束索引 diff --git a/codes/csharp/chapter_stack_and_queue/stack.cs b/codes/csharp/chapter_stack_and_queue/stack.cs index 2595dea50..c19666b72 100644 --- a/codes/csharp/chapter_stack_and_queue/stack.cs +++ b/codes/csharp/chapter_stack_and_queue/stack.cs @@ -22,6 +22,7 @@ namespace hello_algo.chapter_stack_and_queue stack.Push(2); stack.Push(5); stack.Push(4); + // 请注意,stack.ToArray() 得到的是倒序序列,即索引 0 为栈顶 Console.WriteLine("栈 stack = " + string.Join(",", stack.ToArray())); /* 访问栈顶元素 */ diff --git a/codes/csharp/chapter_tree/avl_tree.cs b/codes/csharp/chapter_tree/avl_tree.cs index 7cef62318..f2dcde219 100644 --- a/codes/csharp/chapter_tree/avl_tree.cs +++ b/codes/csharp/chapter_tree/avl_tree.cs @@ -148,7 +148,7 @@ namespace hello_algo.chapter_tree } /* 递归删除结点(辅助函数) */ - private TreeNode? removeHelper(TreeNode? node, int? val) + private TreeNode? removeHelper(TreeNode? node, int val) { if (node == null) return null; /* 1. 查找结点,并删除之 */ @@ -172,8 +172,8 @@ namespace hello_algo.chapter_tree { // 子结点数量 = 2 ,则将中序遍历的下个结点删除,并用该结点替换当前结点 TreeNode? temp = minNode(node.right); - node.right = removeHelper(node.right, temp?.val); - node.val = temp?.val; + node.right = removeHelper(node.right, temp.val); + node.val = temp.val; } } updateHeight(node); // 更新结点高度 @@ -223,14 +223,14 @@ namespace hello_algo.chapter_tree { tree.insert(val); Console.WriteLine("\n插入结点 " + val + " 后,AVL 树为"); - PrintUtil.printTree(tree.root); + PrintUtil.PrintTree(tree.root); } static void testRemove(AVLTree tree, int val) { tree.remove(val); Console.WriteLine("\n删除结点 " + val + " 后,AVL 树为"); - PrintUtil.printTree(tree.root); + PrintUtil.PrintTree(tree.root); } [Test] diff --git a/codes/csharp/chapter_tree/binary_search_tree.cs b/codes/csharp/chapter_tree/binary_search_tree.cs index 00958dcba..8224317df 100644 --- a/codes/csharp/chapter_tree/binary_search_tree.cs +++ b/codes/csharp/chapter_tree/binary_search_tree.cs @@ -9,16 +9,38 @@ using NUnit.Framework; namespace hello_algo.chapter_tree { - internal class binary_search_tree + class BinarySearchTree { TreeNode? root; + public BinarySearchTree(int[] nums) { + Array.Sort(nums); // 排序数组 + root = buildTree(nums, 0, nums.Length - 1); // 构建二叉搜索树 + } + + /* 获取二叉树根结点 */ + public TreeNode? getRoot() { + return root; + } + + /* 构建二叉搜索树 */ + public TreeNode? buildTree(int[] nums, int i, int j) { + if (i > j) return null; + // 将数组中间结点作为根结点 + int mid = (i + j) / 2; + TreeNode root = new TreeNode(nums[mid]); + // 递归建立左子树和右子树 + root.left = buildTree(nums, i, mid - 1); + root.right = buildTree(nums, mid + 1, j); + return root; + } + /// /// 查找结点 /// /// /// - TreeNode? search(int num) + public TreeNode? search(int num) { TreeNode? cur = root; // 循环查找,越过叶结点后跳出 @@ -36,7 +58,7 @@ namespace hello_algo.chapter_tree } /* 插入结点 */ - TreeNode? insert(int num) + public TreeNode? insert(int num) { // 若树为空,直接提前返回 if (root == null) return null; @@ -65,7 +87,7 @@ namespace hello_algo.chapter_tree /* 删除结点 */ - TreeNode? remove(int? num) + public TreeNode? remove(int num) { // 若树为空,直接提前返回 if (root == null) return null; @@ -106,7 +128,7 @@ namespace hello_algo.chapter_tree TreeNode? nex = min(cur.right); if (nex != null) { - int? tmp = nex.val; + int tmp = nex.val; // 递归删除结点 nex remove(nex.val); // 将 nex 的值复制给 cur @@ -117,7 +139,7 @@ namespace hello_algo.chapter_tree } /* 获取最小结点 */ - TreeNode? min(TreeNode? root) + private TreeNode? min(TreeNode? root) { if (root == null) return root; // 循环访问左子结点,直到叶结点时为最小结点,跳出 @@ -127,55 +149,38 @@ namespace hello_algo.chapter_tree } return root; } + } + public class binary_search_tree + { [Test] public void Test() { - // 初始化结点 - TreeNode n1 = new TreeNode(1); - TreeNode n2 = new TreeNode(2); - TreeNode n3 = new TreeNode(3); - TreeNode n4 = new TreeNode(4); - TreeNode n5 = new TreeNode(5); - TreeNode n6 = new TreeNode(6); - TreeNode n7 = new TreeNode(7); - TreeNode n8 = new TreeNode(8); - TreeNode n9 = new TreeNode(9); - TreeNode n10 = new TreeNode(10); - TreeNode n11 = new TreeNode(11); - TreeNode n12 = new TreeNode(12); - TreeNode n13 = new TreeNode(13); - TreeNode n14 = new TreeNode(14); - TreeNode n15 = new TreeNode(15); - root = n8; - root.left = n4; - root.right = n12; - n4.left = n2; - n4.right = n6; - n12.left = n10; - n12.right = n14; - n2.left = n1; - n2.right = n3; - n6.left = n5; - n6.right = n7; - n10.left = n9; - n10.right = n11; - n14.left = n13; - n14.right = n15; + /* 初始化二叉搜索树 */ + int[] nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; + BinarySearchTree bst = new BinarySearchTree(nums); + Console.WriteLine("\n初始化的二叉树为\n"); + PrintUtil.PrintTree(bst.getRoot()); - var cur = search(7); - Console.WriteLine("查找结点 结果 = " + cur?.val); + /* 查找结点 */ + TreeNode? node = bst.search(5); + Console.WriteLine("\n查找到的结点对象为 " + node + ",结点值 = " + node.val); - var node = insert(16); - Console.WriteLine("插入结点 结果 = " + node?.val); - - node = remove(1); - Console.WriteLine("删除结点 结果 = " + node?.val); - node = remove(2); - Console.WriteLine("删除结点 结果 = " + node?.val); - node = remove(4); - Console.WriteLine("删除结点 结果 = " + node?.val); + /* 插入结点 */ + node = bst.insert(16); + Console.WriteLine("\n插入结点 16 后,二叉树为\n"); + PrintUtil.PrintTree(bst.getRoot()); + /* 删除结点 */ + bst.remove(1); + Console.WriteLine("\n删除结点 1 后,二叉树为\n"); + PrintUtil.PrintTree(bst.getRoot()); + bst.remove(2); + Console.WriteLine("\n删除结点 2 后,二叉树为\n"); + PrintUtil.PrintTree(bst.getRoot()); + bst.remove(4); + Console.WriteLine("\n删除结点 4 后,二叉树为\n"); + PrintUtil.PrintTree(bst.getRoot()); } } } diff --git a/codes/csharp/chapter_tree/binary_tree.cs b/codes/csharp/chapter_tree/binary_tree.cs index 88b5f767e..275a69f93 100644 --- a/codes/csharp/chapter_tree/binary_tree.cs +++ b/codes/csharp/chapter_tree/binary_tree.cs @@ -28,7 +28,7 @@ namespace hello_algo.chapter_tree n2.left = n4; n2.right = n5; Console.WriteLine("\n初始化二叉树\n"); - PrintUtil.printTree(n1); + PrintUtil.PrintTree(n1); /* 插入与删除结点 */ TreeNode P = new TreeNode(0); @@ -36,11 +36,11 @@ namespace hello_algo.chapter_tree n1.left = P; P.left = n2; Console.WriteLine("\n插入结点 P 后\n"); - PrintUtil.printTree(n1); + PrintUtil.PrintTree(n1); // 删除结点 P n1.left = n2; Console.WriteLine("\n删除结点 P 后\n"); - PrintUtil.printTree(n1); + PrintUtil.PrintTree(n1); } } } \ No newline at end of file diff --git a/codes/csharp/chapter_tree/binary_tree_bfs.cs b/codes/csharp/chapter_tree/binary_tree_bfs.cs index b686c8892..31f707246 100644 --- a/codes/csharp/chapter_tree/binary_tree_bfs.cs +++ b/codes/csharp/chapter_tree/binary_tree_bfs.cs @@ -17,17 +17,17 @@ namespace hello_algo.chapter_tree /// /// /// - public List hierOrder(TreeNode root) + public List hierOrder(TreeNode root) { // 初始化队列,加入根结点 Queue queue = new(); queue.Enqueue(root); // 初始化一个列表,用于保存遍历序列 - List list = new(); + List list = new(); while (queue.Count != 0) { - TreeNode node = queue.Dequeue(); // 队列出队 - list.Add(node.val); // 保存结点值 + TreeNode node = queue.Dequeue(); // 队列出队 + list.Add(node.val); // 保存结点值 if (node.left != null) queue.Enqueue(node.left); // 左子结点入队 if (node.right != null) @@ -36,88 +36,18 @@ namespace hello_algo.chapter_tree return list; } - List list = new(); - - /// - /// 前序遍历 - /// - /// - void preOrder(TreeNode? root) - { - if (root == null) return; - // 访问优先级:根结点 -> 左子树 -> 右子树 - list.Add(root.val); - preOrder(root.left); - preOrder(root.right); - } - - /// - /// 中序遍历 - /// - /// - void inOrder(TreeNode? root) - { - if (root == null) return; - // 访问优先级:左子树 -> 根结点 -> 右子树 - inOrder(root.left); - list.Add(root.val); - inOrder(root.right); - } - - /// - /// 后序遍历 - /// - /// - void postOrder(TreeNode? root) - { - if (root == null) return; - // 访问优先级:左子树 -> 右子树 -> 根结点 - postOrder(root.left); - postOrder(root.right); - list.Add(root.val); - } - - /// - /// 辅助函数,数组转字符串 - /// - public static string ToString(int?[] nums) - { - return string.Join(",", nums); - } - [Test] public void Test() { - // 初始化结点 - TreeNode root = new TreeNode(1); - TreeNode n2 = new TreeNode(2); - TreeNode n3 = new TreeNode(3); - TreeNode n4 = new TreeNode(4); - TreeNode n5 = new TreeNode(5); - TreeNode n6 = new TreeNode(6); - TreeNode n7 = new TreeNode(7); - // 构建引用指向(即指针) - root.left = n2; - root.right = n3; - n2.left = n4; - n2.right = n5; - n3.left = n6; - n3.right = n7; + /* 初始化二叉树 */ + // 这里借助了一个从数组直接生成二叉树的函数 + TreeNode? root = TreeNode.ArrToTree(new int?[] { + 1, 2, 3, 4, 5, 6, 7, null, null, null, null, null, null, null, null}); + Console.WriteLine("\n初始化二叉树\n"); + PrintUtil.PrintTree(root); - list = hierOrder(root); - Console.WriteLine("层序遍历 结果 = " + ToString(list.ToArray())); - - list = new List(); - preOrder(root); - Console.WriteLine("前序遍历 结果 = " + ToString(list.ToArray())); - - list = new List(); - inOrder(root); - Console.WriteLine("中序遍历 结果 = " + ToString(list.ToArray())); - - list = new List(); - postOrder(root); - Console.WriteLine("后序遍历 结果 = " + ToString(list.ToArray())); + List list = hierOrder(root); + Console.WriteLine("\n层序遍历的结点打印序列 = " + string.Join(",", list.ToArray())); } } } diff --git a/codes/csharp/chapter_tree/binary_tree_dfs.cs b/codes/csharp/chapter_tree/binary_tree_dfs.cs new file mode 100644 index 000000000..6e38ebe4c --- /dev/null +++ b/codes/csharp/chapter_tree/binary_tree_dfs.cs @@ -0,0 +1,78 @@ +/** + * File: binary_tree_bfs.cs + * Created Time: 2022-12-23 + * Author: haptear (haptear@hotmail.com) + */ + +using hello_algo.include; +using NUnit.Framework; + +namespace hello_algo.chapter_tree +{ + public class binary_tree_dfs + { + List list = new(); + + /// + /// 前序遍历 + /// + /// + void preOrder(TreeNode? root) + { + if (root == null) return; + // 访问优先级:根结点 -> 左子树 -> 右子树 + list.Add(root.val); + preOrder(root.left); + preOrder(root.right); + } + + /// + /// 中序遍历 + /// + /// + void inOrder(TreeNode? root) + { + if (root == null) return; + // 访问优先级:左子树 -> 根结点 -> 右子树 + inOrder(root.left); + list.Add(root.val); + inOrder(root.right); + } + + /// + /// 后序遍历 + /// + /// + void postOrder(TreeNode? root) + { + if (root == null) return; + // 访问优先级:左子树 -> 右子树 -> 根结点 + postOrder(root.left); + postOrder(root.right); + list.Add(root.val); + } + + [Test] + public void Test() + { + /* 初始化二叉树 */ + // 这里借助了一个从数组直接生成二叉树的函数 + TreeNode? root = TreeNode.ArrToTree(new int?[] { + 1, 2, 3, 4, 5, 6, 7, null, null, null, null, null, null, null, null}); + Console.WriteLine("\n初始化二叉树\n"); + PrintUtil.PrintTree(root); + + list.Clear(); + preOrder(root); + Console.WriteLine("\n前序遍历的结点打印序列 = " + string.Join(",", list.ToArray())); + + list.Clear(); + inOrder(root); + Console.WriteLine("\n中序遍历的结点打印序列 = " + string.Join(",", list.ToArray())); + + list.Clear(); + postOrder(root); + Console.WriteLine("\n后序遍历的结点打印序列 = " + string.Join(",", list.ToArray())); + } + } +} diff --git a/codes/csharp/include/PrintUtil.cs b/codes/csharp/include/PrintUtil.cs index 3249c3ea6..06e85a93c 100644 --- a/codes/csharp/include/PrintUtil.cs +++ b/codes/csharp/include/PrintUtil.cs @@ -24,7 +24,7 @@ namespace hello_algo.include * Print a linked list * @param head */ - public static void printLinkedList(ListNode head) + public static void PrintLinkedList(ListNode head) { List list = new(); while (head != null) @@ -41,9 +41,9 @@ namespace hello_algo.include * 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); + PrintTree(root, null, false); } /** @@ -52,7 +52,7 @@ namespace hello_algo.include * @param prev * @param isLeft */ - public static void printTree(TreeNode? root, Trunk? prev, bool isLeft) + public static void PrintTree(TreeNode? root, Trunk? prev, bool isLeft) { if (root == null) { @@ -62,7 +62,7 @@ namespace hello_algo.include String prev_str = " "; Trunk trunk = new Trunk(prev, prev_str); - printTree(root.right, trunk, true); + PrintTree(root.right, trunk, true); if (prev == null) { @@ -80,7 +80,7 @@ namespace hello_algo.include } showTrunks(trunk); - Console.Write(" " + root.val); + Console.WriteLine(" " + root.val); if (prev != null) { @@ -88,7 +88,7 @@ namespace hello_algo.include } trunk.str = " |"; - printTree(root.left, trunk, false); + PrintTree(root.left, trunk, false); } /** diff --git a/codes/csharp/include/TreeNode.cs b/codes/csharp/include/TreeNode.cs index 69dd59b4c..e5cacd59e 100644 --- a/codes/csharp/include/TreeNode.cs +++ b/codes/csharp/include/TreeNode.cs @@ -8,12 +8,12 @@ namespace hello_algo.include { public class TreeNode { - public int? val; // 结点值 + public int val; // 结点值 public int height; // 结点高度 public TreeNode? left; // 左子结点引用 public TreeNode? right; // 右子结点引用 - public TreeNode(int? x) + public TreeNode(int x) { val = x; } @@ -23,12 +23,12 @@ namespace hello_algo.include * @param arr * @return */ - public static TreeNode? arrToTree(int?[] arr) + public static TreeNode? ArrToTree(int?[] arr) { - if (arr.Length == 0) + if (arr.Length == 0 || arr[0] == null) return null; - TreeNode root = new TreeNode(arr[0]); + TreeNode root = new TreeNode((int) arr[0]); Queue queue = new Queue(); queue.Enqueue(root); int i = 1; @@ -37,13 +37,13 @@ namespace hello_algo.include TreeNode node = queue.Dequeue(); if (arr[i] != null) { - node.left = new TreeNode(arr[i]); + node.left = new TreeNode((int) arr[i]); queue.Enqueue(node.left); } i++; if (arr[i] != null) { - node.right = new TreeNode(arr[i]); + node.right = new TreeNode((int) arr[i]); queue.Enqueue(node.right); } i++; @@ -56,7 +56,7 @@ namespace hello_algo.include * @param root * @return */ - public static List treeToList(TreeNode root) + public static List TreeToList(TreeNode root) { List list = new(); if (root == null) return list; @@ -84,14 +84,14 @@ namespace hello_algo.include * @param val * @return */ - public static TreeNode? getTreeNode(TreeNode? root, int val) + public static TreeNode? GetTreeNode(TreeNode? root, int val) { if (root == null) return null; if (root.val == val) return root; - TreeNode? left = getTreeNode(root.left, val); - TreeNode? right = getTreeNode(root.right, val); + TreeNode? left = GetTreeNode(root.left, val); + TreeNode? right = GetTreeNode(root.right, val); return left != null ? left : right; } } diff --git a/docs/chapter_array_and_linkedlist/list.md b/docs/chapter_array_and_linkedlist/list.md index 505265b11..0868b3eee 100644 --- a/docs/chapter_array_and_linkedlist/list.md +++ b/docs/chapter_array_and_linkedlist/list.md @@ -314,7 +314,7 @@ comments: true list.Insert(3, 6); /* 删除元素 */ - list.Remove(3); + list.RemoveAt(3); ``` **遍历列表。** 与数组一样,列表可以使用索引遍历,也可以使用 `for-each` 直接遍历。 @@ -376,9 +376,9 @@ comments: true /* 直接遍历列表元素 */ count = 0 - for range list { - count++ - } + for range list { + count++ + } ``` === "JavaScript" @@ -1148,7 +1148,7 @@ comments: true } /* 访问元素 */ - public int get(int index) + public int Get(int index) { // 索引如果越界则抛出异常,下同 if (index >= size) @@ -1157,7 +1157,7 @@ comments: true } /* 更新元素 */ - public void set(int index, int num) + public void Set(int index, int num) { if (index >= size) throw new IndexOutOfRangeException("索引越界"); @@ -1165,24 +1165,24 @@ comments: true } /* 尾部添加元素 */ - public void add(int num) + public void Add(int num) { // 元素数量超出容量时,触发扩容机制 if (size == Capacity()) - extendCapacity(); + ExtendCapacity(); nums[size] = num; // 更新元素数量 size++; } /* 中间插入元素 */ - public void insert(int index, int num) + public void Insert(int index, int num) { if (index >= size) throw new IndexOutOfRangeException("索引越界"); // 元素数量超出容量时,触发扩容机制 if (size == Capacity()) - extendCapacity(); + ExtendCapacity(); // 将索引 index 以及之后的元素都向后移动一位 for (int j = size - 1; j >= index; j--) { @@ -1194,7 +1194,7 @@ comments: true } /* 删除元素 */ - public int remove(int index) + public int Remove(int index) { if (index >= size) throw new IndexOutOfRangeException("索引越界"); @@ -1211,25 +1211,12 @@ comments: true } /* 列表扩容 */ - public void extendCapacity() + public void ExtendCapacity() { // 新建一个长度为 size 的数组,并将原数组拷贝到新数组 System.Array.Resize(ref nums, Capacity() * extendRatio); // 更新列表容量 capacity = nums.Length; } - - /* 将列表转换为数组 */ - public int[] toArray() - { - int size = Size(); - // 仅转换有效长度范围内的列表元素 - int[] nums = new int[size]; - for (int i = 0; i < size; i++) - { - nums[i] = get(i); - } - return nums; - } } ``` diff --git a/docs/chapter_sorting/bubble_sort.md b/docs/chapter_sorting/bubble_sort.md index fa24232a6..f44b11924 100644 --- a/docs/chapter_sorting/bubble_sort.md +++ b/docs/chapter_sorting/bubble_sort.md @@ -365,7 +365,7 @@ comments: true 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]) diff --git a/docs/chapter_sorting/insertion_sort.md b/docs/chapter_sorting/insertion_sort.md index 3c8b4be7f..1614b5c35 100644 --- a/docs/chapter_sorting/insertion_sort.md +++ b/docs/chapter_sorting/insertion_sort.md @@ -151,7 +151,7 @@ comments: true // 内循环:将 base 插入到左边的正确位置 while (j >= 0 && nums[j] > bas) { - nums[j + 1] = nums[j]; // 1. 将 nums[j] 向右移动一位 + nums[j + 1] = nums[j]; // 1. 将 nums[j] 向右移动一位 j--; } nums[j + 1] = bas; // 2. 将 base 赋值到正确位置 diff --git a/docs/chapter_sorting/merge_sort.md b/docs/chapter_sorting/merge_sort.md index 95eb2e2cd..62ec5e47e 100644 --- a/docs/chapter_sorting/merge_sort.md +++ b/docs/chapter_sorting/merge_sort.md @@ -352,7 +352,7 @@ comments: true void merge(int[] nums, int left, int mid, int right) { // 初始化辅助数组 - int[] tmp = nums[left..(right + 1)];//Array.CopyOfRange(nums, left, right + 1); + int[] tmp = nums[left..(right + 1)]; // 左子数组的起始索引和结束索引 int leftStart = left - left, leftEnd = mid - left; // 右子数组的起始索引和结束索引 diff --git a/docs/chapter_tree/avl_tree.md b/docs/chapter_tree/avl_tree.md index 42131202c..ab3574263 100644 --- a/docs/chapter_tree/avl_tree.md +++ b/docs/chapter_tree/avl_tree.md @@ -660,7 +660,6 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影 // 返回子树的根节点 return node; } - ``` ### 删除结点 @@ -765,7 +764,7 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影 } /* 递归删除结点(辅助函数) */ - private TreeNode? removeHelper(TreeNode? node, int? val) + private TreeNode? removeHelper(TreeNode? node, int val) { if (node == null) return null; /* 1. 查找结点,并删除之 */ @@ -789,8 +788,8 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影 { // 子结点数量 = 2 ,则将中序遍历的下个结点删除,并用该结点替换当前结点 TreeNode? temp = minNode(node.right); - node.right = removeHelper(node.right, temp?.val); - node.val = temp?.val; + node.right = removeHelper(node.right, temp.val); + node.val = temp.val; } } updateHeight(node); // 更新结点高度 diff --git a/docs/chapter_tree/binary_search_tree.md b/docs/chapter_tree/binary_search_tree.md index a01b41807..c2551e749 100644 --- a/docs/chapter_tree/binary_search_tree.md +++ b/docs/chapter_tree/binary_search_tree.md @@ -692,7 +692,7 @@ comments: true ```csharp title="binary_search_tree.cs" /* 删除结点 */ - TreeNode? remove(int? num) + TreeNode? remove(int num) { // 若树为空,直接提前返回 if (root == null) return null; @@ -724,7 +724,6 @@ comments: true { pre.right = child; } - } // 子结点数量 = 2 else @@ -733,7 +732,7 @@ comments: true TreeNode? nex = min(cur.right); if (nex != null) { - int? tmp = nex.val; + int tmp = nex.val; // 递归删除结点 nex remove(nex.val); // 将 nex 的值复制给 cur @@ -742,7 +741,7 @@ comments: true } return cur; } - + /* 获取最小结点 */ TreeNode? min(TreeNode? root) { diff --git a/docs/chapter_tree/binary_tree_traversal.md b/docs/chapter_tree/binary_tree_traversal.md index 2facda257..971d24cc5 100644 --- a/docs/chapter_tree/binary_tree_traversal.md +++ b/docs/chapter_tree/binary_tree_traversal.md @@ -156,11 +156,11 @@ comments: true Queue queue = new(); queue.Enqueue(root); // 初始化一个列表,用于保存遍历序列 - List list = new(); + List list = new(); while (queue.Count != 0) { - TreeNode node = queue.Dequeue(); // 队列出队 - list.Add(node.val); // 保存结点值 + TreeNode node = queue.Dequeue(); // 队列出队 + list.Add(node.val); // 保存结点值 if (node.left != null) queue.Enqueue(node.left); // 左子结点入队 if (node.right != null)