mirror of
https://github.com/krahets/hello-algo.git
synced 2026-04-13 17:29:52 +08:00
build
This commit is contained in:
@@ -12,7 +12,7 @@ comments: true
|
||||
|
||||
## 4.1.1 数组常用操作
|
||||
|
||||
### 初始化数组
|
||||
### 1. 初始化数组
|
||||
|
||||
我们可以根据需求选用数组的两种初始化方式:无初始值、给定初始值。在未指定初始值的情况下,大多数编程语言会将数组元素初始化为 $0$ 。
|
||||
|
||||
@@ -118,7 +118,7 @@ comments: true
|
||||
let nums: Vec<i32> = vec![1, 3, 2, 5, 4];
|
||||
```
|
||||
|
||||
### 访问元素
|
||||
### 2. 访问元素
|
||||
|
||||
数组元素被存储在连续的内存空间中,这意味着计算数组元素的内存地址非常容易。给定数组内存地址(即首元素内存地址)和某个元素的索引,我们可以使用以下公式计算得到该元素的内存地址,从而直接访问此元素。
|
||||
|
||||
@@ -291,7 +291,7 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
|
||||
}
|
||||
```
|
||||
|
||||
### 插入元素
|
||||
### 3. 插入元素
|
||||
|
||||
数组元素在内存中是“紧挨着的”,它们之间没有空间再存放任何数据。这意味着如果想要在数组中间插入一个元素,则需要将该元素之后的所有元素都向后移动一位,之后再把元素赋值给该索引。
|
||||
|
||||
@@ -468,7 +468,7 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
|
||||
}
|
||||
```
|
||||
|
||||
### 删除元素
|
||||
### 4. 删除元素
|
||||
|
||||
同理,如果我们想要删除索引 $i$ 处的元素,则需要把索引 $i$ 之后的元素都向前移动一位。
|
||||
|
||||
@@ -629,7 +629,7 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
|
||||
- **丢失元素**:由于数组的长度不可变,因此在插入元素后,超出数组长度范围的元素会丢失。
|
||||
- **内存浪费**:我们可以初始化一个比较长的数组,只用前面一部分,这样在插入数据时,丢失的末尾元素都是“无意义”的,但这样做也会造成部分内存空间的浪费。
|
||||
|
||||
### 遍历数组
|
||||
### 5. 遍历数组
|
||||
|
||||
在大多数编程语言中,我们既可以通过索引遍历数组,也可以直接遍历获取数组中的每个元素。
|
||||
|
||||
@@ -836,7 +836,7 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
|
||||
}
|
||||
```
|
||||
|
||||
### 查找元素
|
||||
### 6. 查找元素
|
||||
|
||||
在数组中查找指定元素需要遍历数组,每轮判断元素值是否匹配,若匹配则输出对应索引。
|
||||
|
||||
@@ -999,7 +999,7 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
|
||||
}
|
||||
```
|
||||
|
||||
### 扩容数组
|
||||
### 7. 扩容数组
|
||||
|
||||
在复杂的系统环境中,程序难以保证数组之后的内存空间是可用的,从而无法安全地扩展数组容量。因此在大多数编程语言中,**数组的长度是不可变的**。
|
||||
|
||||
|
||||
@@ -190,7 +190,7 @@ comments: true
|
||||
|
||||
## 4.2.1 链表常用操作
|
||||
|
||||
### 初始化链表
|
||||
### 1. 初始化链表
|
||||
|
||||
建立链表分为两步,第一步是初始化各个节点对象,第二步是构建引用指向关系。初始化完成后,我们就可以从链表的头节点出发,通过引用指向 `next` 依次访问所有节点。
|
||||
|
||||
@@ -401,7 +401,7 @@ comments: true
|
||||
|
||||
数组整体是一个变量,比如数组 `nums` 包含元素 `nums[0]` , `nums[1]` 等,而链表是由多个独立的节点对象组成的。**我们通常将头节点当作链表的代称**,比如以上代码中的链表可被记做链表 `n0` 。
|
||||
|
||||
### 插入节点
|
||||
### 2. 插入节点
|
||||
|
||||
**在链表中插入节点非常容易**。假设我们想在相邻的两个节点 `n0` , `n1` 之间插入一个新节点 `P` ,则只需要改变两个节点引用(指针)即可,时间复杂度为 $O(1)$ 。
|
||||
|
||||
@@ -543,7 +543,7 @@ comments: true
|
||||
}
|
||||
```
|
||||
|
||||
### 删除节点
|
||||
### 3. 删除节点
|
||||
|
||||
在链表中删除节点也非常简便,只需改变一个节点的引用(指针)即可。
|
||||
|
||||
@@ -728,7 +728,7 @@ comments: true
|
||||
}
|
||||
```
|
||||
|
||||
### 访问节点
|
||||
### 4. 访问节点
|
||||
|
||||
**在链表访问节点的效率较低**。如上节所述,我们可以在 $O(1)$ 时间下访问数组中的任意元素。链表则不然,程序需要从头节点出发,逐个向后遍历,直至找到目标节点。也就是说,访问链表的第 $i$ 个节点需要循环 $i - 1$ 轮,时间复杂度为 $O(n)$ 。
|
||||
|
||||
@@ -901,7 +901,7 @@ comments: true
|
||||
}
|
||||
```
|
||||
|
||||
### 查找节点
|
||||
### 5. 查找节点
|
||||
|
||||
遍历链表,查找链表内值为 `target` 的节点,输出节点在链表中的索引。此过程也属于「线性查找」。
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ comments: true
|
||||
|
||||
## 4.3.1 列表常用操作
|
||||
|
||||
### 初始化列表
|
||||
### 1. 初始化列表
|
||||
|
||||
我们通常使用“无初始值”和“有初始值”这两种初始化方法。
|
||||
|
||||
@@ -132,7 +132,7 @@ comments: true
|
||||
let list2: Vec<i32> = vec![1, 3, 2, 5, 4];
|
||||
```
|
||||
|
||||
### 访问元素
|
||||
### 2. 访问元素
|
||||
|
||||
列表本质上是数组,因此可以在 $O(1)$ 时间内访问和更新元素,效率很高。
|
||||
|
||||
@@ -251,7 +251,7 @@ comments: true
|
||||
list[1] = 0; // 将索引 1 处的元素更新为 0
|
||||
```
|
||||
|
||||
### 插入与删除元素
|
||||
### 3. 插入与删除元素
|
||||
|
||||
相较于数组,列表可以自由地添加与删除元素。在列表尾部添加元素的时间复杂度为 $O(1)$ ,但插入和删除元素的效率仍与数组相同,时间复杂度为 $O(n)$ 。
|
||||
|
||||
@@ -481,7 +481,7 @@ comments: true
|
||||
list.remove(3); // 删除索引 3 处的元素
|
||||
```
|
||||
|
||||
### 遍历列表
|
||||
### 4. 遍历列表
|
||||
|
||||
与数组一样,列表可以根据索引遍历,也可以直接遍历各元素。
|
||||
|
||||
@@ -666,7 +666,7 @@ comments: true
|
||||
}
|
||||
```
|
||||
|
||||
### 拼接列表
|
||||
### 5. 拼接列表
|
||||
|
||||
给定一个新列表 `list1` ,我们可以将该列表拼接到原列表的尾部。
|
||||
|
||||
@@ -767,7 +767,7 @@ comments: true
|
||||
list.extend(list1);
|
||||
```
|
||||
|
||||
### 排序列表
|
||||
### 6. 排序列表
|
||||
|
||||
完成列表排序后,我们便可以使用在数组类算法题中经常考察的“二分查找”和“双指针”算法。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user