数据结构与算法:完全二叉树和非完全二叉数的各种详细操作以及哈希表的简单应用

1. 二叉树基础概念与节点定义

二叉树图示

text

复制代码
        A
       / \
      B   C
     / \   \
    D   E   F

节点定义代码

c

复制代码
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

// 二叉树节点定义
typedef struct TreeNode {
    int data;                // 节点数据
    struct TreeNode *left;   // 左子树
    struct TreeNode *right;  // 右子树
} TreeNode;

// 队列节点定义(用于层序遍历)
typedef struct QueueNode {
    TreeNode *treeNode;      // 存储的树节点
    struct QueueNode *next;  // 下一个队列节点
} QueueNode;

// 队列定义
typedef struct {
    QueueNode *front;        // 队头
    QueueNode *rear;         // 队尾
} Queue;

// 栈节点定义(用于非递归遍历)
typedef struct StackNode {
    TreeNode *treeNode;      // 存储的树节点
    struct StackNode *next;  // 下一个栈节点
} StackNode;

// 栈定义
typedef struct {
    StackNode *top;          // 栈顶
} Stack;

2. 完全二叉树的链表构建

完全二叉树图示

text

复制代码
        1
       / \
      2   3
     / \ / \
    4  5 6  7

构建方法

完全二叉树可以使用层序构建法,按照从上到下、从左到右的顺序构建节点。

构建代码

c

复制代码
// 创建新节点
TreeNode* createNode(int data) {
    TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode));
    newNode->data = data;
    newNode->left = NULL;
    newNode->right = NULL;
    return newNode;
}

// 队列操作函数
Queue* createQueue() {
    Queue* queue = (Queue*)malloc(sizeof(Queue));
    queue->front = queue->rear = NULL;
    return queue;
}

void enqueue(Queue* queue, TreeNode* treeNode) {
    QueueNode* newNode = (QueueNode*)malloc(sizeof(QueueNode));
    newNode->treeNode = treeNode;
    newNode->next = NULL;
    
    if (queue->rear == NULL) {
        queue->front = queue->rear = newNode;
    } else {
        queue->rear->next = newNode;
        queue->rear = newNode;
    }
}

TreeNode* dequeue(Queue* queue) {
    if (queue->front == NULL) return NULL;
    
    QueueNode* temp = queue->front;
    TreeNode* treeNode = temp->treeNode;
    queue->front = queue->front->next;
    
    if (queue->front == NULL) {
        queue->rear = NULL;
    }
    
    free(temp);
    return treeNode;
}

bool isQueueEmpty(Queue* queue) {
    return queue->front == NULL;
}

// 构建完全二叉树
TreeNode* buildCompleteBinaryTree(int nodes[], int n) {
    if (n == 0) return NULL;
    
    // 创建根节点
    TreeNode* root = createNode(nodes[0]);
    
    // 使用队列辅助构建
    Queue* queue = createQueue();
    enqueue(queue, root);
    
    int i = 1;
    while (i < n) {
        TreeNode* parent = dequeue(queue);
        
        // 创建左孩子
        if (i < n) {
            parent->left = createNode(nodes[i]);
            enqueue(queue, parent->left);
            i++;
        }
        
        // 创建右孩子
        if (i < n) {
            parent->right = createNode(nodes[i]);
            enqueue(queue, parent->right);
            i++;
        }
    }
    
    free(queue);
    return root;
}

// 测试完全二叉树构建
void testCompleteBinaryTree() {
    int nodes[] = {1, 2, 3, 4, 5, 6, 7};
    int n = sizeof(nodes) / sizeof(nodes[0]);
    
    printf("构建完全二叉树,节点序列: ");
    for (int i = 0; i < n; i++) {
        printf("%d ", nodes[i]);
    }
    printf("\n");
    
    TreeNode* root = buildCompleteBinaryTree(nodes, n);
    printf("完全二叉树构建完成!\n");
    
    // 清理内存(实际使用时需要添加释放函数)
    // freeTree(root);
}

