【算法】查找与排序

因文章篇幅有限,查找和排序分开写(附代码与详细过程 + 注释详解),这篇文章主讲算法中的数据查找。

查找是数据结构中最基本的操作之一,用于从给定的数据集合中找到特定的目标数据。查找的效率直接影响程序的性能,选择合适的查找方法取决于数据的组织形式和应用场景。

查找的分类

查找操作可以按照数据存储结构和应用场景分为以下几类:

  1. 线性表上的查找
    • 顺序查找(线性查找)
    • 二分查找(折半查找)
    • 索引查找(分块查找)
  2. 树上的查找
    • 二叉搜索树查找
    • 平衡二叉树查找(如 AVL 树、红黑树)
    • B 树和 B+ 树查找
  3. 散列表上的查找
    • 基于哈希表的查找(hash查找)
  4. 图的查找
    • 广度优先搜索(BFS)
    • 深度优先搜索(DFS)
线性表上的查找
1. 顺序查找(线性查找)

逐一扫描线性表中的元素,直到找到目标值或扫描完所有元素。适用于无序集合

时间复杂度

  • 最好情况:O(1)(目标值在第一个位置)。
  • 最坏情况:O(n)(目标值不在表中)。
  • 平均情况:O(n/2) ≈ O(n)
int linearSearch(int arr[], int n, int target) {
    for (int i = 0; i < n; i++) {
        if (arr[i] == target) {
            return i;  // 找到并返回索引
        }
    }
    return -1;  // 未找到
}
// 适用场景
//   数据无序。
//   数据规模小,查找次数少。
2. 二分查找(折半查找)

有序集合中,每次将查找范围缩小一半,直至找到目标值。适用于静态有序集合

时间复杂度

  • 最好情况:O(1)
  • 最坏情况:O(log n)
  • 平均情况:O(log n)
int half_search(int *a,int elem)
{
	int low,high,mid; //设置三个指向标志位
	low=0;     //低位下标
	high=N-1;  //高位下标
	
	while(low<=high)  //当low>high 表中没有对应数据
	{
		mid=(low+high)/2;  //不断进行操作的中间下标
		if(elem>a[mid])  //要查的数据与中间下标指向的值做比较
		{
			low=mid+1;   //大于mid指向值时,低位下标指向位置改变
		}
		if(elem<a[mid]) //小于mid指向值时,高位下标指向位置改变
		{
			high=mid-1;
		}
		if(elem==a[mid]) //等于中间值时
		{
			return mid+1; //返回的是排在数组中第几个
		}
	}
	return -1; // 未找到
}
// 适用场景
//   数据有序。
//   需要频繁查找。

在这里插入图片描述

3. 索引查找(分块查找)

将线性表划分为多个块,块内元素无序,但块间有序。通过索引表定位块,再在块内使用顺序查找。

时间复杂度

  • 查找索引表:O(√n)
  • 块内顺序查找:O(√n)
  • 总复杂度:O(2√n) ≈ O(√n)
int blockSearch(int index[], int blocks[][10], int indexSize, int blockSize, int target) {
    int block = -1;

    // 查找索引表
    for (int i = 0; i < indexSize; i++) {
        if (target <= index[i]) {
            block = i;
            break;
        }
    }
    if (block == -1) return -1;  // 未找到
    // 在对应的块中顺序查找
    for (int j = 0; j < blockSize; j++) {
        if (blocks[block][j] == target) {
            return block * blockSize + j;  // 返回全局索引
        }
    }
    return -1;  // 未找到
}
// 适用场景
//   数据量大,且对查找效率要求较高。
//   索引表占用空间较小。
树上的查找
1. 二叉搜索树查找

在二叉搜索树中,每个节点的左子树节点值小于根节点值,右子树节点值大于根节点值。查找时,根据节点值大小递归向左或右子树查找。

时间复杂度

  • 平衡树:O(log n)
  • 退化为链表时:O(n)
Node* search(Node* root, int key) {
    if (root == NULL || root->data == key) {
        return root;  // 找到目标值或未找到
    }
    if (key < root->data) {
        return search(root->left, key);  // 左子树查找
    }
    return search(root->right, key);    // 右子树查找
}
// 适用场景
//   动态数据集合。
//   数据插入和删除频繁。
2. 平衡二叉树查找

平衡二叉树(如 AVL 树、红黑树)通过平衡旋转维持树的高度在 O(log n)。查找操作与二叉搜索树类似。

时间复杂度

  • O(log n)
