mirror of
				https://github.com/krahets/hello-algo.git
				synced 2025-11-04 14:18:20 +08:00 
			
		
		
		
	fine tune
This commit is contained in:
		@ -139,7 +139,7 @@ int main(int argc, char *argv[]) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    count = linear(n);
 | 
					    count = linear(n);
 | 
				
			||||||
    printf("线性阶的操作数量 = %d\n", count);
 | 
					    printf("线性阶的操作数量 = %d\n", count);
 | 
				
			||||||
    // 分配堆区内存(创建一维可变长数组:数组中元素数量为n,元素类型为int)
 | 
					    // 分配堆区内存(创建一维可变长数组:数组中元素数量为 n ,元素类型为 int )
 | 
				
			||||||
    int *nums = (int *)malloc(n * sizeof(int));
 | 
					    int *nums = (int *)malloc(n * sizeof(int));
 | 
				
			||||||
    count = arrayTraversal(nums, n);
 | 
					    count = arrayTraversal(nums, n);
 | 
				
			||||||
    printf("线性阶(遍历数组)的操作数量 = %d\n", count);
 | 
					    printf("线性阶(遍历数组)的操作数量 = %d\n", count);
 | 
				
			||||||
 | 
				
			|||||||
@ -8,7 +8,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* 生成一个数组,元素为 { 1, 2, ..., n },顺序被打乱 */
 | 
					/* 生成一个数组,元素为 { 1, 2, ..., n },顺序被打乱 */
 | 
				
			||||||