3. 二叉树的递归遍历

遍历图示

text

复制代码
        A
       / \
      B   C
     
前序: A B C (根左右)
中序: B A C (左根右)
后序: B C A (左右根)

递归遍历代码

c

复制代码
// 前序遍历(根-左-右)
void preorderTraversal(TreeNode* root) {
    if (root == NULL) return;
    
    printf("%d ", root->data);  // 访问根节点
    preorderTraversal(root->left);  // 遍历左子树
    preorderTraversal(root->right); // 遍历右子树
}

// 中序遍历(左-根-右)
void inorderTraversal(TreeNode* root) {
    if (root == NULL) return;
    
    inorderTraversal(root->left);   // 遍历左子树
    printf("%d ", root->data);      // 访问根节点
    inorderTraversal(root->right);  // 遍历右子树
}

// 后序遍历(左-右-根)
void postorderTraversal(TreeNode* root) {
    if (root == NULL) return;
    
    postorderTraversal(root->left);   // 遍历左子树
    postorderTraversal(root->right);  // 遍历右子树
    printf("%d ", root->data);        // 访问根节点
}

// 测试递归遍历
void testRecursiveTraversal() {
    printf("\n=== 递归遍历测试 ===\n");
    
    // 构建一个简单的二叉树
    TreeNode* root = createNode(1);
    root->left = createNode(2);
    root->right = createNode(3);
    root->left->left = createNode(4);
    root->left->right = createNode(5);
    root->right->left = createNode(6);
    root->right->right = createNode(7);
    
    printf("前序遍历: ");
    preorderTraversal(root);
    printf("\n");
    
    printf("中序遍历: ");
    inorderTraversal(root);
    printf("\n");
    
    printf("后序遍历: ");
    postorderTraversal(root);
    printf("\n");
}

4. 二叉树的层序遍历

层序遍历图示

text

复制代码
        1       ← 第1层
       / \
      2   3     ← 第2层
     / \ / \
    4  5 6  7   ← 第3层
    
层序遍历结果: 1 2 3 4 5 6 7

层序遍历代码

c

复制代码
// 层序遍历(广度优先遍历)
void levelOrderTraversal(TreeNode* root) {
    if (root == NULL) return;
    
    Queue* queue = createQueue();
    enqueue(queue, root);
    
    printf("层序遍历: ");
    while (!isQueueEmpty(queue)) {
        TreeNode* current = dequeue(queue);
        printf("%d ", current->data);
        
        // 将左右孩子入队
        if (current->left != NULL) {
            enqueue(queue, current->left);
        }
        if (current->right != NULL) {
            enqueue(queue, current->right);
        }
    }
    printf("\n");
    
    free(queue);
}

// 测试层序遍历
void testLevelOrderTraversal() {
    printf("\n=== 层序遍历测试 ===\n");
    
    // 构建一个二叉树
    TreeNode* root = createNode(1);
    root->left = createNode(2);
    root->right = createNode(3);
    root->left->left = createNode(4);
    root->left->right = createNode(5);
    root->right->left = createNode(6);
    root->right->right = createNode(7);
    
    levelOrderTraversal(root);
}

5. 二叉树的非递归遍历(顺序栈)

栈操作函数

c

复制代码
// 栈操作函数
Stack* createStack() {
    Stack* stack = (Stack*)malloc(sizeof(Stack));
    stack->top = NULL;
    return stack;
}

void push(Stack* stack, TreeNode* treeNode) {
    StackNode* newNode = (StackNode*)malloc(sizeof(StackNode));
    newNode->treeNode = treeNode;
    newNode->next = stack->top;
    stack->top = newNode;
}

TreeNode* pop(Stack* stack) {
    if (stack->top == NULL) return NULL;
    
    StackNode* temp = stack->top;
    TreeNode* treeNode = temp->treeNode;
    stack->top = stack->top->next;
    free(temp);
    return treeNode;
}