#include <stdio.h>
#include <stdlib.h>

// 定义 AVL 树节点
typedef struct Node {
    int data;               // 节点值
    struct Node* left;      // 左子树
    struct Node* right;     // 右子树
    int height;             // 节点高度
} Node;

// 创建新节点
Node* createNode(int data) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->data = data;
    newNode->left = NULL;
    newNode->right = NULL;
    newNode->height = 1;  // 新节点高度为 1
    return newNode;
}

// 适用场景
//   动态数据集合,要求查找性能稳定。
3. B 树和 B+ 树查找

B 树是一种多叉平衡树,适用于外部存储(如磁盘)。B+ 树是 B 树的改进版本,叶子节点通过链表连接,适合范围查找。

时间复杂度

  • O(log n)
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define MAX_KEYS 3  // B 树的阶数为 4(MAX_KEYS + 1)

// B 树的查找过程
// B 树节点定义
typedef struct BTreeNode {
    int keys[MAX_KEYS];               // 节点中的关键字
    struct BTreeNode* children[MAX_KEYS + 1];  // 子节点指针
    int keyCount;                     // 当前节点的关键字数量
    bool isLeaf;                      // 是否是叶子节点
} BTreeNode;

// 创建 B 树节点
BTreeNode* createNode(bool isLeaf) {
    BTreeNode* newNode = (BTreeNode*)malloc(sizeof(BTreeNode));
    newNode->isLeaf = isLeaf;
    newNode->keyCount = 0;

    for (int i = 0; i <= MAX_KEYS; i++) {
        newNode->children[i] = NULL;
    }

    return newNode;
}

// 查找关键字
BTreeNode* search(BTreeNode* root, int key) {
    if (root == NULL) return NULL;

    int i = 0;
    // 在当前节点中查找关键字
    while (i < root->keyCount && key > root->keys[i]) {
        i++;
    }

    // 如果找到关键字,返回当前节点
    if (i < root->keyCount && key == root->keys[i]) {
        return root;
    }

    // 如果是叶子节点,说明找不到
    if (root->isLeaf) {
        return NULL;
    }

    // 否则递归到对应的子节点
    return search(root->children[i], key);
}

// 插入关键字到非满节点
void insertNonFull(BTreeNode* node, int key) {
    int i = node->keyCount - 1;

    // 如果是叶子节点
    if (node->isLeaf) {
        // 插入到合适的位置
        while (i >= 0 && node->keys[i] > key) {
            node->keys[i + 1] = node->keys[i];
            i--;
        }
        node->keys[i + 1] = key;
        node->keyCount++;
    } else {
        // 如果是内部节点
        while (i >= 0 && node->keys[i] > key) {
            i--;
        }
        i++;

        // 如果子节点已满,先分裂
        if (node->children[i]->keyCount == MAX_KEYS) {
            splitChild(node, i);
            if (key > node->keys[i]) {
                i++;
            }
        }

        // 递归插入到子节点
        insertNonFull(node->children[i], key);
    }
}

// 分裂子节点
void splitChild(BTreeNode* parent, int index) {
    BTreeNode* child = parent->children[index];
    BTreeNode* newChild = createNode(child->isLeaf);
    newChild->keyCount = MAX_KEYS / 2;

    // 将后半部分的关键字复制到新节点
    for (int i = 0; i < MAX_KEYS / 2; i++) {
        newChild->keys[i] = child->keys[i + MAX_KEYS / 2 + 1];
    }

    // 如果不是叶子节点,将子节点指针也复制
    if (!child->isLeaf) {
        for (int i = 0; i <= MAX_KEYS / 2; i++) {
            newChild->children[i] = child->children[i + MAX_KEYS / 2 + 1];
        }
    }

    child->keyCount = MAX_KEYS / 2;

    // 将新节点插入到父节点
    for (int i = parent->keyCount; i > index; i--) {
        parent->children[i + 1] = parent->children[i];
        parent->keys[i] = parent->keys[i - 1];
    }
    parent->children[index + 1] = newChild;
    parent->keys[index] = child->keys[MAX_KEYS / 2];
    parent->keyCount++;
}

// 插入关键字到 B 树
BTreeNode* insert(BTreeNode* root, int key) {
    if (root == NULL) {
        root = createNode(true);
        root->keys[0] = key;
        root->keyCount = 1;
        return root;
    }

    // 如果根节点已满
    if (root->keyCount == MAX_KEYS) {
        BTreeNode* newRoot = createNode(false);
        newRoot->children[0] = root;
        splitChild(newRoot, 0);

        int i = 0;
        if (newRoot->keys[0] < key) {
            i++;
        }
        insertNonFull(newRoot->children[i], key);

        return newRoot;
    }

    // 否则直接插入
    insertNonFull(root, key);
    return root;
}

