数据结构总结

news2024/12/25 12:35:42

数据结构总结

  • 排序算法
    • 冒泡排序
    • 选择排序
    • 插入排序
    • 希尔排序
    • 堆排序
    • 快速排序算法
    • 归并排序
    • 计数排序
    • 基数排序
    • 红黑树
      • 基本概念
      • 规则
    • B树
      • 基础知识
      • 规则
    • B+树
    • 回溯算法
    • 并查集
    • 拓扑排序
  • 其他算法
    • KMP算法
  • 例题
    • 数组类
        • 求最大和子数组
        • 求子数组最大乘积
        • 删除重复链表元素

十大排序算法参考

排序算法

冒泡排序

冒泡排序通过俩个for循环来实现排序,每次循环将一个最大的数放在左侧,直到所有数排列完毕位置。
时间复杂度 o ( n 2 ) o(n^2) o(n2),空间复杂度 o ( 1 ) o(1) o(1)

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;
void sortArray(vector<int>& nums);
int main(){
    vector<int> nums({321,-3123,413,43,0,43,2,3,5,7,5,3,2,21,1,52,6,45,76,532,-4,341,-4343,24,-432,34,-43,2423});
    sortArray(nums);
    for(int &i:nums) cout << i << " ";
    return 0;
}
void sortArray(vector<int>& nums) {
    int len = nums.size();
    for(int i=0;i<len;++i){
        for(int j=0;j<len-i-1;++j){
            if(nums[j] > nums[j+1]){
                swap(nums[j], nums[j+1]);
            }
        }
    }
    return ;
}

选择排序

选择排序的思想是:双重循环遍历数组,每经过一轮比较,找到最小元素的下标,将其交换至首位。
时间复杂度 o ( n 2 ) o(n^2) o(n2),空间复杂度 o ( 1 ) o(1) o(1)
在这里插入图片描述

图中可以看出,每一轮排序都找到了当前的最小值,这个最小值就是被选中的数字,将其交换至本轮首位。这就是「选择排序法」名称的由来。

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;
void sortArray(vector<int>& nums);
int main(){
    vector<int> nums({321,-3123,413,43,0,43,2,3,5,7,5,3,2,21,1,52,6,45,76,532,-4,341,-4343,24,-432,34,-43,2423});
    sortArray(nums);
    for(int &i:nums) cout << i << " ";
    return 0;
}
void sortArray(vector<int>& nums) {
    int len = nums.size();
    for(int i=0;i<len;++i){
        int minindex = i;
        for(int j=i+1;j<len;++j){
            if(nums[minindex] > nums[j]) minindex = j;
        }
        swap(nums[i], nums[minindex]);//和最小值互换
    }
    return ;
}

插入排序

插入排序的思想非常简单,生活中有一个很常见的场景:在打扑克牌时,我们一边抓牌一边给扑克牌排序,每次摸一张牌,就将它插入手上已有的牌中合适的位置,逐渐完成整个排序。
时间复杂度 o ( n 2 ) o(n^2) o(n2),空间复杂度 o ( 1 ) o(1) o(1)
在这里插入图片描述

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;
void sortArray(vector<int>& nums);
int main(){
    vector<int> nums({321,-3123,413,43,0,43,2,3,5,7,5,3,2,21,1,52,6,45,76,532,-4,341,-4343,24,-432,34,-43,2423});
    sortArray(nums);
    for(int &i:nums) cout << i << " ";
    return 0;
}
void sortArray(vector<int>& nums) {
    int len = nums.size();
    for(int i=1;i<len;++i){
        int curnum = nums[i];
        int j = i-1;
        //向后移动大数
        while(j >= 0 && nums[j] > curnum){
            nums[j+1] = nums[j];
            --j;
        }
        nums[j+1] = curnum;
    }
    return ;
}

希尔排序