TreeNode* peek(Stack* stack) {
    if (stack->top == NULL) return NULL;
    return stack->top->treeNode;
}

bool isStackEmpty(Stack* stack) {
    return stack->top == NULL;
}

// 非递归前序遍历
void preorderIterative(TreeNode* root) {
    if (root == NULL) return;
    
    Stack* stack = createStack();
    push(stack, root);
    
    printf("非递归前序遍历: ");
    while (!isStackEmpty(stack)) {
        TreeNode* current = pop(stack);
        printf("%d ", current->data);
        
        // 注意:右孩子先入栈,左孩子后入栈
        // 这样左孩子会先出栈,符合根-左-右的顺序
        if (current->right != NULL) {
            push(stack, current->right);
        }
        if (current->left != NULL) {
            push(stack, current->left);
        }
    }
    printf("\n");
    free(stack);
}

// 非递归中序遍历
void inorderIterative(TreeNode* root) {
    if (root == NULL) return;
    
    Stack* stack = createStack();
    TreeNode* current = root;
    
    printf("非递归中序遍历: ");
    while (current != NULL || !isStackEmpty(stack)) {
        // 将左子树所有节点入栈
        while (current != NULL) {
            push(stack, current);
            current = current->left;
        }
        
        // 弹出栈顶节点并访问
        current = pop(stack);
        printf("%d ", current->data);
        
        // 处理右子树
        current = current->right;
    }
    printf("\n");
    free(stack);
}

// 非递归后序遍历(使用两个栈)
void postorderIterative(TreeNode* root) {
    if (root == NULL) return;
    
    Stack* stack1 = createStack();
    Stack* stack2 = createStack();
    push(stack1, root);
    
    printf("非递归后序遍历: ");
    while (!isStackEmpty(stack1)) {
        TreeNode* current = pop(stack1);
        push(stack2, current);
        
        if (current->left != NULL) {
            push(stack1, current->left);
        }
        if (current->right != NULL) {
            push(stack1, current->right);
        }
    }
    
    // stack2中存储的是后序遍历的逆序
    while (!isStackEmpty(stack2)) {
        TreeNode* current = pop(stack2);
        printf("%d ", current->data);
    }
    printf("\n");
    
    free(stack1);
    free(stack2);
}

// 测试非递归遍历
void testIterativeTraversal() {
    printf("\n=== 非递归遍历测试 ===\n");
    
    // 构建一个二叉树
    TreeNode* root = createNode(1);
    root->left = createNode(2);
    root->right = createNode(3);
    root->left->left = createNode(4);
    root->left->right = createNode(5);
    root->right->left = createNode(6);
    root->right->right = createNode(7);
    
    preorderIterative(root);
    inorderIterative(root);
    postorderIterative(root);
}

6. 树的高度/层数统计

高度计算图示

text

复制代码
        A        ← 高度3
       / \
      B   C      ← 高度2
       \   \
        D   E    ← 高度1
       
空树高度为0,只有根节点高度为1

高度统计代码

c

复制代码
// 方法1:递归计算树的高度
int treeHeightRecursive(TreeNode* root) {
    if (root == NULL) return 0;
    
    int leftHeight = treeHeightRecursive(root->left);
    int rightHeight = treeHeightRecursive(root->right);
    
    return (leftHeight > rightHeight ? leftHeight : rightHeight) + 1;
}

// 方法2:层序遍历计算树的高度
int treeHeightLevelOrder(TreeNode* root) {
    if (root == NULL) return 0;
    
    Queue* queue = createQueue();
    enqueue(queue, root);
    int height = 0;
    
    while (!isQueueEmpty(queue)) {
        height++;
        int levelSize = 0;
        
        // 计算当前层的节点数
        QueueNode* temp = queue->front;
        while (temp != NULL) {
            levelSize++;
            temp = temp->next;
        }
        
        // 处理当前层的所有节点
        for (int i = 0; i < levelSize; i++) {
            TreeNode* current = dequeue(queue);
            
            if (current->left != NULL) {
                enqueue(queue, current->left);
            }
            if (current->right != NULL) {
                enqueue(queue, current->right);
            }
        }
    }
    
    free(queue);
    return height;
}