// 中序遍历
void inorderTraversal(BTreeNode* root) {
    if (root != NULL) {
        int i;
        for (i = 0; i < root->keyCount; i++) {
            inorderTraversal(root->children[i]);
            printf("%d ", root->keys[i]);
        }
        inorderTraversal(root->children[i]);
    }
}

int main() {
    BTreeNode* root = NULL;

    // 插入关键字
    root = insert(root, 10);
    root = insert(root, 20);
    root = insert(root, 5);
    root = insert(root, 6);
    root = insert(root, 12);
    root = insert(root, 30);
    root = insert(root, 7);
    root = insert(root, 17);

    printf("Inorder traversal of B-Tree: ");
    inorderTraversal(root);
    printf("\n");

    // 查找关键字
    int key = 6;
    BTreeNode* result = search(root, key);
    if (result != NULL) {
        printf("Key %d found in the B-Tree.\n", key);
    } else {
        printf("Key %d not found in the B-Tree.\n", key);
    }

    return 0;
}
// 使用场景
//   B 树适用于动态插入、删除和查找操作。
//   B+ 树更适合范围查询和顺序访问。
//   B 树和 B+ 树查找时间复杂度均为 O(log n),非常高效,广泛应用于数据库索引和文件系统中。
//   数据量极大,存储在磁盘或其他外部存储介质上。
//   数据库索引结构。

B+ 树是 B 树的改进版本,所有数据存储在叶子节点中,叶子节点通过链表相连,适合范围查询。由于实现较复杂,这里不加以演示。

散列表上的查找
1. 哈希查找(hash查找)

利用哈希函数将关键字直接映射到数组索引,查找时通过计算哈希值快速定位。

时间复杂度

  • 理想情况:O(1)
  • 最坏情况(冲突严重):O(n)
#define SIZE 10

int hash(int key) {
    return key % SIZE;  // 哈希函数
}

void insert(int table[], int key) {
    int index = hash(key);
    while (table[index] != -1) {  // 线性探测解决冲突
        index = (index + 1) % SIZE;
    }
    table[index] = key;
}

int search(int table[], int key) {
    int index = hash(key);
    while (table[index] != -1) {
        if (table[index] == key) return index;  // 找到目标值
        index = (index + 1) % SIZE;
    }
    return -1;  // 未找到
}
// 适用场景
//   高效查找需求,数据量大但内存充足。
//   实现字典、集合等数据结构。

散列

图的查找
1. 广度优先搜索(BFS)
  • BFS 是一种逐层遍历图的算法:
    • 先访问起始节点。
    • 然后访问所有直接相邻的节点(第一层)。
    • 再访问上一层节点的下一层邻居,依此类推。
  • BFS 使用队列作为辅助数据结构,先进先出(FIFO)保证了按层访问节点。

代码描述:
给定一个无向图,求从起点节点 0 到目标节点 4 的最短路径。

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX 100

// BFS 实现最短路径
void bfsShortestPath(int graph[MAX][MAX], int n, int start, int end) {
    int visited[MAX] = {0};  // 记录节点是否被访问
    int distance[MAX] = {0}; // 记录起点到每个节点的距离
    int previous[MAX];       // 记录路径

    for (int i = 0; i < n; i++) previous[i] = -1;

    int queue[MAX];
    int front = 0, rear = 0;

    // 起点入队
    queue[rear++] = start;
    visited[start] = 1;

    while (front < rear) {
        int current = queue[front++];

        // 遍历当前节点的邻居
        for (int i = 0; i < n; i++) {
            if (graph[current][i] == 1 && !visited[i]) {
                queue[rear++] = i; // 将邻居节点入队
                visited[i] = 1;    // 标记为已访问
                distance[i] = distance[current] + 1;
                previous[i] = current; // 记录路径

                // 如果找到目标节点,停止搜索
                if (i == end) {
                    front = rear;
                    break;
                }
            }
        }
    }

    // 输出路径和距离
    if (visited[end]) {
        printf("Shortest distance: %d\n", distance[end]);
        printf("Path: ");
        int path[MAX], pathLength = 0, node = end;
        while (node != -1) {
            path[pathLength++] = node;
            node = previous[node];
        }
        for (int i = pathLength - 1; i >= 0; i--) {
            printf("%d ", path[i]);
        }
        printf("\n");
    } else {
        printf("No path found from %d to %d\n", start, end);
    }
}

int main() {
    // 定义无向图(邻接矩阵)
    int graph[MAX][MAX] = {
        {0, 1, 1, 0, 0},
        {1, 0, 1, 1, 0},
        {1, 1, 0, 0, 1},
        {0, 1, 0, 0, 1},
        {0, 0, 1, 1, 0}
    };

    int n = 5; // 节点数量
    int start = 0, end = 4;

    bfsShortestPath(graph, n, start, end);

    return 0;
}

输出:

Shortest distance: 2
Path: 0 2 4

BFS的应用

  1. 最短路径问题(无权图):
    • BFS 能够找到从起始点到目标点的最短路径(路径长度以边的数量衡量)。
    • 应用场景:
      • 地图导航(如最短路径规划)。
      • 网络传输中的最短跳数计算。
  2. 连通性检查
    • 检查图中是否存在连接的路径,或统计连通分量的数量。
    • 应用场景
      • 网络连通性分析。
      • 图的分区问题。
  3. 层次遍历
    • BFS 可以用于按层次访问节点。
    • 应用场景
      • 社交网络中的层级推荐。
      • 树的层次遍历。
2. 深度优先搜索(DFS)
  • DFS 是一种尽可能沿着一条路径探索下去的图遍历算法:
    • 访问起始节点后,优先访问其第一个未访问的邻居。
    • 如果当前路径走到尽头,则回溯到上一个节点,继续探索其他未访问的邻居。
  • DFS 使用作为辅助数据结构,递归实现中使用函数调用栈。

代码描述:
给定一个有向图,找到从起点节点 0 到目标节点 4 的所有路径。

#include <stdio.h>
#include <stdlib.h>

// 打印路径
void printPath(int path[], int pathLength) {
    for (int i = 0; i < pathLength; i++) {
        printf("%d ", path[i]);
    }
    printf("\n");
}

// DFS 寻找所有路径
void dfsAllPaths(int graph[100][100], int n, int current, int end, int visited[], int path[], int pathLength) {
    visited[current] = 1;             // 标记当前节点为已访问
    path[pathLength++] = current;     // 添加当前节点到路径中

    if (current == end) {
        // 如果到达目标节点,输出路径
        printPath(path, pathLength);
    } else {
        // 遍历当前节点的邻居
        for (int i = 0; i < n; i++) {
            if (graph[current][i] == 1 && !visited[i]) {
                dfsAllPaths(graph, n, i, end, visited, path, pathLength);
            }
        }
    }

    visited[current] = 0;  // 回溯,标记当前节点为未访问
}

int main() {
    // 定义有向图(邻接矩阵)
    int graph[100][100] = {
        {0, 1, 1, 0, 0},
        {0, 0, 1, 1, 0},
        {0, 0, 0, 0, 1},
        {0, 0, 0, 0, 1},
        {0, 0, 0, 0, 0}
    };

    int n = 5; // 节点数量
    int start = 0, end = 4;

    int visited[100] = {0};
    int path[100];
    int pathLength = 0;

    printf("All paths from %d to %d:\n", start, end);
    dfsAllPaths(graph, n, start, end, visited, path, pathLength);

    return 0;
}

输出:

All paths from 0 to 4:
0 1 3 4
0 1 2 4
0 2 4

DFS的应用

  1. 路径搜索问题
    • 找到从起点到目标点的所有路径。
    • 应用场景
      • 迷宫求解。
      • 寻找所有可能的方案。
  2. 拓扑排序
    • 对有向无环图(DAG)进行排序,以确定任务的依赖顺序。
    • 应用场景
      • 编译器中的任务调度。
      • 项目任务规划。
  3. 连通性检查
    • 统计图的连通分量,判断两个节点是否连通。
    • 应用场景
      • 网络故障分析。
      • 图的分区问题。
  4. 图的循环检测
    • 检测图中是否存在环。
    • 应用场景
      • 死锁检测。
      • 图依赖的验证。

BFS 与 DFS 的对比:

算法特点适用场景
广度优先搜索(BFS)逐层遍历,找到目标节点时路径一定是最短的(适用于无权图)。最短路径、层次遍历、连通性检查。
深度优先搜索(DFS)沿着路径搜索到底再回溯,适合搜寻所有路径或解决需要回溯的问题。所有路径、拓扑排序、循环检测。
选择使用 BFS 或 DFS:如果关心路径最短,使用 BFS。如果关心所有可能的路径或需要深入探索,使用 DFS。