在这里插入图片描述

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;
void sortArray(vector<int>& nums);
int main(){
    vector<int> nums({321,-3123,413,43,0,43,2,3,5,7,5,3,2,21,1,52,6,45,76,532,-4,341,-4343,24,-432,34,-43,2423});
    sortArray(nums);
    for(int &i:nums) cout << i << " ";
    return 0;
}
void sortArray(vector<int>& nums) {
    // 间隔序列,在希尔排序中我们称之为增量序列
    for (int gap = nums.size()/2; gap > 0; gap /= 2) {
        // 分组
        for (int groupStartIndex = 0; groupStartIndex < gap; groupStartIndex++) {
            // 插入排序
            for (int currentIndex = groupStartIndex + gap; currentIndex < nums.size(); currentIndex += gap) {
                // currentNumber 站起来,开始找位置
                int currentNumber = nums[currentIndex];
                int preIndex = currentIndex - gap;
                while (preIndex >= groupStartIndex && currentNumber < nums[preIndex]) {
                    // 向后挪位置
                    nums[preIndex + gap] = nums[preIndex];
                    preIndex -= gap;
                }
                // currentNumber 找到了自己的位置,坐下
                nums[preIndex + gap] = currentNumber;
            }
        }
    }
}

堆排序

原理描述
代码实现

#include <iostream>
#include <vector>
using namespace std;
void heap_adjust(vector<int>& nums, int begin, int end);
void sort_heap(vector<int>& nums, int begin, int end);
int main(){
    vector<int> nums({2,4,5,7,8,2,1,5,7,856,545,23,4,1,23,23,213,1323,-321,-32,-321,-1,2,0,6435,65,80});
    sort_heap(nums, 0, nums.size());
    for(int &i:nums) cout << i << " ";
    return 0;
}

void sort_heap(vector<int>& nums, int begin, int end){
    for(int i=(end-1)/2;i>=0;--i){
        heap_adjust(nums, i, end);
    }
    for(int i=end;i>0;--i){
        swap(nums[0], nums[i-1]);
        heap_adjust(nums, 0, i-1);
    }
}

void heap_adjust(vector<int>& nums, int begin, int end){
    int father = begin;
    int son = 2*father+1;
    while(son+1 < end && son < end){
        if(nums[son] < nums[son+1]) ++son;
        if(nums[father] < nums[son]){
            swap(nums[father], nums[son]);
            father = son;
            son = 2*father+1;
        }else{
            return;
        }
    }
}

快速排序算法

快速排序算法由 C. A. R. Hoare 在 1960 年提出。它的时间复杂度也是 (nlogn)O(nlogn),但它在时间复杂度为O(nlogn) 级的几种排序算法中,大多数情况下效率更高,所以快速排序的应用非常广泛。再加上快速排序所采用的分治思想非常实用,使得快速排序深受面试官的青睐,所以掌握快速排序的思想尤为重要。
快速排序算法的基本思想是:
从数组中取出一个数,称之为基数(pivot)
遍历数组,将比基数大的数字放到它的右边,比基数小的数字放到它的左边。遍历完成后,数组被分成了左右两个区域,将左右两个区域视为两个数组,重复前两个步骤,直到排序完成。
事实上,快速排序的每一次遍历,都将基数摆到了最终位置上。第一轮遍历排好 1 个基数,第二轮遍历排好 2 个基数(每个区域一个基数,但如果某个区域为空,则此轮只能排好一个基数),第三轮遍历排好 4 个基数(同理,最差的情况下,只能排好一个基数),以此类推。总遍历次数为 logn~n 次,每轮遍历的时间复杂度为 O(n),所以很容易分析出快速排序的时间复杂度为 O ( n l o g n ) ~ O ( n 2 ) O(nlogn) ~ O(n^2) O(nlogn)O(n2),平均时间复杂度为 O(nlogn)。
在这里插入图片描述

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void temp(vector<int> &nums, int l, int r);
int n;
int main(){
    vector<int> nums({321,-3123,413,43,0,43,2,3,5,7,5,3,2,21,1,52,6,45,76,532,-4,341,-4343,24,-432,34,-43,2423});
    n = nums.size();
    temp(nums, 0, n);
    for(int &i:nums) cout << i << " ";
    return 0;
}

void sortArra(vector<int> &nums, int l, int r){
    //当需要排序的数组中只有一个或者没有元素时直接跳出
    if(r-l <= 1) return ;
    int pivot = l;//基数位置选取
    for(int i=l+1;i<r;++i){
        //判断是否需要进行位置更新
        if(nums[i] < nums[pvio]){
            nums.insert(nums.begin()+pvio, nums[i]);
            nums.erase(nums.begin()+i+1);
            ++pvio;
        }
    }
    //递归求解
    temp(nums, l, pvio);
    temp(nums, pvio+1, r);
    return ;
}

归并排序

归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
算法步骤:

  1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;
  2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置;
  3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;
  4. 重复步骤 3 直到某一指针达到序列尾;
  5. 将另一序列剩下的所有元素直接复制到合并序列尾。
    时间复杂度 o ( n l o g n ) o(nlogn) o(nlogn),空间复杂度 o ( n ) o(n) o(n)
    在这里插入图片描述
#include <iostream>
#include <vector>
using namespace std;
void sortArray(vector<int>& nums);
int main(){
    vector<int> nums({312,312,312,3213,312,12,43,2,345,356,44,5,658,56,546,5,32,0,1});
    sortArray(nums);
    for(int &i:nums) cout << i << " ";
    return 0;
}

void sortArray(vector<int>& nums){
    int len = nums.size();
    vector<int> temp = nums;
    //排序数组大小
    for(int seg=1;seg<len;seg += seg){
        //对每个子数组进行排序
        for(int start=0;start<len;start += 2*seg){
            int l = start, m = min(len, start+seg), h = min(len, start+2*seg);
            int k = l;
            int s1 = l, e1 = m;
            int s2 = m, e2 = h;
            //选取俩个子数组中最小的进行填充
            while(s1 < e1 && s2 < e2){
                temp[k++] = nums[s1] < nums[s2] ? nums[s1++]:nums[s2++];
            }
            //将剩余的进行尾加
            while(s1 < e1){
                temp[k++] = nums[s1++];
            }
            while(s2 < e2){
                temp[k++] = nums[s2++];
            }
        }
        //保留排序后的数组
        swap(temp, nums);
    }
}

计数排序

算法的步骤如下:

  1. 找出待排序的数组中最大和最小的元素
  2. 统计数组中每个值为i的元素出现的次数,存入数组C的第i项
  3. 对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加)
  4. 反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1

时间复杂度 o ( n ) o(n) o(n),空间复杂度 o ( n + k ) o(n+k) o(n+k)
在这里插入图片描述

基数排序

基数排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数。
时间复杂度 o ( n ) o(n) o(n),空间复杂度 o ( n + k ) o(n+k) o(n+k)
在这里插入图片描述

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
void sortArray(vector<int>& nums);
int main(){
    vector<int> nums({312,312,312,3213,312,12,43,2,345,356,44,5,658,56,546,5,32,0,1});
    sortArray(nums);
    for(int &i:nums) cout << i << " ";
    return 0;
}
//求解最大数据位数
int maxbit(vector<int>& nums){
    int maxbit = 0;
    int maxnum = *max_element(nums.begin(), nums.end());
    while(maxnum){
        ++maxbit;
        maxnum /= 10;
    }
    return maxbit;
}
void sortArray(vector<int>& nums){
    int len = nums.size();
    int d = maxbit(nums);
    vector<int> temp = nums;
    //创建排序桶
    vector<int> count(10, 0);
    for(int i=0;i<d;++i){
        count = vector<int>(10, 0);
        //计数值求解
        for(int j=0;j<len;++j){
            count[(int)(nums[j]/pow(10, i))%10]++;
        }
        //保证后续元素正确插入相关的位置
        for(int j=1;j<10;++j) count[j] += count[j-1];
        //从后向前插入数据
        for(int j=len-1;j>=0;--j){
            temp[--count[(int)(nums[j]/pow(10, i))%10]] = nums[j];
        }
        swap(nums, temp);
    }
    return ;
}

红黑树

基本概念

在具体实现红黑树之前,必须弄清它的基本含义。红黑树本质上是一颗二叉搜索树,它满足二叉搜索树的基本性质——即树中的任何节点的值大于它的左子节点,且小于它的右子节点。理论上,一颗平衡的二叉搜索树的任意节点平均查找效率为树的高度h,即O(lgn)。但是如果二叉搜索树的失去平衡(元素全在一侧),搜索效率就退化为O(n),因此二叉搜索树的平衡是搜索效率的关键所在。于是红黑树就是通过自身的特性去维持整个搜索叔的平衡性的。

规则

顾名思义,红黑树的节点是有颜色概念的,即非红即黑。通过颜色的约束,红黑树维持着二叉搜索树的平衡性。一颗红黑树必须满足以下几点条件:

  1. 根节点必须是黑色。
  2. 任意从根到叶子的路径不包含连续的红色节点。
  3. 任意从根到叶子的路径的黑色节点总数相同。
    在这里插入图片描述

B树

基础知识

B树就是一棵平衡的多叉查找树。用于实现快速查找,相对于二叉树,具有更多的分支,更小的高度。查找树的高度决定了查找过程中访问磁盘的次数,而磁盘的访问速度低。由于B树具有更小的高度,因此在查找时对磁盘的访问会大大降低,从而相对于二叉查找树有更高的效率。

规则

下面的 m 是 B 树的阶,阶就是一颗树每个结点最多包含的孩子数,m 取值与磁盘页大小有关
1.根结点至少两个子女
2.每个中间结点有 k-1 个元素,和有 k 个孩子,m/2 <= k <= m(m/2 向上取整)
3.每个叶子结点有 k-1 个元素,m/2 <= k <= m(m/2 向上取整)
4.所有叶子结点都位于同一层
5.每个节点中的元素从小到大排列,节点当中k-1个元素正好是k个孩子包含的元素的值域分划
在这里插入图片描述

B+树

B+树和B树的区别:

  1. B+跟B树不同在于B+树的非叶子节点不保存关键字记录的指针,只进行数据索引,这样使得B+树每个非叶子节点所能保存的关键字大大增加;
  2. B+树叶子节点保存了父节点的所有关键字记录的指针,所有数据地址必须要到叶子节点才能获取到。所以每次数据查询的次数都一样;

回溯算法

Backtracking:回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径。当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法。
相关例题
代码实现:

class Solution {
public:
    vector<vector<int>> ans;
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        vector<int> tempcand;
        temp(candidates, tempcand,target, 0);
        return ans;
    }

    void temp(vector<int>& candidates, vector<int>& tempcand, int target, int idx){
        //判断是否生成满足条件的结果
        if(target == 0) {
            ans.push_back(tempcand);
            return ;
        }
        //判断是否需要剪枝
        if(target < 0) return ;
        //遍历所有值进行回溯
        for(int i=idx;i<candidates.size();++i){
            vector<int> v = tempcand;
            v.push_back(candidates[i]);
            temp(candidates, v, target-candidates[i], i);
        }
        return ;
    }

};

并查集

参考资料
并查集是一种树型的数据结构,用于处理一些不相交集合的合并及查询问题。主要涉及到俩种操作:

  1. 查询(Find):查询图中的两个顶点是不是在同一个集合中。
    注意:并查集只回答两个顶点之间是否有一条路径连接,而不回答怎么连接。
  2. 合并(Union):将两个不相交集合进行合并。

首先需要初始化父节点数组,初始化状态下默认自己为自身的父节点。

vector<int> fa;
for(int i=0;i<26;++i) fa.push_back(i);

之后设计查询函数

 int find(int x){
        if(fa[x] == x) return x;
        else{
            fa[x] = find(fa[x]);
            return fa[x];
        }
    }

最后设计合并操作

void merg(int a, int b){
        fa[find(a)] = find(b);
    }

在实际应用中需要通过判断是否位于一个组合进而判断是否满足要求并进行下一步的操作。

练习题目

拓扑排序

参考链接
拓扑排序实质是对有向图的顶点排成一个线性序列,生成的排序满足顶点之间的相互依赖关系。
相关例题
代码实现:

class Solution {
public:
    vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
        //保存依赖关系
        vector<vector<int>> edgs(numCourses);
        //记录每个顶点的入度
        vector<int> index(numCourses, 0);
        //初始化依赖关系和顶点入度
        for(auto &v:prerequisites){
            edgs[v[1]].push_back(v[0]);
            ++index[v[0]];
        }
        vector<int> ans;
        deque<int> d;
        //初始条件下入度为空的顶点入队列。
        for(int i=0;i<numCourses;++i){
            if(index[i] == 0){
                ans.push_back(i);
                d.push_back(i);
                --index[i];
            }
        }
        //结合队列实现广度优先队列
        while(!d.empty()){
            int currnum = d.front();
            d.pop_front();
            //对应的依赖节点入度-1
            for(int &i:edgs[currnum]){
                if(--index[i] == 0){
                    --index[i];
                    ans.push_back(i);
                    d.push_back(i);
                }
            }
        }
        //如多还有
        if(ans.size() != numCourses) return vector<int>();
        return ans;
    }
};

其他算法

KMP算法

例题

数组类

求最大和子数组

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
using namespace std;
vector<int> findMaxsubarr1(vector<int>& nums);
vector<int> findMaxsubarr2(vector<int>& nums);
int main(){
    vector<int> nums({-1,1,2,3,-4,5,6,-3,8,10});
    vector<int> ans = findMaxsubarr2(nums);
    for(int &i:ans) cout << i << " ";
    return 0;
}

vector<int> findMaxsubarr1(vector<int>& nums){
    int len = nums.size();
    int sum = accumulate(nums.begin(), nums.end(), 0);
    int tempsum = sum;
    vector<int> ans;
    int l = 0, r = len-1;
    while(l < r){
        if(nums[l] < nums[r]){
            sum -= nums[l++];
        }else{
            sum -= nums[r--];
        }
        if(tempsum < sum) ans = vector<int>(nums.begin()+l, nums.begin()+r+1);
    }
    return ans;
}
vector<int> findMaxsubarr2(vector<int>& nums){
    int len = nums.size();
    int maxnum = 0;
    int tempsum = 0;
    int l = 0, r = 0;
    vector<int> ans;
    for(int i=0;i<len;++i){
        tempsum += nums[i];
        r = i;
        if(maxnum < tempsum){
            ans = vector<int>(nums.begin()+l, nums.begin()+r+1);
            maxnum = tempsum;
        }
        if(tempsum < 0){
            l = i+1;
            r = l;
            tempsum = 0;
        }
    }
    return ans;
}

求子数组最大乘积

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
using namespace std;
int maxProduct(vector<int>& nums);
int main(){
    vector<int> nums({-1,1,2,3,-4,5,6,-3,8,10});
    cout << maxProduct(nums);
    return 0;
}
int maxProduct(vector<int>& nums) {
    int len = nums.size();
    //维持一以当前元素结尾,最大和最小队列
    vector<int> fmax(len, 0), fmin(len, 0);
    fmax[0] = nums[0], fmin[0] = nums[0];
    for(int i=1;i<len;++i){
        //同时更新当前的最大最小队列状态,
        fmax[i] = max(fmax[i-1]*nums[i], max(nums[i], fmin[i-1]*nums[i]));
        fmin[i] = min(fmin[i-1]*nums[i], min(nums[i], fmax[i-1]*nums[i]));
    }
    return *max_element(fmax.begin(), fmax.end());
}

删除重复链表元素

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

struct Listnode{
    int val;
    Listnode* next;
};
Listnode* temp(Listnode* head);
int main(){
    Listnode n0{1},n1{2},n2{2},n3{2},n4{2},n5{6};
    n0.next = &n1, n1.next = &n2, n2.next = &n3, n3.next = &n4, n4.next = &n5, n5.next = nullptr;
    Listnode *node = temp(&n0);
    while(node){
        cout << node->val << " ";
        node = node->next;
    }
    return 0;
}