// 统计每层节点数
void countNodesByLevel(TreeNode* root) {
    if (root == NULL) return;
    
    Queue* queue = createQueue();
    enqueue(queue, root);
    int level = 1;
    
    printf("\n=== 每层节点数统计 ===\n");
    while (!isQueueEmpty(queue)) {
        int levelSize = 0;
        
        // 计算当前层的节点数
        QueueNode* temp = queue->front;
        while (temp != NULL) {
            levelSize++;
            temp = temp->next;
        }
        
        printf("第%d层: %d个节点\n", level, levelSize);
        
        // 处理当前层的所有节点
        for (int i = 0; i < levelSize; i++) {
            TreeNode* current = dequeue(queue);
            
            if (current->left != NULL) {
                enqueue(queue, current->left);
            }
            if (current->right != NULL) {
                enqueue(queue, current->right);
            }
        }
        
        level++;
    }
    
    free(queue);
}

// 测试高度统计
void testTreeHeight() {
    printf("\n=== 树高度统计测试 ===\n");
    
    // 构建一个二叉树
    TreeNode* root = createNode(1);
    root->left = createNode(2);
    root->right = createNode(3);
    root->left->left = createNode(4);
    root->left->right = createNode(5);
    root->right->left = createNode(6);
    root->right->right = createNode(7);
    root->left->left->left = createNode(8);  // 添加第4层
    
    printf("递归计算树高度: %d\n", treeHeightRecursive(root));
    printf("层序计算树高度: %d\n", treeHeightLevelOrder(root));
    
    countNodesByLevel(root);
}

7. 非完全二叉树的构建

非完全二叉树图示

text

复制代码
        1
       / \
      2   3
     /   / \
    4   5   6
     \     /
      7   8
      
非完全二叉树:节点不一定连续集中在最左边

非完全二叉树构建代码

c

复制代码
// 交互式构建非完全二叉树
TreeNode* buildNonCompleteBinaryTree() {
    int data;
    char choice;
    
    printf("输入节点数据(-1表示空节点): ");
    scanf("%d", &data);
    
    if (data == -1) {
        return NULL;
    }
    
    TreeNode* newNode = createNode(data);
    
    printf("为节点%d创建左子树吗? (y/n): ", data);
    scanf(" %c", &choice);
    if (choice == 'y' || choice == 'Y') {
        newNode->left = buildNonCompleteBinaryTree();
    }
    
    printf("为节点%d创建右子树吗? (y/n): ", data);
    scanf(" %c", &choice);
    if (choice == 'y' || choice == 'Y') {
        newNode->right = buildNonCompleteBinaryTree();
    }
    
    return newNode;
}

// 根据数组构建非完全二叉树(-1表示空节点)
TreeNode* buildNonCompleteBinaryTreeFromArray(int nodes[], int index, int n) {
    if (index >= n || nodes[index] == -1) {
        return NULL;
    }
    
    TreeNode* root = createNode(nodes[index]);
    root->left = buildNonCompleteBinaryTreeFromArray(nodes, 2*index + 1, n);
    root->right = buildNonCompleteBinaryTreeFromArray(nodes, 2*index + 2, n);
    
    return root;
}

