mirror of
https://github.com/krahets/hello-algo.git
synced 2024-12-25 08:46:28 +08:00
Update C# code.
This commit is contained in:
parent
4906021ccb
commit
8733557f00
16 changed files with 88 additions and 118 deletions
|
@ -25,7 +25,7 @@ namespace hello_algo.chapter_array_and_linkedlist
|
||||||
Console.WriteLine("访问索引 1 处的元素,得到 num = " + num);
|
Console.WriteLine("访问索引 1 处的元素,得到 num = " + num);
|
||||||
|
|
||||||
/* 更新元素 */
|
/* 更新元素 */
|
||||||
list[1]=0;
|
list[1] = 0;
|
||||||
Console.WriteLine("将索引 1 处的元素更新为 0 ,得到 list = " + string.Join(",", list));
|
Console.WriteLine("将索引 1 处的元素更新为 0 ,得到 list = " + string.Join(",", list));
|
||||||
|
|
||||||
/* 清空列表 */
|
/* 清空列表 */
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace hello_algo.chapter_computational_complexity
|
||||||
{
|
{
|
||||||
int a = 1; // +0(技巧 1)
|
int a = 1; // +0(技巧 1)
|
||||||
a = a + n; // +0(技巧 1)
|
a = a + n; // +0(技巧 1)
|
||||||
// +n(技巧 2)
|
// +n(技巧 2)
|
||||||
for (int i = 0; i < 5 * n + 1; i++)
|
for (int i = 0; i < 5 * n + 1; i++)
|
||||||
{
|
{
|
||||||
Console.WriteLine(0);
|
Console.WriteLine(0);
|
||||||
|
@ -101,7 +101,7 @@ namespace hello_algo.chapter_computational_complexity
|
||||||
static int bubbleSort(int[] nums)
|
static int bubbleSort(int[] nums)
|
||||||
{
|
{
|
||||||
int count = 0; // 计数器
|
int count = 0; // 计数器
|
||||||
// 外循环:待排序元素数量为 n-1, n-2, ..., 1
|
// 外循环:待排序元素数量为 n-1, n-2, ..., 1
|
||||||
for (int i = nums.Length - 1; i > 0; i--)
|
for (int i = nums.Length - 1; i > 0; i--)
|
||||||
{
|
{
|
||||||
// 内循环:冒泡操作
|
// 内循环:冒泡操作
|
||||||
|
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
@ -91,7 +103,7 @@ namespace hello_algo.chapter_stack_and_queue
|
||||||
queue.offer(2);
|
queue.offer(2);
|
||||||
queue.offer(5);
|
queue.offer(5);
|
||||||
queue.offer(4);
|
queue.offer(4);
|
||||||
Console.WriteLine("队列 queue = " + string.Join(",",queue.toArray()));
|
Console.WriteLine("队列 queue = " + string.Join(",", queue.toArray()));
|
||||||
|
|
||||||
/* 访问队首元素 */
|
/* 访问队首元素 */
|
||||||
int peek = queue.peek();
|
int peek = queue.peek();
|
||||||
|
@ -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()));
|
||||||
|
|
|
@ -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);
|
||||||
// 左偏树
|
// 左偏树
|
||||||
|
|
|
@ -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; // 指向后继结点的指针(引用)
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -164,9 +164,9 @@ 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); // 暂存数据(对象)
|
||||||
int c = function(); // 栈帧空间(调用函数)
|
int c = function(); // 栈帧空间(调用函数)
|
||||||
|
@ -606,7 +606,7 @@ $$
|
||||||
nodes = append(nodes, newNode(i))
|
nodes = append(nodes, newNode(i))
|
||||||
}
|
}
|
||||||
// 长度为 n 的哈希表占用 O(n) 空间
|
// 长度为 n 的哈希表占用 O(n) 空间
|
||||||
m := make(map[int]string, n)
|
m := make(map[int]string, n)
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
m[i] = strconv.Itoa(i)
|
m[i] = strconv.Itoa(i)
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,7 @@ $$
|
||||||
int a = 2; // 1 ns
|
int a = 2; // 1 ns
|
||||||
a = a + 1; // 1 ns
|
a = a + 1; // 1 ns
|
||||||
a = a * 2; // 10 ns
|
a = a * 2; // 10 ns
|
||||||
// 循环 n 次
|
// 循环 n 次
|
||||||
for (int i = 0; i < n; i++)
|
for (int i = 0; i < n; i++)
|
||||||
{ // 1 ns ,每轮都要执行 i++
|
{ // 1 ns ,每轮都要执行 i++
|
||||||
Console.WriteLine(0); // 5 ns
|
Console.WriteLine(0); // 5 ns
|
||||||
|
@ -347,7 +347,7 @@ $$
|
||||||
a = a * 2; // +1
|
a = a * 2; // +1
|
||||||
// 循环 n 次
|
// 循环 n 次
|
||||||
for (int i = 0; i < n; i++) { // +1(每轮都执行 i ++)
|
for (int i = 0; i < n; i++) { // +1(每轮都执行 i ++)
|
||||||
Console.WriteLine(0); // +1
|
Console.WriteLine(0); // +1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -500,7 +500,7 @@ $$
|
||||||
{
|
{
|
||||||
int a = 1; // +0(技巧 1)
|
int a = 1; // +0(技巧 1)
|
||||||
a = a + n; // +0(技巧 1)
|
a = a + n; // +0(技巧 1)
|
||||||
// +n(技巧 2)
|
// +n(技巧 2)
|
||||||
for (int i = 0; i < 5 * n + 1; i++)
|
for (int i = 0; i < 5 * n + 1; i++)
|
||||||
{
|
{
|
||||||
Console.WriteLine(0);
|
Console.WriteLine(0);
|
||||||
|
@ -1422,7 +1422,7 @@ $$
|
||||||
=== "C#"
|
=== "C#"
|
||||||
|
|
||||||
```csharp title="time_complexity.cs"
|
```csharp title="time_complexity.cs"
|
||||||
/* 对数阶(递归实现) */
|
/* 对数阶(递归实现) */
|
||||||
int logRecur(float n)
|
int logRecur(float n)
|
||||||
{
|
{
|
||||||
if (n <= 1) return 0;
|
if (n <= 1) return 0;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 哈希冲突
|
## 哈希冲突
|
||||||
|
|
|
@ -419,7 +419,7 @@ $$
|
||||||
=== "C#"
|
=== "C#"
|
||||||
|
|
||||||
```csharp title=""
|
```csharp title=""
|
||||||
// (i + j) 有可能超出 int 的取值范围
|
// (i + j) 有可能超出 int 的取值范围
|
||||||
int m = (i + j) / 2;
|
int m = (i + j) / 2;
|
||||||
// 更换为此写法则不会越界
|
// 更换为此写法则不会越界
|
||||||
int m = i + (j - i) / 2;
|
int m = i + (j - i) / 2;
|
||||||
|
|
|
@ -379,11 +379,11 @@ comments: true
|
||||||
{
|
{
|
||||||
// 终止条件
|
// 终止条件
|
||||||
if (left >= right) return; // 当子数组长度为 1 时终止递归
|
if (left >= right) return; // 当子数组长度为 1 时终止递归
|
||||||
// 划分阶段
|
// 划分阶段
|
||||||
int mid = (left + right) / 2; // 计算中点
|
int mid = (left + right) / 2; // 计算中点
|
||||||
mergeSort(nums, left, mid); // 递归左子数组
|
mergeSort(nums, left, mid); // 递归左子数组
|
||||||
mergeSort(nums, mid + 1, right); // 递归右子数组
|
mergeSort(nums, mid + 1, right); // 递归右子数组
|
||||||
// 合并阶段
|
// 合并阶段
|
||||||
merge(nums, left, mid, right);
|
merge(nums, left, mid, right);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
|
@ -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; // 返回基准数的索引
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
|
@ -80,10 +80,10 @@ G. M. Adelson-Velsky 和 E. M. Landis 在其 1962 年发表的论文 "An algorit
|
||||||
```csharp title="avl_tree.cs"
|
```csharp title="avl_tree.cs"
|
||||||
/* AVL 树结点类 */
|
/* AVL 树结点类 */
|
||||||
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);
|
||||||
// 左偏树
|
// 左偏树
|
||||||
|
|
|
@ -99,9 +99,9 @@ comments: true
|
||||||
```csharp title=""
|
```csharp title=""
|
||||||
/* 链表结点类 */
|
/* 链表结点类 */
|
||||||
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"
|
||||||
|
@ -470,7 +474,7 @@ comments: true
|
||||||
|
|
||||||
```csharp title=""
|
```csharp title=""
|
||||||
/* 二叉树的数组表示 */
|
/* 二叉树的数组表示 */
|
||||||
// 使用 int?可空类型 ,就可以使用 null 来标记空位
|
// 使用 int? 可空类型 ,就可以使用 null 来标记空位
|
||||||
int?[] tree = { 1, 2, 3, 4, null, 6, 7, 8, 9, null, null, 12, null, null, 15 };
|
int?[] tree = { 1, 2, 3, 4, null, 6, 7, 8, 9, null, null, 12, null, null, 15 };
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue