From 922c05024662a84c90efe1b07df5118f491c94ed Mon Sep 17 00:00:00 2001 From: krahets Date: Tue, 28 Feb 2023 00:14:16 +0800 Subject: [PATCH] build --- chapter_array_and_linkedlist/linked_list.md | 12 ++-- .../time_complexity.md | 28 +-------- chapter_graph/graph_operations.md | 40 ++++++------- chapter_graph/graph_traversal.md | 59 ++++++++++++++++++- chapter_tree/binary_tree.md | 2 +- 5 files changed, 86 insertions(+), 55 deletions(-) diff --git a/chapter_array_and_linkedlist/linked_list.md b/chapter_array_and_linkedlist/linked_list.md index c9414c1c4..54edc14d1 100755 --- a/chapter_array_and_linkedlist/linked_list.md +++ b/chapter_array_and_linkedlist/linked_list.md @@ -69,7 +69,7 @@ comments: true === "JavaScript" ```javascript title="" - /* 链表结点结构体 */ + /* 链表结点类 */ class ListNode { val; next; @@ -83,7 +83,7 @@ comments: true === "TypeScript" ```typescript title="" - /* 链表结点结构体 */ + /* 链表结点类 */ class ListNode { val: number; next: ListNode | null; @@ -97,7 +97,11 @@ comments: true === "C" ```c title="" - + /* 链表结点结构体 */ + struct ListNode { + int val; // 结点值 + ListNode *next; // 指向下一结点的指针(引用) + }; ``` === "C#" @@ -896,7 +900,7 @@ comments: true === "C++" ```cpp title="" - /* 链表结点结构体 */ + /* 双向链表结点结构体 */ struct ListNode { int val; // 结点值 ListNode *next; // 指向后继结点的指针(引用) diff --git a/chapter_computational_complexity/time_complexity.md b/chapter_computational_complexity/time_complexity.md index f451a6870..b46813dec 100755 --- a/chapter_computational_complexity/time_complexity.md +++ b/chapter_computational_complexity/time_complexity.md @@ -2597,33 +2597,9 @@ $$ === "C" ```c title="worst_best_time_complexity.c" - /* 生成一个数组,元素为 { 1, 2, ..., n },顺序被打乱 */ - int *randomNumbers(int n) { - // 分配堆区内存(创建一维可变长数组:数组中元素数量为n,元素类型为int) - int *nums = (int *)malloc(n * sizeof(int)); - // 生成数组 nums = { 1, 2, 3, ..., n } - for (int i = 0; i < n; i++) { - nums[i] = i + 1; - } - // 随机打乱数组元素 - for (int i = n - 1; i > 0; i--) { - int j = rand() % (i + 1); - int temp = nums[i]; - nums[i] = nums[j]; - nums[j] = temp; - } - return nums; - } + [class]{}-[func]{randomNumbers} - /* 查找数组 nums 中数字 1 所在索引 */ - int findOne(int *nums, int n) { - for (int i = 0; i < n; i++) { - // 当元素 1 在数组头部时,达到最佳时间复杂度 O(1) - // 当元素 1 在数组尾部时,达到最差时间复杂度 O(n) - if (nums[i] == 1) return i; - } - return -1; - } + [class]{}-[func]{findOne} ``` === "C#" diff --git a/chapter_graph/graph_operations.md b/chapter_graph/graph_operations.md index 2bc06e424..7fe7530f3 100644 --- a/chapter_graph/graph_operations.md +++ b/chapter_graph/graph_operations.md @@ -1023,15 +1023,14 @@ comments: true ```go title="graph_adjacency_list.go" /* 基于邻接表实现的无向图类 */ type graphAdjList struct { - // 邻接表,使用哈希表来代替链表,以提升删除边、删除顶点的效率 - // 请注意,adjList 中的元素是 Vertex 对象 - adjList map[vertex]map[vertex]struct{} + // 邻接表,key: 顶点,value:该顶点的所有邻接顶点 + adjList map[Vertex][]Vertex } /* 构造方法 */ - func newGraphAdjList(edges [][]vertex) *graphAdjList { + func newGraphAdjList(edges [][]Vertex) *graphAdjList { g := &graphAdjList{ - adjList: make(map[vertex]map[vertex]struct{}), + adjList: make(map[Vertex][]Vertex), } // 添加所有顶点和边 for _, edge := range edges { @@ -1048,41 +1047,41 @@ comments: true } /* 添加边 */ - func (g *graphAdjList) addEdge(vet1 vertex, vet2 vertex) { + func (g *graphAdjList) addEdge(vet1 Vertex, vet2 Vertex) { _, ok1 := g.adjList[vet1] _, ok2 := g.adjList[vet2] if !ok1 || !ok2 || vet1 == vet2 { panic("error") } // 添加边 vet1 - vet2, 添加匿名 struct{}, - g.adjList[vet1][vet2] = struct{}{} - g.adjList[vet2][vet1] = struct{}{} + g.adjList[vet1] = append(g.adjList[vet1], vet2) + g.adjList[vet2] = append(g.adjList[vet2], vet1) } /* 删除边 */ - func (g *graphAdjList) removeEdge(vet1 vertex, vet2 vertex) { + func (g *graphAdjList) removeEdge(vet1 Vertex, vet2 Vertex) { _, ok1 := g.adjList[vet1] _, ok2 := g.adjList[vet2] if !ok1 || !ok2 || vet1 == vet2 { panic("error") } - // 删除边 vet1 - vet2, 借助 delete 来删除 map 中的键 - delete(g.adjList[vet1], vet2) - delete(g.adjList[vet2], vet1) + // 删除边 vet1 - vet2 + DeleteSliceElms(g.adjList[vet1], vet2) + DeleteSliceElms(g.adjList[vet2], vet1) } /* 添加顶点 */ - func (g *graphAdjList) addVertex(vet vertex) { + func (g *graphAdjList) addVertex(vet Vertex) { _, ok := g.adjList[vet] if ok { return } // 在邻接表中添加一个新链表 - g.adjList[vet] = make(map[vertex]struct{}) + g.adjList[vet] = make([]Vertex, 0) } /* 删除顶点 */ - func (g *graphAdjList) removeVertex(vet vertex) { + func (g *graphAdjList) removeVertex(vet Vertex) { _, ok := g.adjList[vet] if !ok { panic("error") @@ -1090,9 +1089,8 @@ comments: true // 在邻接表中删除顶点 vet 对应的链表 delete(g.adjList, vet) // 遍历其它顶点的链表,删除所有包含 vet 的边 - for _, set := range g.adjList { - // 操作 - delete(set, vet) + for _, list := range g.adjList { + DeleteSliceElms(list, vet) } } @@ -1101,9 +1099,9 @@ comments: true var builder strings.Builder fmt.Printf("邻接表 = \n") for k, v := range g.adjList { - builder.WriteString("\t\t" + strconv.Itoa(k.val) + ": ") - for vet := range v { - builder.WriteString(strconv.Itoa(vet.val) + " ") + builder.WriteString("\t\t" + strconv.Itoa(k.Val) + ": ") + for _, vet := range v { + builder.WriteString(strconv.Itoa(vet.Val) + " ") } fmt.Println(builder.String()) builder.Reset() diff --git a/chapter_graph/graph_traversal.md b/chapter_graph/graph_traversal.md index 41e0a650e..22f645e85 100644 --- a/chapter_graph/graph_traversal.md +++ b/chapter_graph/graph_traversal.md @@ -94,7 +94,37 @@ BFS 常借助「队列」来实现。队列具有“先入先出”的性质, === "Go" ```go title="graph_bfs.go" - [class]{}-[func]{graphBFS} + /* 广度优先遍历 BFS */ + // 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点 + func graphBFS(g *graphAdjList, startVet Vertex) []Vertex { + // 顶点遍历序列 + res := make([]Vertex, 0) + // 哈希表,用于记录已被访问过的顶点 + visited := make(map[Vertex]struct{}) + visited[startVet] = struct{}{} + // 队列用于实现 BFS, 使用切片模拟队列 + queue := make([]Vertex, 0) + queue = append(queue, startVet) + // 以顶点 vet 为起点,循环直至访问完所有顶点 + for len(queue) > 0 { + // 队首顶点出队 + vet := queue[0] + queue = queue[1:] + // 记录访问顶点 + res = append(res, vet) + // 遍历该顶点的所有邻接顶点 + for _, adjVet := range g.adjList[vet] { + _, isExist := visited[adjVet] + // 只入队未访问的顶点 + if !isExist { + queue = append(queue, adjVet) + visited[adjVet] = struct{}{} + } + } + } + // 返回顶点遍历序列 + return res + } ``` === "JavaScript" @@ -328,9 +358,32 @@ BFS 常借助「队列」来实现。队列具有“先入先出”的性质, === "Go" ```go title="graph_dfs.go" - [class]{}-[func]{dfs} + /* 深度优先遍历 DFS 辅助函数 */ + func dfs(g *graphAdjList, visited map[Vertex]struct{}, res *[]Vertex, vet Vertex) { + // append 操作会返回新的的引用,必须让原引用重新赋值为新slice的引用 + *res = append(*res, vet) + visited[vet] = struct{}{} + // 遍历该顶点的所有邻接顶点 + for _, adjVet := range g.adjList[vet] { + _, isExist := visited[adjVet] + // 递归访问邻接顶点 + if !isExist { + dfs(g, visited, res, adjVet) + } + } + } - [class]{}-[func]{graphDFS} + /* 深度优先遍历 DFS */ + // 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点 + func graphDFS(g *graphAdjList, startVet Vertex) []Vertex { + // 顶点遍历序列 + res := make([]Vertex, 0) + // 哈希表,用于记录已被访问过的顶点 + visited := make(map[Vertex]struct{}) + dfs(g, visited, &res, startVet) + // 返回顶点遍历序列 + return res + } ``` === "JavaScript" diff --git a/chapter_tree/binary_tree.md b/chapter_tree/binary_tree.md index e0c193028..2feba14cd 100644 --- a/chapter_tree/binary_tree.md +++ b/chapter_tree/binary_tree.md @@ -44,7 +44,7 @@ comments: true === "Go" ```go title="" - /* 链表结点类 */ + /* 链表结点结构体 */ type TreeNode struct { Val int Left *TreeNode