// 测试非完全二叉树构建
void testNonCompleteBinaryTree() {
    printf("\n=== 非完全二叉树测试 ===\n");
    
    // 方法1:交互式构建
    // TreeNode* root = buildNonCompleteBinaryTree();
    
    // 方法2:通过数组构建(-1表示空节点)
    int nodes[] = {1, 2, 3, 4, -1, 5, 6, -1, 7, -1, -1, 8};
    int n = sizeof(nodes) / sizeof(nodes[0]);
    
    printf("构建非完全二叉树,节点序列: ");
    for (int i = 0; i < n; i++) {
        printf("%d ", nodes[i]);
    }
    printf("\n");
    
    TreeNode* root = buildNonCompleteBinaryTreeFromArray(nodes, 0, n);
    
    printf("前序遍历: ");
    preorderTraversal(root);
    printf("\n");
    
    printf("层序遍历: ");
    levelOrderTraversal(root);
    
    printf("树高度: %d\n", treeHeightRecursive(root));
}

8. 哈希表基础概念

哈希表示意图

text

复制代码
哈希表结构:
索引 0: [键1→值1] → [键2→值2] → ...
索引 1: [键3→值3] → ...
...
索引 n-1: [键k→值k] → ...

哈希函数: key → hash(key) → 索引

哈希表定义

c

复制代码
// 哈希表节点定义(链表法解决冲突)
typedef struct HashNode {
    int key;               // 键
    int value;             // 值
    struct HashNode* next; // 下一个节点
} HashNode;

// 哈希表定义
typedef struct {
    int size;              // 哈希表大小
    HashNode** table;      // 哈希表数组
} HashTable;

9. 哈希表应用示例

应用场景:统计100以内随机数出现次数

text

复制代码
输入: [5, 23, 5, 78, 23, 5, 91, 23]
输出:
5出现3次
23出现3次
78出现1次
91出现1次

哈希表实现代码

c

复制代码
// 创建哈希表
HashTable* createHashTable(int size) {
    HashTable* hashTable = (HashTable*)malloc(sizeof(HashTable));
    hashTable->size = size;
    hashTable->table = (HashNode**)malloc(size * sizeof(HashNode*));
    
    // 初始化所有链表为空
    for (int i = 0; i < size; i++) {
        hashTable->table[i] = NULL;
    }
    
    return hashTable;
}

// 简单哈希函数:取余法
int hashFunction(int key, int tableSize) {
    return key % tableSize;
}

// 插入键值对
void insert(HashTable* hashTable, int key, int value) {
    int index = hashFunction(key, hashTable->size);
    
    // 创建新节点
    HashNode* newNode = (HashNode*)malloc(sizeof(HashNode));
    newNode->key = key;
    newNode->value = value;
    newNode->next = NULL;
    
    // 如果该位置为空,直接插入
    if (hashTable->table[index] == NULL) {
        hashTable->table[index] = newNode;
    } else {
        // 否则插入到链表头部
        newNode->next = hashTable->table[index];
        hashTable->table[index] = newNode;
    }
}

// 查找键对应的值
int search(HashTable* hashTable, int key) {
    int index = hashFunction(key, hashTable->size);
    HashNode* current = hashTable->table[index];
    
    while (current != NULL) {
        if (current->key == key) {
            return current->value;
        }
        current = current->next;
    }
    
    return -1; // 未找到
}

// 更新键的值(如果存在则更新,不存在则插入)
void update(HashTable* hashTable, int key, int value) {
    int index = hashFunction(key, hashTable->size);
    HashNode* current = hashTable->table[index];
    
    // 查找是否已存在该键
    while (current != NULL) {
        if (current->key == key) {
            current->value = value;
            return;
        }
        current = current->next;
    }
    
    // 不存在则插入
    insert(hashTable, key, value);
}