Listnode* temp(Listnode* head){
    Listnode* node = head;
    Listnode* pre = new Listnode{0};
    Listnode* tempnode = nullptr;
    pre->next = node;
    while(node){
        int num = node->val;
        if(node->next && node->next->val == num){
            while(node->next && node->next->val == num){
                node = node->next;
            }
            node = node->next;
        }
        if(!tempnode) tempnode = node;
        pre->next = node;
        pre = node;
        node = node->next;
    }
    return tempnode;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

16:00面试,16:09就出来了 ,问的实在是太...

从外包出来&#xff0c;没想到算法死在另一家厂子 自从加入这家公司&#xff0c;每天都在加班&#xff0c;钱倒是给的不少&#xff0c;所以也就忍了。没想到8月一纸通知&#xff0c;所有人不许加班&#xff0c;薪资直降30%&#xff0c;顿时有吃不起饭的赶脚。 好在有个兄弟内…

情人节快到了,我部署了一套情侣头像小程序,并过审了

最近在学习如何部署微信小程序&#xff0c;目的就是像拥有一个属于自己的小程序 之前做的是一个微信公众号&#xff0c;靠自然的流量虽然也开通了流量主&#xff0c;但是每天收益就是那0.0几的,所有寻思看能不能做一个小程序出来。不会写小程序的我&#xff0c;也只能用现成的…

IO流01_字节字符流、缓冲流、标准输入、输出流、打印流

文章目录①. IO流概述及分类②. 字节输入流 - FileInputStream③. 字节输出流 - FileOutputStream④. 字符输入流 - FileReader⑤. 字符输出流 - FileWriter⑥. 字节缓冲流 - Buffered⑦. 掌握 - 相关流习题操作⑧. 标准输入、输出流(了解)⑨. 打印流 - PrintStream、PrintWrit…

Retinanet网络与focal loss损失

1.损失函数 1&#xff09;原理 本文一个核心的贡献点就是 focal loss。总损失依然分为两部分&#xff0c;一部分是分类损失&#xff0c;一部分是回归损失。 在讲分类损失之前&#xff0c;我们来回顾一下二分类交叉熵损失 &#xff08;binary_cross_entropy&#xff09;。 计…

算法设计与分析(屈婉玲)视频笔记day2

序列求和的方法 数列求和公式 等差、等比数列与调和级数 求和的例子 二分检索算法 二分检索运行实例 2 n 1个输入 比较 t 次的输入个数 二分检索平均时间复杂度 估计和式上界的放大法 放大法的例子 估计和式渐近的界 估计和式渐近的界 小结 • 序列求和基本公式&#xff1a;…

使用 CSS 变量更改多个元素样式

使用 CSS 变量更改多个元素样式 var() 函数用于插入自定义的属性值&#xff0c;如果一个属性值在多处被使用&#xff0c;该方法就很有用。 custom-property-name 是必需的, 自定义属性的名称&#xff0c;必需以 – 开头。 value 可选。备用值&#xff0c;在属性不存在的时候使…

牛客网Python篇数据分析习题(六)

1.某公司计划举办一场运动会&#xff0c;现有运动会项目数据集items.csv。 包含以下字段&#xff1a; item_id&#xff1a;项目编号&#xff1b; item_name:项目名称&#xff1b; location:比赛场地。 有员工报名情况数据集signup.csv。包含以下字段&#xff1a; employee_id&a…

高性能(二)

三、读写分离和分库分表 1.读写分离 1.1 概述 将数据库的读写操作分散到不同的数据库节点上 通常一主多从一台主数据库负责写&#xff0c;多台从数据库负责读。 主库和从库之间会进行数据同步&#xff0c;以保证从库中数据的准确性。 1.2 问题及解决 1.2.1 问题 主从同…

ChatGPT眼中的产品经理是这样的

在玩ChatGPT的时候&#xff0c;突发奇想&#xff0c;ChatGPT对产品经理的认知是啥样呢&#xff1f;于是我找了几个大家都比较关注的产品经理问题&#xff0c;看看ChatGPT是如何回答的。1、产品经理可以干一辈子嘛&#xff1f;2、产品经理的核心竞争力是啥&#xff1f;3、产品经…

【本周特惠课程】深度学习6大模型部署场景(Pytorch+NCNN+MNN+Tengine+TensorRT+微信小程序)速成!...

前言欢迎大家关注有三AI的视频课程系列&#xff0c;我们的视频课程系列共分为5层境界&#xff0c;内容和学习路线图如下&#xff1a;第1层&#xff1a;掌握学习算法必要的预备知识&#xff0c;包括Python编程&#xff0c;深度学习基础&#xff0c;数据使用&#xff0c;框架使用…

操作系统——1.操作系统的概念、定义和目标

目录 1.概念 1.1 操作系统的种类 1.2电脑的组成 1.3电脑组成的介绍 1.4操作系统的概念&#xff08;定义&#xff09; 2.操作系统的功能和目标 2.1概述 2.2 操作系统作为系统资源的管理者 2.3 操作系统作为用户和计算机硬件间的接口 2.3.1用户接口的解释 2.3.2 GUI 2.3.3接…

代码随想录第十一天(459)

文章目录459. 重复的子字符串答案思路暴力破解移动匹配459. 重复的子字符串 也不知道为啥这个提示简单题…… 答案思路 暴力破解 例如&#xff1a;abcabc 移位一次&#xff1a;cabcab 移位两次&#xff1a;bcabca 移位三次&#xff1a;abcabc 现在字符串和原字符串匹配了…

搭建Vue版Ant Design Pro后台管理系统

搭建Vue版Ant Design Pro后台管理系统 此文章通过基于Vue实现的Ant DesignPro脚手架快速构建一个后台管理系统的前端 相关文档链接 1、【Ant Design Pro of Vue 官方文档】2、【Vue 官方文档】3、【Vue Router 官方文档】 Ant Design Pro相关系列文章&#xff1a; 一、AntDesig…

Ansible中常用的模块

目录 一、Ansible Ad-Hoc命令集 1 Ad-hoc 使用场景 2 Ansible的并发特性 3 Ansible-doc用法 4 ansible命令运行方式及常用参数 5 ansible的基本颜色代表 6 ansible中的常用模块 command模块 shell模块 script模块 copy模块 fetch模块 unarchive模块 archive模块…

Spring3之控制反转(IOC)

简介 控制反转(Inversion of Control, 缩写为IoC), 是面向对象编程中的一种设计原则, 可以用来减低计算机代码之间的耦合度;其中最常见的方式叫做依赖注入(Dependency Injection, 简称DI), 还有一种方式叫 “赖查找” (Dependency Lookup); 通过控制反转, 对象在被创建的时候,…

CData Drivers for Acumatica

CData Drivers for Acumatica Acumatica的CData驱动程序为用户提供了使用AcumaticaERP数据的便捷途径&#xff0c;该数据来自商业智能、分析、定制应用程序、报告以及ETL。通过JDBC、ADO.NET和ODBC等标准驱动程序&#xff0c;以及与PowerShell、Power BI、Excel、SSIS等流行应用…

java微信小程序音乐播放器分享系统

随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,音乐播放器小程序被用户普遍使用,为方便用户能够可以随时进行音乐播放器小程序的数据信息管理,特开发了基于音乐播放器小程序…

计算之变:联想问天给中国智能IT基础设施划下新起点

“冥昭瞢暗&#xff0c;谁能极之&#xff1f;冯翼惟象&#xff0c;何以识之&#xff1f;”屈原在《天问》中喊出了心中的困惑&#xff0c;用无数个问题&#xff0c;展现了中国人对世界的探索精神和好奇心。人对时空无限性的追问&#xff0c;伴随的是对有限性的焦灼感。幸好&…

JZ50、JZ57、JZ56

文章目录JZ50 第一个只出现一次的字符题目描述&#xff1a;具体实现&#xff1a;JZ57 和为S的两个数字题目描述&#xff1a;具体实现&#xff1a;JZ56 数组中只出现一次的两个数字题目描述具体实现&#xff1a;JZ50 第一个只出现一次的字符 题源 &#x1f449; 第一个只出现一…

在线预览PDF文件、图片,并且预览地址不显示文件或图片的真实路径。

实现在线预览PDF文件、图片&#xff0c;并且预览地址不显示文件或图片的真实路径。1、vue使用blob流在线预览PDF、图片&#xff08;包括jpg、png等格式&#xff09;。1、按钮的方法&#xff1a;2、方法详细&#xff1a;&#xff08;此方法可以在发起请求时携带token&#xff0c…