int *randomNumbers(int n) {
 | 
					int *randomNumbers(int n) {
 | 
				
			||||||
    // 分配堆区内存(创建一维可变长数组:数组中元素数量为n,元素类型为int)
 | 
					    // 分配堆区内存(创建一维可变长数组:数组中元素数量为 n ,元素类型为 int )
 | 
				
			||||||
    int *nums = (int *)malloc(n * sizeof(int));
 | 
					    int *nums = (int *)malloc(n * sizeof(int));
 | 
				
			||||||
    // 生成数组 nums = { 1, 2, 3, ..., n }
 | 
					    // 生成数组 nums = { 1, 2, 3, ..., n }
 | 
				
			||||||
    for (int i = 0; i < n; i++) {
 | 
					    for (int i = 0; i < n; i++) {
 | 
				
			||||||
 | 
				
			|||||||
@ -150,10 +150,10 @@ int main() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /* 元素出队 */
 | 
					    /* 元素出队 */
 | 
				
			||||||
    int popLastNum = popLast(deque);
 | 
					    int popLastNum = popLast(deque);
 | 
				
			||||||
    printf("队尾出队元素 = %d,队尾出队后 deque= ", popLastNum);
 | 
					    printf("队尾出队元素 = %d ,队尾出队后 deque= ", popLastNum);
 | 
				
			||||||
    printArrayDeque(deque);
 | 
					    printArrayDeque(deque);
 | 
				
			||||||
    int popFirstNum = popFirst(deque);
 | 
					    int popFirstNum = popFirst(deque);
 | 
				
			||||||
    printf("队首出队元素 = %d,队首出队后 deque= ", popFirstNum);
 | 
					    printf("队首出队元素 = %d ,队首出队后 deque= ", popFirstNum);
 | 
				
			||||||
    printArrayDeque(deque);
 | 
					    printArrayDeque(deque);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* 获取队列的长度 */
 | 
					    /* 获取队列的长度 */
 | 
				
			||||||
 | 
				
			|||||||
@ -106,7 +106,7 @@ int main() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /* 元素出队 */
 | 
					    /* 元素出队 */
 | 
				
			||||||
    pop(queue);
 | 
					    pop(queue);
 | 
				
			||||||
    printf("出队元素 pop = %d,出队后 queue = ", peekNum);
 | 
					    printf("出队元素 pop = %d ,出队后 queue = ", peekNum);
 | 
				
			||||||
    printArrayQueue(queue);
 | 
					    printArrayQueue(queue);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* 获取队列的长度 */
 | 
					    /* 获取队列的长度 */
 | 
				
			||||||
 | 
				
			|||||||
@ -85,7 +85,7 @@ int main() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /* 元素出栈 */
 | 
					    /* 元素出栈 */
 | 
				
			||||||
    val = pop(stack);
 | 
					    val = pop(stack);
 | 
				
			||||||
    printf("出栈元素 pop = %d,出栈后 stack = ", val);
 | 
					    printf("出栈元素 pop = %d ,出栈后 stack = ", val);
 | 
				
			||||||
    printArray(stack->data, stack->size);
 | 
					    printArray(stack->data, stack->size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* 获取栈的长度 */
 | 
					    /* 获取栈的长度 */
 | 
				
			||||||
 | 
				
			|||||||
@ -194,10 +194,10 @@ int main() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /* 元素出队 */
 | 
					    /* 元素出队 */
 | 
				
			||||||
    int popLastNum = popLast(deque);
 | 
					    int popLastNum = popLast(deque);
 | 
				
			||||||
    printf("队尾出队元素 popLast = %d,队尾出队后 deque = ", popLastNum);
 | 
					    printf("队尾出队元素 popLast = %d ,队尾出队后 deque = ", popLastNum);
 | 
				
			||||||
    printLinkedListDeque(deque);
 | 
					    printLinkedListDeque(deque);
 | 
				
			||||||
    int popFirstNum = popFirst(deque);
 | 
					    int popFirstNum = popFirst(deque);
 | 
				
			||||||
    printf("队首出队元素 popFirst = %d,队首出队后 deque = ", popFirstNum);
 | 
					    printf("队首出队元素 popFirst = %d ,队首出队后 deque = ", popFirstNum);
 | 
				
			||||||
    printLinkedListDeque(deque);
 | 
					    printLinkedListDeque(deque);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* 获取队列的长度 */
 | 
					    /* 获取队列的长度 */
 | 
				
			||||||
 | 
				
			|||||||
@ -110,7 +110,7 @@ int main() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /* 元素出队 */
 | 
					    /* 元素出队 */
 | 
				
			||||||
    pop(queue);
 | 
					    pop(queue);
 | 
				
			||||||
    printf("出队元素 pop = %d,出队后 queue = ", peekNum);
 | 
					    printf("出队元素 pop = %d ,出队后 queue = ", peekNum);
 | 
				
			||||||
    printLinkedListQueue(queue);
 | 
					    printLinkedListQueue(queue);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* 获取队列的长度 */
 | 
					    /* 获取队列的长度 */
 | 
				
			||||||
 | 
				
			|||||||
@ -134,10 +134,10 @@ int main() {
 | 
				
			|||||||
    // 访问节点
 | 
					    // 访问节点
 | 
				
			||||||
    int i = 1;
 | 
					    int i = 1;
 | 
				
			||||||
    int l = left(i), r = right(i), p = parent(i);
 | 
					    int l = left(i), r = right(i), p = parent(i);
 | 
				
			||||||
    printf("\n当前节点的索引为 %d,值为 %d\n", i, val(abt, i));
 | 
					    printf("\n当前节点的索引为 %d ,值为 %d\n", i, val(abt, i));
 | 
				
			||||||
    printf("其左子节点的索引为 %d,值为 %d\r\n", l, val(abt, l));
 | 
					    printf("其左子节点的索引为 %d ,值为 %d\r\n", l, val(abt, l));
 | 
				
			||||||
    printf("其右子节点的索引为 %d,值为 %d\r\n", r, val(abt, r));
 | 
					    printf("其右子节点的索引为 %d ,值为 %d\r\n", r, val(abt, r));
 | 
				
			||||||
    printf("其父节点的索引为 %d,值为 %d\r\n", p, val(abt, p));
 | 
					    printf("其父节点的索引为 %d ,值为 %d\r\n", p, val(abt, p));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 遍历树
 | 
					    // 遍历树
 | 
				
			||||||
    vector *res = levelOrder(abt);
 | 
					    vector *res = levelOrder(abt);
 | 
				
			||||||
 | 
				
			|||||||
@ -200,7 +200,7 @@ template <typename T> void printDeque(deque<T> deque) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Print a HashMap */
 | 
					/* Print a HashMap */
 | 
				
			||||||
// 定义模板参数 TKey 和 TValue,用于指定键值对的类型
 | 
					// 定义模板参数 TKey 和 TValue ,用于指定键值对的类型
 | 
				
			||||||
template <typename TKey, typename TValue> void printHashMap(unordered_map<TKey, TValue> map) {
 | 
					template <typename TKey, typename TValue> void printHashMap(unordered_map<TKey, TValue> map) {
 | 
				
			||||||
    for (auto kv : map) {
 | 
					    for (auto kv : map) {
 | 
				
			||||||
        cout << kv.first << " -> " << kv.second << '\n';
 | 
					        cout << kv.first << " -> " << kv.second << '\n';
 | 
				
			||||||
 | 
				
			|||||||
@ -132,9 +132,9 @@ void main() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* 元素出队 */
 | 
					  /* 元素出队 */
 | 
				
			||||||
  final int popLast = deque.popLast();
 | 
					  final int popLast = deque.popLast();
 | 
				
			||||||
  print("队尾出队元素 = $popLast,队尾出队后 deque = ${deque.toArray()}");
 | 
					  print("队尾出队元素 = $popLast ,队尾出队后 deque = ${deque.toArray()}");
 | 
				
			||||||
  final int popFirst = deque.popFirst();
 | 
					  final int popFirst = deque.popFirst();
 | 
				
			||||||
  print("队首出队元素 = $popFirst,队首出队后 deque = ${deque.toArray()}");
 | 
					  print("队首出队元素 = $popFirst ,队首出队后 deque = ${deque.toArray()}");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* 获取双向队列的长度 */
 | 
					  /* 获取双向队列的长度 */
 | 
				
			||||||
  final int size = deque.size();
 | 
					  final int size = deque.size();
 | 
				
			||||||
 | 
				
			|||||||
@ -91,7 +91,7 @@ void main() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* 元素出队 */
 | 
					  /* 元素出队 */
 | 
				
			||||||
  final int pop = queue.pop();
 | 
					  final int pop = queue.pop();
 | 
				
			||||||
  print("出队元素 pop = $pop,出队后 queue = ${queue.toArray()}");
 | 
					  print("出队元素 pop = $pop ,出队后 queue = ${queue.toArray()}");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* 获取队列长度 */
 | 
					  /* 获取队列长度 */
 | 
				
			||||||
  final int size = queue.size();
 | 
					  final int size = queue.size();
 | 
				
			||||||
 | 
				
			|||||||
@ -65,7 +65,7 @@ void main() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* 元素出栈 */
 | 
					  /* 元素出栈 */
 | 
				
			||||||
  final int pop = stack.pop();
 | 
					  final int pop = stack.pop();
 | 
				
			||||||
  print("出栈元素 pop = $pop,出栈后 stack = ${stack.toArray()}");
 | 
					  print("出栈元素 pop = $pop ,出栈后 stack = ${stack.toArray()}");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* 获取栈的长度 */
 | 
					  /* 获取栈的长度 */
 | 
				
			||||||
  final int size = stack.size();
 | 
					  final int size = stack.size();
 | 
				
			||||||
 | 
				
			|||||||
@ -28,9 +28,9 @@ void main() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* 元素出队 */
 | 
					  /* 元素出队 */
 | 
				
			||||||
  final int popLast = deque.removeLast();
 | 
					  final int popLast = deque.removeLast();
 | 
				
			||||||
  print("队尾出队元素 = $popLast,队尾出队后 deque = $deque");
 | 
					  print("队尾出队元素 = $popLast ,队尾出队后 deque = $deque");
 | 
				
			||||||
  final int popFirst = deque.removeFirst();
 | 
					  final int popFirst = deque.removeFirst();
 | 
				
			||||||
  print("队首出队元素 = $popFirst,队首出队后 deque = $deque");
 | 
					  print("队首出队元素 = $popFirst ,队首出队后 deque = $deque");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* 获取双向队列的长度 */
 | 
					  /* 获取双向队列的长度 */
 | 
				
			||||||
  final int size = deque.length;
 | 
					  final int size = deque.length;
 | 
				
			||||||
 | 
				
			|||||||
@ -38,7 +38,7 @@ class LinkedListDeque {
 | 
				
			|||||||
  void push(int num, bool isFront) {
 | 
					  void push(int num, bool isFront) {
 | 
				
			||||||
    final ListNode node = ListNode(num);
 | 
					    final ListNode node = ListNode(num);
 | 
				
			||||||
    if (isEmpty()) {
 | 
					    if (isEmpty()) {
 | 
				
			||||||
      // 若链表为空,则令 _front,_rear 都指向 node
 | 
					      // 若链表为空,则令 _front 和 _rear 都指向 node
 | 
				
			||||||
      _front = _rear = node;
 | 
					      _front = _rear = node;
 | 
				
			||||||
    } else if (isFront) {
 | 
					    } else if (isFront) {
 | 
				
			||||||
      // 队首入队操作
 | 
					      // 队首入队操作
 | 
				
			||||||
@ -153,9 +153,9 @@ void main() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* 元素出队 */
 | 
					  /* 元素出队 */
 | 
				
			||||||
  int? popLast = deque.popLast();
 | 
					  int? popLast = deque.popLast();
 | 
				
			||||||
  print("队尾出队元素 = $popLast,队尾出队后 deque = ${deque.toArray()}");
 | 
					  print("队尾出队元素 = $popLast ,队尾出队后 deque = ${deque.toArray()}");
 | 
				
			||||||
  int? popFirst = deque.popFirst();
 | 
					  int? popFirst = deque.popFirst();
 | 
				
			||||||
  print("队首出队元素 = $popFirst,队首出队后 deque = ${deque.toArray()}");
 | 
					  print("队首出队元素 = $popFirst ,队首出队后 deque = ${deque.toArray()}");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* 获取双向队列的长度 */
 | 
					  /* 获取双向队列的长度 */
 | 
				
			||||||
  int size = deque.size();
 | 
					  int size = deque.size();
 | 
				
			||||||
 | 
				
			|||||||
@ -91,7 +91,7 @@ void main() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* 元素出队 */
 | 
					  /* 元素出队 */
 | 
				
			||||||
  final int pop = queue.pop();
 | 
					  final int pop = queue.pop();
 | 
				
			||||||
  print("出队元素 pop = $pop,出队后 queue = ${queue.toArray()}");
 | 
					  print("出队元素 pop = $pop ,出队后 queue = ${queue.toArray()}");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* 获取队列的长度 */
 | 
					  /* 获取队列的长度 */
 | 
				
			||||||
  final int size = queue.size();
 | 
					  final int size = queue.size();
 | 
				
			||||||
 | 
				
			|||||||
@ -81,7 +81,7 @@ void main() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* 元素出栈 */
 | 
					  /* 元素出栈 */
 | 
				
			||||||
  final int pop = stack.pop();
 | 
					  final int pop = stack.pop();
 | 
				
			||||||
  print("出栈元素 pop = $pop,出栈后 stack = ${stack.toList()}");
 | 
					  print("出栈元素 pop = $pop ,出栈后 stack = ${stack.toList()}");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* 获取栈的长度 */
 | 
					  /* 获取栈的长度 */
 | 
				
			||||||
  final int size = stack.size();
 | 
					  final int size = stack.size();
 | 
				
			||||||
 | 
				
			|||||||
@ -25,7 +25,7 @@ void main() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* 元素出队 */
 | 
					  /* 元素出队 */
 | 
				
			||||||
  final int pop = queue.removeFirst();
 | 
					  final int pop = queue.removeFirst();
 | 
				
			||||||
  print("出队元素 pop = $pop,出队后 queue = $queue");
 | 
					  print("出队元素 pop = $pop ,出队后 queue = $queue");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* 获取队列长度 */
 | 
					  /* 获取队列长度 */
 | 
				
			||||||
  final int size = queue.length;
 | 
					  final int size = queue.length;
 | 
				
			||||||
 | 
				
			|||||||
@ -23,7 +23,7 @@ void main() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* 元素出栈 */
 | 
					  /* 元素出栈 */
 | 
				
			||||||
  final int pop = stack.removeLast();
 | 
					  final int pop = stack.removeLast();
 | 
				
			||||||
  print("出栈元素 pop = $pop,出栈后 stack = $stack");
 | 
					  print("出栈元素 pop = $pop ,出栈后 stack = $stack");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* 获取栈的长度 */
 | 
					  /* 获取栈的长度 */
 | 
				
			||||||
  final int size = stack.length;
 | 
					  final int size = stack.length;
 | 
				
			||||||
 | 
				
			|||||||
@ -214,5 +214,5 @@ void main() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* 查询节点 */
 | 
					  /* 查询节点 */
 | 
				
			||||||
  TreeNode? node = avlTree.search(7);
 | 
					  TreeNode? node = avlTree.search(7);
 | 
				
			||||||
  print("\n查找到的节点对象为 $node,节点值 = ${node!.val}");
 | 
					  print("\n查找到的节点对象为 $node ,节点值 = ${node!.val}");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -133,7 +133,7 @@ void main() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* 查找节点 */
 | 
					  /* 查找节点 */
 | 
				
			||||||
  TreeNode? node = bst.search(7);
 | 
					  TreeNode? node = bst.search(7);
 | 
				
			||||||
  print("\n查找到的节点对象为 $node,节点值 = ${node?.val}");
 | 
					  print("\n查找到的节点对象为 $node ,节点值 = ${node?.val}");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* 插入节点 */
 | 
					  /* 插入节点 */
 | 
				
			||||||
  bst.insert(16);
 | 
					  bst.insert(16);
 | 
				
			||||||
 | 
				
			|||||||
@ -8,7 +8,7 @@ const { MaxHeap } = require('./my_heap');
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* 基于堆查找数组中最大的 k 个元素 */
 | 
					/* 基于堆查找数组中最大的 k 个元素 */
 | 
				
			||||||
function topKHeap(nums, k) {
 | 
					function topKHeap(nums, k) {
 | 
				
			||||||
    // 使用大顶堆 MaxHeap,对数组 nums 取相反数
 | 
					    // 使用大顶堆 MaxHeap ,对数组 nums 取相反数
 | 
				
			||||||
    const invertedNums = nums.map((num) => -num);
 | 
					    const invertedNums = nums.map((num) => -num);
 | 
				
			||||||
    // 将数组的前 k 个元素入堆
 | 
					    // 将数组的前 k 个元素入堆
 | 
				
			||||||
    const heap = new MaxHeap(invertedNums.slice(0, k));
 | 
					    const heap = new MaxHeap(invertedNums.slice(0, k));
 | 
				
			||||||
 | 
				
			|||||||
@ -16,7 +16,7 @@ class GraphAdjList:
 | 
				
			|||||||
    def __init__(self, edges: list[list[Vertex]]):
 | 
					    def __init__(self, edges: list[list[Vertex]]):
 | 
				
			||||||
        """构造方法"""
 | 
					        """构造方法"""
 | 
				
			||||||
        # 邻接表,key: 顶点,value:该顶点的所有邻接顶点
 | 
					        # 邻接表,key: 顶点,value:该顶点的所有邻接顶点
 | 
				
			||||||
        self.adj_list = dict[Vertex, Vertex]()
 | 
					        self.adj_list = dict[Vertex, list[Vertex]]()
 | 
				
			||||||
        # 添加所有顶点和边
 | 
					        # 添加所有顶点和边
 | 
				
			||||||
        for edge in edges:
 | 
					        for edge in edges:
 | 
				
			||||||
            self.add_vertex(edge[0])
 | 
					            self.add_vertex(edge[0])
 | 
				
			||||||
 | 
				
			|||||||
@ -92,7 +92,7 @@ class HashMapChaining:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
"""Driver Code"""
 | 
					"""Driver Code"""
 | 
				
			||||||
if __name__ == "__main__":
 | 
					if __name__ == "__main__":
 | 
				
			||||||
    # 测试代码
 | 
					    # 初始化哈希表
 | 
				
			||||||
    hashmap = HashMapChaining()
 | 
					    hashmap = HashMapChaining()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # 添加操作
 | 
					    # 添加操作
 | 
				
			||||||
 | 
				
			|||||||
@ -35,7 +35,7 @@ class TreeNode:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
def list_to_tree_dfs(arr: list[int], i: int) -> TreeNode | None:
 | 
					def list_to_tree_dfs(arr: list[int], i: int) -> TreeNode | None:
 | 
				
			||||||
    """将列表反序列化为二叉树:递归"""
 | 
					    """将列表反序列化为二叉树:递归"""
 | 
				
			||||||
    # 如果索引超出数组长度,或者对应的元素为 None,返回 None
 | 
					    # 如果索引超出数组长度,或者对应的元素为 None ,则返回 None
 | 
				
			||||||
    if i < 0 or i >= len(arr) or arr[i] is None:
 | 
					    if i < 0 or i >= len(arr) or arr[i] is None:
 | 
				
			||||||
        return None
 | 
					        return None
 | 
				
			||||||
    # 构建当前节点
 | 
					    # 构建当前节点
 | 
				
			||||||
 | 
				
			|||||||
@ -41,8 +41,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
### Swift 环境
 | 
					### Swift 环境
 | 
				
			||||||
 | 
					
 | 
				
			||||||
1. 下载并安装 [Swift](https://www.swift.org/download/)。
 | 
					1. 下载并安装 [Swift](https://www.swift.org/download/) 。
 | 
				
			||||||
2. 在 VSCode 的插件市场中搜索 `swift` ,安装 [Swift for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=sswg.swift-lang)。
 | 
					2. 在 VSCode 的插件市场中搜索 `swift` ,安装 [Swift for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=sswg.swift-lang) 。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Dart 环境
 | 
					### Dart 环境
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -51,5 +51,5 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
### Rust 环境
 | 
					### Rust 环境
 | 
				
			||||||
 | 
					
 | 
				
			||||||
1. 下载并安装 [Rust](https://www.rust-lang.org/tools/install)。
 | 
					1. 下载并安装 [Rust](https://www.rust-lang.org/tools/install) 。
 | 
				
			||||||
2. 在 VSCode 的插件市场中搜索 `rust` ,安装 [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer)。
 | 
					2. 在 VSCode 的插件市场中搜索 `rust` ,安装 [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer) 。
 | 
				
			||||||
 | 
				
			|||||||
@ -857,7 +857,7 @@
 | 
				
			|||||||
为了加深对列表工作原理的理解,我们尝试实现一个简易版列表,包括以下三个重点设计。
 | 
					为了加深对列表工作原理的理解,我们尝试实现一个简易版列表,包括以下三个重点设计。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- **初始容量**:选取一个合理的数组初始容量。在本示例中,我们选择 10 作为初始容量。
 | 
					- **初始容量**:选取一个合理的数组初始容量。在本示例中,我们选择 10 作为初始容量。
 | 
				
			||||||
- **数量记录**:声明一个变量 size,用于记录列表当前元素数量,并随着元素插入和删除实时更新。根据此变量,我们可以定位列表尾部,以及判断是否需要扩容。
 | 
					- **数量记录**:声明一个变量 `size` ,用于记录列表当前元素数量,并随着元素插入和删除实时更新。根据此变量,我们可以定位列表尾部,以及判断是否需要扩容。
 | 
				
			||||||
- **扩容机制**:若插入元素时列表容量已满,则需要进行扩容。首先根据扩容倍数创建一个更大的数组,再将当前数组的所有元素依次移动至新数组。在本示例中,我们规定每次将数组扩容至之前的 2 倍。
 | 
					- **扩容机制**:若插入元素时列表容量已满,则需要进行扩容。首先根据扩容倍数创建一个更大的数组,再将当前数组的所有元素依次移动至新数组。在本示例中,我们规定每次将数组扩容至之前的 2 倍。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
=== "Python"
 | 
					=== "Python"
 | 
				
			||||||
 | 
				
			|||||||
@ -148,7 +148,7 @@
 | 
				
			|||||||
除此之外,我们还对代码进行了以下两项优化。
 | 
					除此之外,我们还对代码进行了以下两项优化。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- 在开启搜索前,先将数组 `nums` 排序。在遍历所有选择时,**当子集和超过 `target` 时直接结束循环**,因为后边的元素更大,其子集和都一定会超过 `target` 。
 | 
					- 在开启搜索前,先将数组 `nums` 排序。在遍历所有选择时,**当子集和超过 `target` 时直接结束循环**,因为后边的元素更大,其子集和都一定会超过 `target` 。
 | 
				
			||||||
- 省去元素和变量 `total`,**通过在 `target` 上执行减法来统计元素和**,当 `target` 等于 $0$ 时记录解。
 | 
					- 省去元素和变量 `total` ,**通过在 `target` 上执行减法来统计元素和**,当 `target` 等于 $0$ 时记录解。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
=== "Python"
 | 
					=== "Python"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -3,7 +3,7 @@
 | 
				
			|||||||
运行时间可以直观且准确地反映算法的效率。如果我们想要准确预估一段代码的运行时间,应该如何操作呢?
 | 
					运行时间可以直观且准确地反映算法的效率。如果我们想要准确预估一段代码的运行时间,应该如何操作呢?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
1. **确定运行平台**,包括硬件配置、编程语言、系统环境等,这些因素都会影响代码的运行效率。
 | 
					1. **确定运行平台**,包括硬件配置、编程语言、系统环境等,这些因素都会影响代码的运行效率。
 | 
				
			||||||
2. **评估各种计算操作所需的运行时间**,例如加法操作 `+` 需要 1 ns,乘法操作 `*` 需要 10 ns,打印操作 `print()` 需要 5 ns 等。
 | 
					2. **评估各种计算操作所需的运行时间**,例如加法操作 `+` 需要 1 ns ,乘法操作 `*` 需要 10 ns ,打印操作 `print()` 需要 5 ns 等。
 | 
				
			||||||
3. **统计代码中所有的计算操作**,并将所有操作的执行时间求和,从而得到运行时间。
 | 
					3. **统计代码中所有的计算操作**,并将所有操作的执行时间求和,从而得到运行时间。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
例如在以下代码中,输入数据大小为 $n$ :
 | 
					例如在以下代码中,输入数据大小为 $n$ :
 | 
				
			||||||
 | 
				
			|||||||
@ -88,7 +88,7 @@ $$
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
## 浮点数编码
 | 
					## 浮点数编码
 | 
				
			||||||
 | 
					
 | 
				
			||||||
细心的你可能会发现:`int` 和 `float` 长度相同,都是 4 bytes,但为什么 `float` 的取值范围远大于 `int` ?这非常反直觉,因为按理说 `float` 需要表示小数,取值范围应该变小才对。
 | 
					细心的你可能会发现:`int` 和 `float` 长度相同,都是 4 bytes ,但为什么 `float` 的取值范围远大于 `int` ?这非常反直觉,因为按理说 `float` 需要表示小数,取值范围应该变小才对。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
实际上,**这是因为浮点数 `float` 采用了不同的表示方式**。记一个 32-bit 长度的二进制数为:
 | 
					实际上,**这是因为浮点数 `float` 采用了不同的表示方式**。记一个 32-bit 长度的二进制数为:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -75,7 +75,7 @@ $$
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
**第三步:确定边界条件和状态转移顺序**
 | 
					**第三步:确定边界条件和状态转移顺序**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
在本题中,处在首行的状态只能向右转移,首列状态只能向下转移,因此首行 $i = 0$ 和首列 $j = 0$ 是边界条件。
 | 
					在本题中,首行的状态只能从其左边的状态得来,首列的状态只能从其上边的状态得来,因此首行 $i = 0$ 和首列 $j = 0$ 是边界条件。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
如下图所示,由于每个格子是由其左方格子和上方格子转移而来,因此我们使用采用循环来遍历矩阵,外循环遍历各行、内循环遍历各列。
 | 
					如下图所示,由于每个格子是由其左方格子和上方格子转移而来,因此我们使用采用循环来遍历矩阵,外循环遍历各行、内循环遍历各列。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -35,7 +35,7 @@
 | 
				
			|||||||
- 感谢我在公司的导师李汐博士,在一次畅谈中您鼓励我“快行动起来”,坚定了我写这本书的决心。
 | 
					- 感谢我在公司的导师李汐博士,在一次畅谈中您鼓励我“快行动起来”,坚定了我写这本书的决心。
 | 
				
			||||||
- 感谢我的女朋友泡泡作为本书的首位读者,从算法小白的角度提出许多宝贵建议,使得本书更适合新手阅读。
 | 
					- 感谢我的女朋友泡泡作为本书的首位读者,从算法小白的角度提出许多宝贵建议,使得本书更适合新手阅读。
 | 
				
			||||||
- 感谢腾宝、琦宝、飞宝为本书起了一个富有创意的名字,唤起大家写下第一行代码 "Hello World!" 的美好回忆。
 | 
					- 感谢腾宝、琦宝、飞宝为本书起了一个富有创意的名字,唤起大家写下第一行代码 "Hello World!" 的美好回忆。
 | 
				
			||||||
- 感谢苏潼为本书设计了精美的封面和 LOGO,并在我的强迫症下多次耐心修改。
 | 
					- 感谢苏潼为本书设计了精美的封面和 LOGO ,并在我的强迫症下多次耐心修改。
 | 
				
			||||||
- 感谢 @squidfunk 提供的写作排版建议,以及他开发的开源文档主题 [Material-for-MkDocs](https://github.com/squidfunk/mkdocs-material/tree/master) 。
 | 
					- 感谢 @squidfunk 提供的写作排版建议,以及他开发的开源文档主题 [Material-for-MkDocs](https://github.com/squidfunk/mkdocs-material/tree/master) 。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
在写作过程中,我阅读了许多关于数据结构与算法的教材和文章。这些作品为本书提供了优秀的范本,确保了本书内容的准确性与品质。在此感谢所有老师和前辈们的杰出贡献!
 | 
					在写作过程中,我阅读了许多关于数据结构与算法的教材和文章。这些作品为本书提供了优秀的范本,确保了本书内容的准确性与品质。在此感谢所有老师和前辈们的杰出贡献!
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
# AVL 树 *
 | 
					# AVL 树 *
 | 
				
			||||||
 | 
					
 | 
				
			||||||
在二叉搜索树章节中,我们提到了在多次插入和删除操作后,二叉搜索树可能退化为链表。这种情况下,所有操作的时间复杂度将从 $O(\log n)$ 恶化为 $O(n)$。
 | 
					在二叉搜索树章节中,我们提到了在多次插入和删除操作后,二叉搜索树可能退化为链表。这种情况下,所有操作的时间复杂度将从 $O(\log n)$ 恶化为 $O(n)$ 。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
如下图所示,经过两次删除节点操作,这个二叉搜索树便会退化为链表。
 | 
					如下图所示,经过两次删除节点操作,这个二叉搜索树便会退化为链表。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user