// 统计100以内随机数出现次数
void countRandomNumbers() {
    printf("\n=== 哈希表应用:统计100以内随机数 ===\n");
    
    // 创建哈希表,大小为10(用于100以内的数字)
    HashTable* hashTable = createHashTable(10);
    
    // 生成随机数数组
    int randomNumbers[] = {5, 23, 5, 78, 23, 5, 91, 23, 12, 45, 78, 5, 12};
    int count = sizeof(randomNumbers) / sizeof(randomNumbers[0]);
    
    printf("随机数序列: ");
    for (int i = 0; i < count; i++) {
        printf("%d ", randomNumbers[i]);
    }
    printf("\n\n");
    
    // 统计每个数字出现次数
    for (int i = 0; i < count; i++) {
        int key = randomNumbers[i];
        int currentValue = search(hashTable, key);
        
        if (currentValue == -1) {
            // 第一次出现
            insert(hashTable, key, 1);
        } else {
            // 已存在,次数加1
            update(hashTable, key, currentValue + 1);
        }
    }
    
    // 显示统计结果
    printf("统计结果:\n");
    printf("数字\t出现次数\n");
    printf("----\t--------\n");
    
    // 遍历所有可能的键(0-99)
    for (int key = 0; key < 100; key++) {
        int value = search(hashTable, key);
        if (value != -1) {
            printf("%d\t%d次\n", key, value);
        }
    }
    
    // 释放哈希表内存
    for (int i = 0; i < hashTable->size; i++) {
        HashNode* current = hashTable->table[i];
        while (current != NULL) {
            HashNode* temp = current;
            current = current->next;
            free(temp);
        }
    }
    free(hashTable->table);
    free(hashTable);
}

// 测试哈希表
void testHashTable() {
    printf("\n=== 哈希表基本操作测试 ===\n");
    
    HashTable* hashTable = createHashTable(7);
    
    // 插入测试
    insert(hashTable, 10, 100);
    insert(hashTable, 20, 200);
    insert(hashTable, 17, 170);  // 17 % 7 = 3,与10冲突
    
    // 查找测试
    printf("查找键10: %d\n", search(hashTable, 10));
    printf("查找键20: %d\n", search(hashTable, 20));
    printf("查找键17: %d\n", search(hashTable, 17));
    printf("查找键30: %d\n", search(hashTable, 30));  // 应返回-1
    
    // 更新测试
    update(hashTable, 10, 150);
    printf("更新后查找键10: %d\n", search(hashTable, 10));
    
    // 清理内存
    for (int i = 0; i < hashTable->size; i++) {
        HashNode* current = hashTable->table[i];
        while (current != NULL) {
            HashNode* temp = current;
            current = current->next;
            free(temp);
        }
    }
    free(hashTable->table);
    free(hashTable);
}

10. 补充内容

二叉树的其他重要操作

c

复制代码
// 1. 查找节点
TreeNode* findNode(TreeNode* root, int target) {
    if (root == NULL) return NULL;
    if (root->data == target) return root;
    
    TreeNode* leftResult = findNode(root->left, target);
    if (leftResult != NULL) return leftResult;
    
    return findNode(root->right, target);
}

// 2. 计算节点总数
int countNodes(TreeNode* root) {
    if (root == NULL) return 0;
    return 1 + countNodes(root->left) + countNodes(root->right);
}

// 3. 计算叶子节点数
int countLeafNodes(TreeNode* root) {
    if (root == NULL) return 0;
    if (root->left == NULL && root->right == NULL) return 1;
    return countLeafNodes(root->left) + countLeafNodes(root->right);
}

// 4. 释放二叉树内存
void freeTree(TreeNode* root) {
    if (root == NULL) return;
    freeTree(root->left);
    freeTree(root->right);
    free(root);
}

// 5. 判断是否为完全二叉树
bool isCompleteBinaryTree(TreeNode* root) {
    if (root == NULL) return true;
    
    Queue* queue = createQueue();
    enqueue(queue, root);
    bool end = false;  // 标记是否遇到了空节点
    
    while (!isQueueEmpty(queue)) {
        TreeNode* current = dequeue(queue);
        
        if (current == NULL) {
            end = true;
        } else {
            // 如果已经遇到过空节点,又遇到了非空节点,则不是完全二叉树
            if (end) {
                free(queue);
                return false;
            }
            
            // 入队左右孩子(即使是NULL也入队)
            enqueue(queue, current->left);
            enqueue(queue, current->right);
        }
    }
    
    free(queue);
    return true;
}