选择合适的查找方法取决于数据的组织形式、应用场景和性能需求。例如,小规模无序数据:使用顺序查找更为简单易用;有序数据:使用二分查找快速高效;动态数据集合:使用二叉搜索树或平衡树;大规模数据:哈希查找或 B+ 树适合外部存储。

综上。希望该内容能对你有帮助。

以上。仅供学习与分享交流,请勿用于商业用途!转载需提前说明。

我是一个十分热爱技术的程序员,希望这篇文章能够对您有帮助,也希望认识更多热爱程序开发的小伙伴。
感谢!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/951488.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux环境中对Postgrel数据库的安装与配置

一、环境准备 linux操作系统的环境是centos7; Postgrel数据库的版本是12.0&#xff0c;不同版本的下载渠道如下&#xff08;PostgreSQL: File Browser&#xff09;&#xff1a; 可以看到压缩包是比较小的&#xff1b;下载之后&#xff0c;上传到你的linux环境中即可。 二、安…

基于vue的商城小程序的毕业设计与实现(源码及报告)

环境搭建 ☞☞☞ ​​​Vue入手篇(一)&#xff0c;防踩雷(全网最详细教程)_vue force-CSDN博客 目录 一、功能介绍 二、登录注册功能 三、首页 四、项目截图 五、源码获取 一、功能介绍 用户信息展示&#xff1a;页面顶部设有用户头像和昵称展示区&#xff0c;方便用户识别…

单元测试概述入门

引入 什么是测试&#xff1f;测试的阶段划分&#xff1f; 测试方法有哪些&#xff1f; 1.什么是单元测试&#xff1f; 单元测试&#xff1a;就是针对最小的功能单元&#xff08;方法&#xff09;&#xff0c;编写测试代码对其正确性进行测试。 2.为什么要引入单元测试&#x…

Springboot3巧妙运用拦截器阻断xss攻击

Springboot3巧妙运用拦截器阻断xss攻击 什么是xss跨站脚本攻击类型简单示例解决方法拦截器代码使用demo 什么是xss 人们经常将跨站脚本攻击&#xff08;Cross Site Scripting&#xff09;缩写为CSS&#xff0c;但这会与层叠样式表&#xff08;Cascading Style Sheets&#xff…

DAY39|动态规划Part07|LeetCode:198.打家劫舍、213.打家劫舍II、337.打家劫舍III

目录 LeetCode:198.打家劫舍 基本思路 C代码 LeetCode:213.打家劫舍II 基本思路 C代码 LeetCode:337.打家劫舍III 基本思路 C代码 LeetCode:198.打家劫舍 力扣题目链接 文字讲解&#xff1a;LeetCode:198.打家劫舍 视频讲解&#xff1a;动态规划&#xff0c;偷不偷这个…

数据结构——栈的实现

今天&#xff0c;我们来写一下关于栈的博文。 1.首先我们先了解一下什么是栈&#xff1f; 一&#xff1a;概念&#xff1a; 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。 进行数据插入和删除操作的一端称为栈顶&#xff0c;另…

uniapp 的uni.getRecorderManager() 录音功能小记

官网上明确说的是全局唯一并且只是获取对象&#xff0c;所以会导致一个问题就是&#xff0c;当你多个页面要用到这个对象的时候&#xff0c;会发现 onStop 方法会被覆盖&#xff0c;导致调用结果不是自己想要的 解决办法也简单粗暴&#xff0c;在需要用到的界面重新覆盖onStop…

Unity:删除注册表内的项目记录

然后WinR按键输入regedit 打开注册表 在注册表 HKEY CURRENT USER—>SOFTWARE—>Unity—>UnityEditor—>DefaultCompany —>language_Test 中&#xff0c;删除我们的之前存储的语言环境数据。在 “ 三、文本调用和替换 ” 测试时已经将语言环境存储到注册表中了…

标准应用 | 2025年网络安全服务成本度量实施参考

01 网络安全服务成本度量依据相关新变化 为了解决我国网络安全服务产业发展中面临的服务供需两方对于服务成本组成认知偏差较大、网络安全服务成本度量缺乏依据的问题&#xff0c;中国网络安全产业联盟&#xff08;CCIA&#xff09;组织北京赛西科技发展有限责任公司、北京安…

