mirror of
https://github.com/krahets/hello-algo.git
synced 2026-04-24 18:43:59 +08:00
Update the book based on the revised second edition (#1014)
* Revised the book * Update the book with the second revised edition * Revise base on the manuscript of the first edition
This commit is contained in:
@@ -85,13 +85,13 @@ class MyList {
|
||||
}
|
||||
// 更新元素数量
|
||||
_size -= 1
|
||||
// 返回被删除元素
|
||||
// 返回被删除的元素
|
||||
return num
|
||||
}
|
||||
|
||||
/* 列表扩容 */
|
||||
func extendCapacity() {
|
||||
// 新建一个长度为原数组 extendRatio 倍的新数组,并将原数组拷贝到新数组
|
||||
// 新建一个长度为原数组 extendRatio 倍的新数组,并将原数组复制到新数组
|
||||
arr = arr + Array(repeating: 0, count: _capacity * (extendRatio - 1))
|
||||
// 更新列表容量
|
||||
_capacity = arr.count
|
||||
|
||||
@@ -13,10 +13,10 @@ func backtrack(row: Int, n: Int, state: inout [[String]], res: inout [[[String]]
|
||||
}
|
||||
// 遍历所有列
|
||||
for col in 0 ..< n {
|
||||
// 计算该格子对应的主对角线和副对角线
|
||||
// 计算该格子对应的主对角线和次对角线
|
||||
let diag1 = row - col + n - 1
|
||||
let diag2 = row + col
|
||||
// 剪枝:不允许该格子所在列、主对角线、副对角线上存在皇后
|
||||
// 剪枝:不允许该格子所在列、主对角线、次对角线上存在皇后
|
||||
if !cols[col] && !diags1[diag1] && !diags2[diag2] {
|
||||
// 尝试:将皇后放置在该格子
|
||||
state[row][col] = "Q"
|
||||
@@ -40,7 +40,7 @@ func nQueens(n: Int) -> [[[String]]] {
|
||||
var state = Array(repeating: Array(repeating: "#", count: n), count: n)
|
||||
var cols = Array(repeating: false, count: n) // 记录列是否有皇后
|
||||
var diags1 = Array(repeating: false, count: 2 * n - 1) // 记录主对角线上是否有皇后
|
||||
var diags2 = Array(repeating: false, count: 2 * n - 1) // 记录副对角线上是否有皇后
|
||||
var diags2 = Array(repeating: false, count: 2 * n - 1) // 记录次对角线上是否有皇后
|
||||
var res: [[[String]]] = []
|
||||
|
||||
backtrack(row: 0, n: n, state: &state, res: &res, cols: &cols, diags1: &diags1, diags2: &diags2)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
import graph_adjacency_list_target
|
||||
import utils
|
||||
|
||||
/* 广度优先遍历 BFS */
|
||||
/* 广度优先遍历 */
|
||||
// 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点
|
||||
func graphBFS(graph: GraphAdjList, startVet: Vertex) -> [Vertex] {
|
||||
// 顶点遍历序列
|
||||
@@ -48,7 +48,7 @@ enum GraphBFS {
|
||||
print("\n初始化后,图为")
|
||||
graph.print()
|
||||
|
||||
/* 广度优先遍历 BFS */
|
||||
/* 广度优先遍历 */
|
||||
let res = graphBFS(graph: graph, startVet: v[0])
|
||||
print("\n广度优先遍历(BFS)顶点序列为")
|
||||
print(Vertex.vetsToVals(vets: res))
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
import graph_adjacency_list_target
|
||||
import utils
|
||||
|
||||
/* 深度优先遍历 DFS 辅助函数 */
|
||||
/* 深度优先遍历辅助函数 */
|
||||
func dfs(graph: GraphAdjList, visited: inout Set<Vertex>, res: inout [Vertex], vet: Vertex) {
|
||||
res.append(vet) // 记录访问顶点
|
||||
visited.insert(vet) // 标记该顶点已被访问
|
||||
@@ -21,7 +21,7 @@ func dfs(graph: GraphAdjList, visited: inout Set<Vertex>, res: inout [Vertex], v
|
||||
}
|
||||
}
|
||||
|
||||
/* 深度优先遍历 DFS */
|
||||
/* 深度优先遍历 */
|
||||
// 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点
|
||||
func graphDFS(graph: GraphAdjList, startVet: Vertex) -> [Vertex] {
|
||||
// 顶点遍历序列
|
||||
@@ -46,7 +46,7 @@ enum GraphDFS {
|
||||
print("\n初始化后,图为")
|
||||
graph.print()
|
||||
|
||||
/* 深度优先遍历 DFS */
|
||||
/* 深度优先遍历 */
|
||||
let res = graphDFS(graph: graph, startVet: v[0])
|
||||
print("\n深度优先遍历(DFS)顶点序列为")
|
||||
print(Vertex.vetsToVals(vets: res))
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
/* 最大容量:贪心 */
|
||||
func maxCapacity(ht: [Int]) -> Int {
|
||||
// 初始化 i, j 分列数组两端
|
||||
// 初始化 i, j,使其分列数组两端
|
||||
var i = 0, j = ht.count - 1
|
||||
// 初始最大容量为 0
|
||||
var res = 0
|
||||
|
||||
@@ -103,7 +103,7 @@ enum _ArrayHashMap {
|
||||
map.print()
|
||||
|
||||
/* 查询操作 */
|
||||
// 向哈希表输入键 key ,得到值 value
|
||||
// 向哈希表中输入键 key ,得到值 value
|
||||
let name = map.get(key: 15937)!
|
||||
print("\n输入学号 15937 ,查询到姓名 \(name)")
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ enum HashMap {
|
||||
PrintUtil.printHashMap(map: map)
|
||||
|
||||
/* 查询操作 */
|
||||
// 向哈希表输入键 key ,得到值 value
|
||||
// 向哈希表中输入键 key ,得到值 value
|
||||
let name = map[15937]!
|
||||
print("\n输入学号 15937 ,查询到姓名 \(name)")
|
||||
|
||||
|
||||
@@ -37,13 +37,13 @@ class HashMapChaining {
|
||||
func get(key: Int) -> String? {
|
||||
let index = hashFunc(key: key)
|
||||
let bucket = buckets[index]
|
||||
// 遍历桶,若找到 key 则返回对应 val
|
||||
// 遍历桶,若找到 key ,则返回对应 val
|
||||
for pair in bucket {
|
||||
if pair.key == key {
|
||||
return pair.val
|
||||
}
|
||||
}
|
||||
// 若未找到 key 则返回 nil
|
||||
// 若未找到 key ,则返回 nil
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ enum _HashMapChaining {
|
||||
map.print()
|
||||
|
||||
/* 查询操作 */
|
||||
// 向哈希表输入键 key ,得到值 value
|
||||
// 向哈希表中输入键 key ,得到值 value
|
||||
let name = map.get(key: 13276)
|
||||
print("\n输入学号 13276 ,查询到姓名 \(name!)")
|
||||
|
||||
|
||||
@@ -41,9 +41,9 @@ class HashMapOpenAddressing {
|
||||
var firstTombstone = -1
|
||||
// 线性探测,当遇到空桶时跳出
|
||||
while buckets[index] != nil {
|
||||
// 若遇到 key ,返回对应桶索引
|
||||
// 若遇到 key ,返回对应的桶索引
|
||||
if buckets[index]!.key == key {
|
||||
// 若之前遇到了删除标记,则将键值对移动至该索引
|
||||
// 若之前遇到了删除标记,则将键值对移动至该索引处
|
||||
if firstTombstone != -1 {
|
||||
buckets[firstTombstone] = buckets[index]
|
||||
buckets[index] = TOMBSTONE
|
||||
@@ -55,7 +55,7 @@ class HashMapOpenAddressing {
|
||||
if firstTombstone == -1 && buckets[index] == TOMBSTONE {
|
||||
firstTombstone = index
|
||||
}
|
||||
// 计算桶索引,越过尾部返回头部
|
||||
// 计算桶索引,越过尾部则返回头部
|
||||
index = (index + 1) % capacity
|
||||
}
|
||||
// 若 key 不存在,则返回添加点的索引
|
||||
@@ -151,7 +151,7 @@ enum _HashMapOpenAddressing {
|
||||
map.print()
|
||||
|
||||
/* 查询操作 */
|
||||
// 向哈希表输入键 key ,得到值 value
|
||||
// 向哈希表中输入键 key ,得到值 value
|
||||
let name = map.get(key: 13276)
|
||||
print("\n输入学号 13276 ,查询到姓名 \(name!)")
|
||||
|
||||
|
||||
@@ -20,17 +20,17 @@ class MaxHeap {
|
||||
}
|
||||
}
|
||||
|
||||
/* 获取左子节点索引 */
|
||||
/* 获取左子节点的索引 */
|
||||
private func left(i: Int) -> Int {
|
||||
2 * i + 1
|
||||
}
|
||||
|
||||
/* 获取右子节点索引 */
|
||||
/* 获取右子节点的索引 */
|
||||
private func right(i: Int) -> Int {
|
||||
2 * i + 2
|
||||
}
|
||||
|
||||
/* 获取父节点索引 */
|
||||
/* 获取父节点的索引 */
|
||||
private func parent(i: Int) -> Int {
|
||||
(i - 1) / 2 // 向下整除
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ func bubbleSortWithFlag(nums: inout [Int]) {
|
||||
flag = true // 记录交换元素
|
||||
}
|
||||
}
|
||||
if !flag { // 此轮冒泡未交换任何元素,直接跳出
|
||||
if !flag { // 此轮“冒泡”未交换任何元素,直接跳出
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
|
||||
/* 合并左子数组和右子数组 */
|
||||
func merge(nums: inout [Int], left: Int, mid: Int, right: Int) {
|
||||
// 左子数组区间 [left, mid], 右子数组区间 [mid+1, right]
|
||||
// 左子数组区间为 [left, mid], 右子数组区间为 [mid+1, right]
|
||||
// 创建一个临时数组 tmp ,用于存放合并后的结果
|
||||
var tmp = Array(repeating: 0, count: right - left + 1)
|
||||
// 初始化左子数组和右子数组的起始索引
|
||||
var i = left, j = mid + 1, k = 0
|
||||
// 当左右子数组都还有元素时,比较并将较小的元素复制到临时数组中
|
||||
// 当左右子数组都还有元素时,进行比较并将较小的元素复制到临时数组中
|
||||
while i <= mid, j <= right {
|
||||
if nums[i] <= nums[j] {
|
||||
tmp[k] = nums[i]
|
||||
|
||||
@@ -45,7 +45,7 @@ func quickSort(nums: inout [Int], left: Int, right: Int) {
|
||||
|
||||
|
||||
/* 快速排序类(中位基准数优化) */
|
||||
/* 选取三个元素的中位数 */
|
||||
/* 选取三个候选元素的中位数 */
|
||||
func medianThree(nums: [Int], left: Int, mid: Int, right: Int) -> Int {
|
||||
if (nums[left] < nums[mid]) != (nums[left] < nums[right]) {
|
||||
return left
|
||||
|
||||
@@ -47,7 +47,7 @@ class ArrayDeque {
|
||||
return
|
||||
}
|
||||
// 队首指针向左移动一位
|
||||
// 通过取余操作,实现 front 越过数组头部后回到尾部
|
||||
// 通过取余操作实现 front 越过数组头部后回到尾部
|
||||
front = index(i: front - 1)
|
||||
// 将 num 添加至队首
|
||||
nums[front] = num
|
||||
@@ -60,7 +60,7 @@ class ArrayDeque {
|
||||
print("双向队列已满")
|
||||
return
|
||||
}
|
||||
// 计算尾指针,指向队尾索引 + 1
|
||||
// 计算队尾指针,指向队尾索引 + 1
|
||||
let rear = index(i: front + size())
|
||||
// 将 num 添加至队尾
|
||||
nums[rear] = num
|
||||
|
||||
@@ -36,8 +36,8 @@ class ArrayQueue {
|
||||
print("队列已满")
|
||||
return
|
||||
}
|
||||
// 计算尾指针,指向队尾索引 + 1
|
||||
// 通过取余操作,实现 rear 越过数组尾部后回到头部
|
||||
// 计算队尾指针,指向队尾索引 + 1
|
||||
// 通过取余操作实现 rear 越过数组尾部后回到头部
|
||||
let rear = (front + queSize) % capacity()
|
||||
// 将 num 添加至队尾
|
||||
nums[rear] = num
|
||||
@@ -48,7 +48,7 @@ class ArrayQueue {
|
||||
@discardableResult
|
||||
func pop() -> Int {
|
||||
let num = peek()
|
||||
// 队首指针向后移动一位,若越过尾部则返回到数组头部
|
||||
// 队首指针向后移动一位,若越过尾部,则返回到数组头部
|
||||
front = (front + 1) % capacity()
|
||||
queSize -= 1
|
||||
return num
|
||||
|
||||
@@ -26,7 +26,7 @@ class LinkedListQueue {
|
||||
|
||||
/* 入队 */
|
||||
func push(num: Int) {
|
||||
// 尾节点后添加 num
|
||||
// 在尾节点后添加 num
|
||||
let node = ListNode(x: num)
|
||||
// 如果队列为空,则令头、尾节点都指向该节点
|
||||
if front == nil {
|
||||
|
||||
@@ -99,7 +99,7 @@ class AVLTree {
|
||||
if node == nil {
|
||||
return TreeNode(x: val)
|
||||
}
|
||||
/* 1. 查找插入位置,并插入节点 */
|
||||
/* 1. 查找插入位置并插入节点 */
|
||||
if val < node!.val {
|
||||
node?.left = insertHelper(node: node?.left, val: val)
|
||||
} else if val > node!.val {
|
||||
@@ -125,7 +125,7 @@ class AVLTree {
|
||||
if node == nil {
|
||||
return nil
|
||||
}
|
||||
/* 1. 查找节点,并删除之 */
|
||||
/* 1. 查找节点并删除 */
|
||||
if val < node!.val {
|
||||
node?.left = removeHelper(node: node?.left, val: val)
|
||||
} else if val > node!.val {
|
||||
|
||||
Reference in New Issue
Block a user