哈希表的其他重要概念

  1. 哈希冲突解决方法

    • 链地址法(如上例)
  2. 常用哈希函数

    • 除留余数法:h(key) = key % p

    • 直接定址法:h(key) = a * key + b

    • 数字分析法:取关键字的某几位

    • 平方取中法:取关键字平方的中间几位

综合测试函数

c

复制代码
// 综合测试所有功能
void comprehensiveTest() {
    printf("====== 数据结构与算法综合测试 ======\n\n");
    
    // 1. 测试完全二叉树
    testCompleteBinaryTree();
    
    // 2. 测试递归遍历
    testRecursiveTraversal();
    
    // 3. 测试层序遍历
    testLevelOrderTraversal();
    
    // 4. 测试非递归遍历
    testIterativeTraversal();
    
    // 5. 测试树高度统计
    testTreeHeight();
    
    // 6. 测试非完全二叉树
    testNonCompleteBinaryTree();
    
    // 7. 测试哈希表基本操作
    testHashTable();
    
    // 8. 测试哈希表应用
    countRandomNumbers();
    
    printf("\n====== 测试完成 ======\n");
}

// 主函数
int main() {
    comprehensiveTest();
    return 0;
}

总结

今天学习的内容涵盖了二叉树和哈希表两大核心数据结构:

二叉树部分

  1. 构建方法:学会了完全二叉树和非完全二叉树的链表构建

  2. 遍历算法

    • 递归遍历(前序、中序、后序)

    • 非递归遍历(使用栈)

    • 层序遍历(使用队列)

  3. 统计功能:树的高度、每层节点数、节点总数等

哈希表部分

  1. 基本概念:哈希冲突

  2. 实现方法:使用数组+链表解决冲突

  3. 实际应用:统计随机数出现频率

学习建议

  1. 理解递归思想:二叉树很多操作都基于递归,理解递归调用栈很重要

  2. 掌握遍历顺序:三种遍历方式的区别和应用场景

  3. 动手实现:自己实现一遍代码,加深理解

  4. 分析时间复杂度

    • 二叉树遍历:O(n)

    • 哈希表操作:平均O(1),最坏O(n)

相关推荐
季明洵2 小时前
反转字符串、反转字符串II、反转字符串中的单词
java·数据结构·算法·leetcode·字符串
2401_841495642 小时前
【Python高级编程】近似串匹配
python·算法·动态规划·字符串·数组·时间复杂度·空间复杂度
lingggggaaaa2 小时前
安全工具篇&魔改二开&CheckSum8算法&Beacon密钥&Stager流量&生成机制
学习·算法·安全·web安全·网络安全·免杀对抗
Python+JAVA+大数据2 小时前
SQL玩出算法竞赛高度!郑凌云数独算法:递归CTE+位运算DFS回溯全解析
数据库·sql·算法·搜索引擎·深度优先·dfs
Hello World . .2 小时前
数据结构:哈希表(Hash table)
数据结构·vim·哈希算法·散列表
MicroTech20252 小时前
量子主成分分析(QPCA):微算法科技(NASDAQ :MLGO)重构图像降维与特征提取的技术
科技·算法·重构
历程里程碑2 小时前
滑动窗口------滑动窗口最大值
大数据·python·算法·elasticsearch·搜索引擎·flask·tornado
Mr_Xuhhh2 小时前
C语言字符串与内存操作函数模拟实现详解
java·linux·算法
B站_计算机毕业设计之家2 小时前
AI大模型:Deepseek美食推荐系统 机器学习 协同过滤推荐算法+可视化 Django框架 大数据毕业设计(源码)✅
python·算法·机器学习·数据分析·django·推荐算法·美食