Update C# code.

This commit is contained in:
Yudong Jin 2022-12-24 17:05:58 +08:00
parent 4906021ccb
commit 8733557f00
16 changed files with 88 additions and 118 deletions

View File

@ -10,36 +10,43 @@ namespace hello_algo.chapter_stack_and_queue
{ {
/* 基于环形数组实现的队列 */ /* 基于环形数组实现的队列 */
class ArrayQueue { class ArrayQueue
{
private int[] nums; // 用于存储队列元素的数组 private int[] nums; // 用于存储队列元素的数组
private int front = 0; // 头指针,指向队首 private int front = 0; // 头指针,指向队首
private int rear = 0; // 尾指针,指向队尾 + 1 private int rear = 0; // 尾指针,指向队尾 + 1
public ArrayQueue(int capacity) { public ArrayQueue(int capacity)
{
// 初始化数组 // 初始化数组
nums = new int[capacity]; nums = new int[capacity];
} }
/* 获取队列的容量 */ /* 获取队列的容量 */
public int capacity() { public int capacity()
{
return nums.Length; return nums.Length;
} }
/* 获取队列的长度 */ /* 获取队列的长度 */
public int size() { public int size()
{
int capacity = this.capacity(); int capacity = this.capacity();
// 由于将数组看作为环形,可能 rear < front ,因此需要取余数 // 由于将数组看作为环形,可能 rear < front ,因此需要取余数
return (capacity + rear - front) % capacity; return (capacity + rear - front) % capacity;
} }
/* 判断队列是否为空 */ /* 判断队列是否为空 */
public bool isEmpty() { public bool isEmpty()
{
return rear - front == 0; return rear - front == 0;
} }
/* 入队 */ /* 入队 */
public void offer(int num) { public void offer(int num)
if (size() == capacity()) { {
if (size() == capacity())
{
Console.WriteLine("队列已满"); Console.WriteLine("队列已满");
return; return;
} }
@ -50,7 +57,8 @@ namespace hello_algo.chapter_stack_and_queue
} }
/* 出队 */ /* 出队 */
public int poll() { public int poll()
{
int num = peek(); int num = peek();
// 队头指针向后移动一位,若越过尾部则返回到数组头部 // 队头指针向后移动一位,若越过尾部则返回到数组头部
front = (front + 1) % capacity(); front = (front + 1) % capacity();
@ -58,26 +66,30 @@ namespace hello_algo.chapter_stack_and_queue
} }
/* 访问队首元素 */ /* 访问队首元素 */
public int peek() { public int peek()
{
if (isEmpty()) if (isEmpty())
throw new Exception(); throw new Exception();
return nums[front]; return nums[front];
} }
/* 返回数组 */ /* 返回数组 */
public int[] toArray() { public int[] toArray()
{
int size = this.size(); int size = this.size();
int capacity = this.capacity(); int capacity = this.capacity();
// 仅转换有效长度范围内的列表元素 // 仅转换有效长度范围内的列表元素
int[] res = new int[size]; int[] res = new int[size];
for (int i = 0, j = front; i < size; i++, j++) { for (int i = 0, j = front; i < size; i++, j++)
{
res[i] = nums[j % capacity]; res[i] = nums[j % capacity];
} }
return res; return res;
} }
} }
public class array_queue { public class array_queue
{
[Test] [Test]
public void Test() public void Test()
{ {
@ -110,7 +122,8 @@ namespace hello_algo.chapter_stack_and_queue
Console.WriteLine("队列是否为空 = " + isEmpty); Console.WriteLine("队列是否为空 = " + isEmpty);
/* 测试环形数组 */ /* 测试环形数组 */
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++)
{
queue.offer(i); queue.offer(i);
queue.poll(); queue.poll();
Console.WriteLine("第 " + i + " 轮入队 + 出队后 queue = " + string.Join(",", queue.toArray())); Console.WriteLine("第 " + i + " 轮入队 + 出队后 queue = " + string.Join(",", queue.toArray()));

View File

@ -40,9 +40,6 @@ namespace hello_algo.chapter_tree
/* 右旋操作 */ /* 右旋操作 */
TreeNode? rightRotate(TreeNode? node) TreeNode? rightRotate(TreeNode? node)
{ {
if (node == null)
return null;
TreeNode? child = node.left; TreeNode? child = node.left;
TreeNode? grandChild = child?.right; TreeNode? grandChild = child?.right;
// 以 child 为原点,将 node 向右旋转 // 以 child 为原点,将 node 向右旋转
@ -58,9 +55,6 @@ namespace hello_algo.chapter_tree
/* 左旋操作 */ /* 左旋操作 */
TreeNode? leftRotate(TreeNode? node) TreeNode? leftRotate(TreeNode? node)
{ {
if (node == null)
return null;
TreeNode? child = node.right; TreeNode? child = node.right;
TreeNode? grandChild = child?.left; TreeNode? grandChild = child?.left;
// 以 child 为原点,将 node 向左旋转 // 以 child 为原点,将 node 向左旋转
@ -76,9 +70,6 @@ namespace hello_algo.chapter_tree
/* 执行旋转操作,使该子树重新恢复平衡 */ /* 执行旋转操作,使该子树重新恢复平衡 */
TreeNode? rotate(TreeNode? node) TreeNode? rotate(TreeNode? node)
{ {
if (node == null)
return node;
// 获取结点 node 的平衡因子 // 获取结点 node 的平衡因子
int balanceFactorInt = balanceFactor(node); int balanceFactorInt = balanceFactor(node);
// 左偏树 // 左偏树

View File

@ -91,7 +91,7 @@ comments: true
=== "C#" === "C#"
```csharp title="" ```csharp title=""
// 链表结点类 /* 链表结点类 */
class ListNode class ListNode
{ {
int val; // 结点值 int val; // 结点值
@ -675,7 +675,7 @@ comments: true
=== "C#" === "C#"
```csharp title="" ```csharp title=""
// 双向链表结点类 /* 双向链表结点类 */
class ListNode { class ListNode {
int val; // 结点值 int val; // 结点值
ListNode next; // 指向后继结点的指针(引用) ListNode next; // 指向后继结点的指针(引用)

View File

@ -137,20 +137,20 @@ comments: true
```js title="list.js" ```js title="list.js"
/* 访问元素 */ /* 访问元素 */
const num = list[1]; const num = list[1]; // 访问索引 1 处的元素
/* 更新元素 */ /* 更新元素 */
list[1] = 0; list[1] = 0; // 将索引 1 处的元素更新为 0
``` ```
=== "TypeScript" === "TypeScript"
```typescript title="list.ts" ```typescript title="list.ts"
/* 访问元素 */ /* 访问元素 */
const num: number = list[1]; const num: number = list[1]; // 访问索引 1 处的元素
/* 更新元素 */ /* 更新元素 */
list[1] = 0; list[1] = 0; // 将索引 1 处的元素更新为 0
``` ```
=== "C" === "C"
@ -163,10 +163,10 @@ comments: true
```csharp title="list.cs" ```csharp title="list.cs"
/* 访问元素 */ /* 访问元素 */
int num = list[1]; int num = list[1]; // 访问索引 1 处的元素
/* 更新元素 */ /* 更新元素 */
list[1]=0; list[1] = 0; // 将索引 1 处的元素更新为 0
``` ```
**在列表中添加、插入、删除元素。** 相对于数组,列表可以自由地添加与删除元素。在列表尾部添加元素的时间复杂度为 $O(1)$ ,但是插入与删除元素的效率仍与数组一样低,时间复杂度为 $O(N)$ 。 **在列表中添加、插入、删除元素。** 相对于数组,列表可以自由地添加与删除元素。在列表尾部添加元素的时间复杂度为 $O(1)$ ,但是插入与删除元素的效率仍与数组一样低,时间复杂度为 $O(N)$ 。
@ -477,7 +477,7 @@ comments: true
```js title="list.js" ```js title="list.js"
/* 拼接两个列表 */ /* 拼接两个列表 */
const list1 = [6, 8, 7, 10, 9]; const list1 = [6, 8, 7, 10, 9];
list.push(...list1); list.push(...list1); // 将列表 list1 拼接到 list 之后
``` ```
=== "TypeScript" === "TypeScript"
@ -485,7 +485,7 @@ comments: true
```typescript title="list.ts" ```typescript title="list.ts"
/* 拼接两个列表 */ /* 拼接两个列表 */
const list1: number[] = [6, 8, 7, 10, 9]; const list1: number[] = [6, 8, 7, 10, 9];
list.push(...list1); list.push(...list1); // 将列表 list1 拼接到 list 之后
``` ```
=== "C" === "C"
@ -499,7 +499,7 @@ comments: true
```csharp title="list.cs" ```csharp title="list.cs"
/* 拼接两个列表 */ /* 拼接两个列表 */
List<int> list1 = new() { 6, 8, 7, 10, 9 }; List<int> list1 = new() { 6, 8, 7, 10, 9 };
list.AddRange(list1); list.AddRange(list1); // 将列表 list1 拼接到 list 之后
``` ```
**排序列表。** 排序也是常用的方法之一,完成列表排序后,我们就可以使用在数组类算法题中经常考察的「二分查找」和「双指针」算法了。 **排序列表。** 排序也是常用的方法之一,完成列表排序后,我们就可以使用在数组类算法题中经常考察的「二分查找」和「双指针」算法了。
@ -536,7 +536,7 @@ comments: true
```js title="list.js" ```js title="list.js"
/* 排序列表 */ /* 排序列表 */
list.sort((a, b) => a - b); list.sort((a, b) => a - b); // 排序后,列表元素从小到大排列
``` ```
=== "TypeScript" === "TypeScript"

View File

@ -164,8 +164,8 @@ comments: true
return 0; return 0;
} }
int algorithm(int n) int algorithm(int n) // 输入数据
{ // 输入数据 {
int a = 0; // 暂存数据(常量) int a = 0; // 暂存数据(常量)
int b = 0; // 暂存数据(变量) int b = 0; // 暂存数据(变量)
Node node = new Node(0); // 暂存数据(对象) Node node = new Node(0); // 暂存数据(对象)
@ -883,8 +883,8 @@ $$
if n <= 0 { if n <= 0 {
return 0 return 0
} }
// 数组 nums 长度为 n, n-1, ..., 2, 1
nums := make([]int, n) nums := make([]int, n)
fmt.Printf("递归 n = %d 中的 nums 长度 = %d \n", n, len(nums))
return spaceQuadraticRecur(n - 1) return spaceQuadraticRecur(n - 1)
} }
``` ```
@ -914,8 +914,8 @@ $$
int quadraticRecur(int n) int quadraticRecur(int n)
{ {
if (n <= 0) return 0; if (n <= 0) return 0;
// 数组 nums 长度为 n, n-1, ..., 2, 1
int[] nums = new int[n]; int[] nums = new int[n];
Console.WriteLine("递归 n = " + n + " 中的 nums 长度 = " + nums.Length);
return quadraticRecur(n - 1); return quadraticRecur(n - 1);
} }

View File

@ -543,14 +543,12 @@ $$
bucket.Add(null); bucket.Add(null);
} }
} }
/* 哈希函数 */ /* 哈希函数 */
private int hashFunc(int key) private int hashFunc(int key)
{ {
int index = key % 100; int index = key % 100;
return index; return index;
} }
/* 查询操作 */ /* 查询操作 */
public String? get(int key) public String? get(int key)
{ {
@ -559,7 +557,6 @@ $$
if (pair == null) return null; if (pair == null) return null;
return pair.val; return pair.val;
} }
/* 添加操作 */ /* 添加操作 */
public void put(int key, String val) public void put(int key, String val)
{ {
@ -567,7 +564,6 @@ $$
int index = hashFunc(key); int index = hashFunc(key);
bucket[index]=pair; bucket[index]=pair;
} }
/* 删除操作 */ /* 删除操作 */
public void remove(int key) public void remove(int key)
{ {
@ -576,7 +572,6 @@ $$
bucket[index]=null; bucket[index]=null;
} }
} }
``` ```
## 哈希冲突 ## 哈希冲突

View File

@ -570,17 +570,7 @@ comments: true
// 将中位数交换至数组最左端 // 将中位数交换至数组最左端
swap(nums, left, med); swap(nums, left, med);
// 以 nums[left] 作为基准数 // 以 nums[left] 作为基准数
int i = left, j = right; // 下同省略...
while (i < j)
{
while (i < j && nums[j] >= nums[left])
j--; // 从右向左找首个小于基准数的元素
while (i < j && nums[i] <= nums[left])
i++; // 从左向右找首个大于基准数的元素
swap(nums, i, j); // 交换这两个元素
}
swap(nums, i, left); // 将基准数交换至两子数组的分界线
return i; // 返回基准数的索引
} }
``` ```

View File

@ -557,25 +557,21 @@ comments: true
{ {
private ListNode? front, rear; // 头结点 front ,尾结点 rear private ListNode? front, rear; // 头结点 front ,尾结点 rear
private int queSize = 0; private int queSize = 0;
public LinkedListQueue() public LinkedListQueue()
{ {
front = null; front = null;
rear = null; rear = null;
} }
/* 获取队列的长度 */ /* 获取队列的长度 */
public int size() public int size()
{ {
return queSize; return queSize;
} }
/* 判断队列是否为空 */ /* 判断队列是否为空 */
public bool isEmpty() public bool isEmpty()
{ {
return size() == 0; return size() == 0;
} }
/* 入队 */ /* 入队 */
public void offer(int num) public void offer(int num)
{ {
@ -595,7 +591,6 @@ comments: true
} }
queSize++; queSize++;
} }
/* 出队 */ /* 出队 */
public int poll() public int poll()
{ {
@ -605,7 +600,6 @@ comments: true
queSize--; queSize--;
return num; return num;
} }
/* 访问队首元素 */ /* 访问队首元素 */
public int peek() public int peek()
{ {
@ -962,36 +956,38 @@ comments: true
```csharp title="array_queue.cs" ```csharp title="array_queue.cs"
/* 基于环形数组实现的队列 */ /* 基于环形数组实现的队列 */
class ArrayQueue { class ArrayQueue
{
private int[] nums; // 用于存储队列元素的数组 private int[] nums; // 用于存储队列元素的数组
private int front = 0; // 头指针,指向队首 private int front = 0; // 头指针,指向队首
private int rear = 0; // 尾指针,指向队尾 + 1 private int rear = 0; // 尾指针,指向队尾 + 1
public ArrayQueue(int capacity)
public ArrayQueue(int capacity) { {
// 初始化数组 // 初始化数组
nums = new int[capacity]; nums = new int[capacity];
} }
/* 获取队列的容量 */ /* 获取队列的容量 */
public int capacity() { public int capacity()
{
return nums.Length; return nums.Length;
} }
/* 获取队列的长度 */ /* 获取队列的长度 */
public int size() { public int size()
{
int capacity = this.capacity(); int capacity = this.capacity();
// 由于将数组看作为环形,可能 rear < front 因此需要取余数 // 由于将数组看作为环形,可能 rear < front 因此需要取余数
return (capacity + rear - front) % capacity; return (capacity + rear - front) % capacity;
} }
/* 判断队列是否为空 */ /* 判断队列是否为空 */
public bool isEmpty() { public bool isEmpty()
{
return rear - front == 0; return rear - front == 0;
} }
/* 入队 */ /* 入队 */
public void offer(int num) { public void offer(int num)
if (size() == capacity()) { {
if (size() == capacity())
{
Console.WriteLine("队列已满"); Console.WriteLine("队列已满");
return; return;
} }
@ -1000,17 +996,17 @@ comments: true
// 尾指针向后移动一位,越过尾部后返回到数组头部 // 尾指针向后移动一位,越过尾部后返回到数组头部
rear = (rear + 1) % capacity(); rear = (rear + 1) % capacity();
} }
/* 出队 */ /* 出队 */
public int poll() { public int poll()
{
int num = peek(); int num = peek();
// 队头指针向后移动一位,若越过尾部则返回到数组头部 // 队头指针向后移动一位,若越过尾部则返回到数组头部
front = (front + 1) % capacity(); front = (front + 1) % capacity();
return num; return num;
} }
/* 访问队首元素 */ /* 访问队首元素 */
public int peek() { public int peek()
{
if (isEmpty()) if (isEmpty())
throw new Exception(); throw new Exception();
return nums[front]; return nums[front];

View File

@ -549,19 +549,16 @@ comments: true
{ {
stackPeek = null; stackPeek = null;
} }
/* 获取栈的长度 */ /* 获取栈的长度 */
public int size() public int size()
{ {
return stkSize; return stkSize;
} }
/* 判断栈是否为空 */ /* 判断栈是否为空 */
public bool isEmpty() public bool isEmpty()
{ {
return size() == 0; return size() == 0;
} }
/* 入栈 */ /* 入栈 */
public void push(int num) public void push(int num)
{ {
@ -570,7 +567,6 @@ comments: true
stackPeek = node; stackPeek = node;
stkSize++; stkSize++;
} }
/* 出栈 */ /* 出栈 */
public int pop() public int pop()
{ {
@ -579,7 +575,6 @@ comments: true
stkSize--; stkSize--;
return num; return num;
} }
/* 访问栈顶元素 */ /* 访问栈顶元素 */
public int peek() public int peek()
{ {
@ -836,25 +831,21 @@ comments: true
// 初始化列表(动态数组) // 初始化列表(动态数组)
stack = new(); stack = new();
} }
/* 获取栈的长度 */ /* 获取栈的长度 */
public int size() public int size()
{ {
return stack.Count(); return stack.Count();
} }
/* 判断栈是否为空 */ /* 判断栈是否为空 */
public bool isEmpty() public bool isEmpty()
{ {
return size() == 0; return size() == 0;
} }
/* 入栈 */ /* 入栈 */
public void push(int num) public void push(int num)
{ {
stack.Add(num); stack.Add(num);
} }
/* 出栈 */ /* 出栈 */
public int pop() public int pop()
{ {
@ -864,7 +855,6 @@ comments: true
stack.RemoveAt(size() - 1); stack.RemoveAt(size() - 1);
return val; return val;
} }
/* 访问栈顶元素 */ /* 访问栈顶元素 */
public int peek() public int peek()
{ {

View File

@ -82,8 +82,8 @@ G. M. Adelson-Velsky 和 E. M. Landis 在其 1962 年发表的论文 "An algorit
class TreeNode { class TreeNode {
public int val; // 结点值 public int val; // 结点值
public int height; // 结点高度 public int height; // 结点高度
public TreeNode left; // 左子结点 public TreeNode? left; // 左子结点
public TreeNode right; // 右子结点 public TreeNode? right; // 右子结点
public TreeNode(int x) { val = x; } public TreeNode(int x) { val = x; }
} }
``` ```
@ -314,9 +314,6 @@ AVL 树的独特之处在于「旋转 Rotation」的操作其可 **在不影
/* 右旋操作 */ /* 右旋操作 */
TreeNode? rightRotate(TreeNode? node) TreeNode? rightRotate(TreeNode? node)
{ {
if (node == null)
return null;
TreeNode? child = node.left; TreeNode? child = node.left;
TreeNode? grandChild = child?.right; TreeNode? grandChild = child?.right;
// 以 child 为原点,将 node 向右旋转 // 以 child 为原点,将 node 向右旋转
@ -399,9 +396,6 @@ AVL 树的独特之处在于「旋转 Rotation」的操作其可 **在不影
/* 左旋操作 */ /* 左旋操作 */
TreeNode? leftRotate(TreeNode? node) TreeNode? leftRotate(TreeNode? node)
{ {
if (node == null)
return null;
TreeNode? child = node.right; TreeNode? child = node.right;
TreeNode? grandChild = child?.left; TreeNode? grandChild = child?.left;
// 以 child 为原点,将 node 向左旋转 // 以 child 为原点,将 node 向左旋转
@ -524,9 +518,6 @@ AVL 树的独特之处在于「旋转 Rotation」的操作其可 **在不影
/* 执行旋转操作,使该子树重新恢复平衡 */ /* 执行旋转操作,使该子树重新恢复平衡 */
TreeNode? rotate(TreeNode? node) TreeNode? rotate(TreeNode? node)
{ {
if (node == null)
return node;
// 获取结点 node 的平衡因子 // 获取结点 node 的平衡因子
int balanceFactorInt = balanceFactor(node); int balanceFactorInt = balanceFactor(node);
// 左偏树 // 左偏树

View File

@ -100,8 +100,8 @@ comments: true
/* 链表结点类 */ /* 链表结点类 */
class TreeNode { class TreeNode {
int val; // 结点值 int val; // 结点值
TreeNode left; // 左子结点指针 TreeNode? left; // 左子结点指针
TreeNode right; // 右子结点指针 TreeNode? right; // 右子结点指针
TreeNode(int x) { val = x; } TreeNode(int x) { val = x; }
} }
``` ```
@ -451,13 +451,17 @@ comments: true
=== "JavaScript" === "JavaScript"
```js title="" ```js title=""
/* 二叉树的数组表示 */
// 直接使用 null 来表示空位
let tree = [1, 2, 3, 4, 5, 6, 7, null, null, null, null, null, null, null, null]
``` ```
=== "TypeScript" === "TypeScript"
```typescript title="" ```typescript title=""
/* 二叉树的数组表示 */
// 直接使用 null 来表示空位
let tree = [1, 2, 3, 4, 5, 6, 7, null, null, null, null, null, null, null, null]
``` ```
=== "C" === "C"