微信小程序map组件所有markers展示在视野范围内

注意&#xff1a;使用include-points属性不生效&#xff0c;要通过createMapContext实现 <template><view class"map-box"><map id"map" class"map" :markers"markers" :enable-traffic"true" :enable-poi&…

PLC实现HTTP协议JSON格式数据上报对接的参数配置说明

IGT-SER系列PLC通讯智能网关支持HTTP协议GET和POST、PUT请求模式。支持JSON格式的文件&#xff0c;也可以实现WebService的调用。 通常智能网关是HTTP协议的客户端&#xff0c;也可以同时作为HTTP的服务端。相关案例 作为客户端时支持触发、周期、混合等多种工…

微信小程序——创建滑动颜色条

在微信小程序中&#xff0c;你可以使用 slider 组件来创建一个颜色滑动条。以下是一个简单的示例&#xff0c;展示了如何实现一个颜色滑动条&#xff0c;该滑动条会根据滑动位置改变背景颜色。 步骤一&#xff1a;创建小程序项目 首先&#xff0c;使用微信开发者工具创建一个新…

Improving Language Understanding by Generative Pre-Training GPT-1详细讲解

Improving Language Understanding by Generative Pre-Training 2018.06 GPT-1 0.有监督、半监督、无监督 CV&#xff1a;ImageNet pre-trained model NLP&#xff1a;pre-trained model? 在计算机视觉中任务包含分类、检测、分割&#xff0c;任务类别数少&#xff0c;对应…

sql server cdc漏扫数据

SQL Server的CDC指的是“变更数据捕获”&#xff08;Change Data Capture&#xff09;。这是SQL Server数据库提供的一项功能&#xff0c;能够跟踪并记录对数据库表中数据所做的更改。这些更改包括插入、更新和删除操作。CDC可以捕获这些变更的详细信息&#xff0c;并使这些信息…

如何在 Ubuntu 22.04 上安装 Caddy Web 服务器教程

简介 Caddy 是一个开源的 Web 服务器&#xff0c;它支持静态和现代 Web 应用程序&#xff0c;使用预定义的配置规则&#xff0c;并为所有链接的域名自动启用 HTTPS。Caddy 使用 GO 语言编写&#xff0c;提供了用户友好的配置指令&#xff0c;使你既可以将其用作 Web 服务器&am…

《机器学习》——贝叶斯算法

贝叶斯简介 贝叶斯公式&#xff0c;又称贝叶斯定理、贝叶斯法则&#xff0c;最初是用来描述两个事件的条件概率间的关系的公式&#xff0c;后来被人们发现具有很深刻的实际意义和应用价值。该公式的实际内涵是&#xff0c;支持某项属性的事件发生得愈多&#xff0c;则该属性成…

边缘计算网关在机床设备数据采集中的应用

边缘计算网关是连接边缘设备和云端的一个中间节点&#xff0c;负责在边缘设备和云服务器之间进行数据传输和处理。它具备数据采集、数据处理、协议转换、数据存储、安全功能及远程管理等多种能力&#xff0c;是边缘计算系统中不可或缺的关键设备。 一、功能与优势 数据采集&a…

腾讯二面:MySQL的半同步是什么?不是MySQL的两阶段提交,那是什么?

前言 年后在进行腾讯二面的时候&#xff0c;写完算法的后问的第一个问题就是&#xff0c;MySQL的半同步是什么&#xff1f;我当时直接懵了&#xff0c;我以为是问的MySQL的两阶段提交的问题呢&#xff1f;结果确认了一下后不是两阶段提交&#xff0c;然后面试官看我连问的是啥都…

云计算基础,虚拟化原理

文章目录 一、虚拟化1.1 什么是虚拟化1.2 虚拟化类型 二 、存储虚拟化2.1 存储指标2.2 存储类型2.3 存储协议2.4 RAID 三、内存 i/O虚拟化3.1 内存虚拟化基本概念地址空间转换原理内存共享与隔离原理 3.2 I/O 虚拟化基本概念模拟&#xff08;Emulation&#xff09;方式半虚拟化…

【网络协议】IPv4 地址分配 - 第二部分

前言 在第 1 部分中&#xff0c;我们学习了 IPv4 地址的分配方式&#xff0c;了解了各种类型的 IPv4 地址&#xff0c;并进行了基础的子网划分&#xff08;Subnetting&#xff09;。在第 2 部分中&#xff0c;我们将继续学习子网划分&#xff0c;并引入一些新的概念。 【网络…