排序类算法

news2024/11/18 5:31:20

目录

一、交换类排序

1.冒泡排序

2.快速排序

二、 插入排序

1.直接插入排序

2.折半插入排序

3.希尔排序

三、选择排序

1.简单选择排序

2.堆排序

 完整代码

四、归并排序

 完整代码

五、汇总

六、OJ练习 

        1.冒泡排序:正确表示前一个数和后一个数   

2.选择、堆、归并

完整代码 


一、交换类排序

1.冒泡排序

演示地址:

Comparison Sorting Visualization

 注意:n个数

1.交换条件 如果从小到大排列那么  判断 大数在前就发生交换

2.注意外层循环控制趟数 i从0 到  n-1趟    i++

3.注意内层循环控制遍历着进行交换  从后往前 n-1  到   i   j不能取0因为里面有j-1   j--

4.注意flag是看是否进行交换  经过一趟后没有发生交换则序列本身有序

#include <stdio.h>


void BubbleSort(int A[10],int n);

void swap(int &a,int &b){
    int temp=a;
    a=b;
    b=temp;
}

int main() {
    int A[10]={9,7,8,6,5,4,3,2,1,0};
    BubbleSort(A,10);
    for (int i = 0; i < 10; ++i) {
        printf("%2d",A[i]);
    }
    return 0;
}

void BubbleSort(int A[10],int n) {
    //控制趟数
    for (int i = 0; i < n - 1; ++i) {
        //交换标志
        bool flag= false;
        //控制交换
        for (int j = n-1; j > i; j--) {
            //从小到大排列 大的在前那么就要发生交换了
            if (A[j-1]>A[j]){
                swap(A[j],A[j-1]);
                flag= true;
            }
        }
        if (!flag){
            //如果经过依次检查后没有发生交换则该数组本身有序
            return;
        }
    }
}

2.快速排序

注意:分治思想

        挖坑法(不断覆盖)得到分隔值的位置

        注意每次循环都要判断   low<high

        注意出现相等的数我们不用管--不需要处理

        最终low与high是相等的

演示地址:

Comparison Sorting Visualization

16.5 快速排序 

64, 94, 95, 79, 69, 84, 18, 22, 12 ,78

把比64小的放在64的左边,把比64大的放在它的右边
18, 22, 12 64  ,94, 95, 79, 69, 84,78

16.6 快速排序实战
原来的
64, 94, 95, 79, 69, 84, 18, 22, 12 ,78


pivot=64
12, 22, 18, 64, 69, 84, 79, 95, 94 ,78
                 high
                 low
pivot=64
12, 94, 95, 79, 69, 84, 18, 22, 12 ,78
                                               high
     low
 

#include <stdio.h>

//得到分割值的位置--挖坑法(不断覆盖)
int getPosition(int A[],int low,int high){
    //把low的位置作为分隔值
    int provt=A[low];
    while (low<high){
        //从high往前找比分隔值小的数的位置--注意循环里面也要判断low<high
        while (low<high&&A[high]>=provt){
            //没有找到就往前移动
            high--;
        }
        //出循环 这时A[high]<provt  就找到了 这个小的元素
        //我们需要把它覆盖到low的位置上
        A[low]=A[high];
        //从low往后找 直到找到比分隔值大的元素--注意循环里面也要判断low<high
        while (low<high&&A[low]<=provt){
            low++;
        }
        //此时A[low]>provt 找到了大的元素我们需要把它放到分割值的右边
        //因此我们需要把它覆盖到high的位置上
        A[high]=A[low];
    }
    //不要忘记把分隔值赋值上去
    A[low]=provt;
    //此时low=high的
    return low;
}


//快速排序--分治思想
void quickSort(int A[],int low,int high){
    if (low>=high){
        return;
    }
    //进行第一次快速排序得到分隔值的位置
    int position=getPosition(A,low,high);
    //接下来排列分隔值的左边
    quickSort(A,low,position-1);
    //接下来排列分隔值的右边
    quickSort(A,position+1,high);
}

二、 插入排序

1.直接插入排序

注意:

        外层循环控制:无序序列的个数--即要插入的元素个数  i从 1到len-1

        内层循环控制交换 注意条件 

        此时j的位置是从i-1开始 j>=0&&A[j]>inserVal 那么就将后面的元素进行覆盖

        注意最后要将j+1的位置即为要插入的位置

        因为循环完成后我们直到j这个位置是小于inserVal的所以要插入到这个位置的后面

16.7 插入排序的原理及实战

insertVal=1
                           i
    1 2 3 72 78      87 61 38 12 40
 j

//玩坑法(覆盖)  插入排序
void insertSort(int A[],int len){
    int i,j,inserVal;
    //注意循环起始  此时有序数列中左半边为1个元素  所以无序的右半边从 1开始到len-1
    for (i = 1; i < len; ++i) {//外层循环控制要插入的数量
        //存储当前要插入的值
        inserVal=A[i];
        //那么我们判断就从有序的开始  i-1  到0--并且这个元素大于要插入的元素那么就进行覆盖
        for (j = i-1; j >=0&&A[j]>inserVal ; j--) {
            //就将后面的元素覆盖成大的那一个
            A[j+1]=A[j];
        }
        //最终要将插入元素进行插入-这里要使用到j因此要将j定义到循环外面
        //如果最终j--到0了 那么此时将j+1的位置也就是0的位置即插入位置
        A[j+1]=inserVal;
    }
}

2.折半插入排序

3.希尔排序

三、选择排序

1.简单选择排序

注意:

         内层循环:

        找到那么就记录该位置--必须写在这  因为我们要把后续的位置找全  找出最小
        如果写在循环条件处那么 它就会找到一个就交换一次  而不是最小才交换  注意最小条件

//简单选择排序
void selectSort(int A[],int len){
    int min;
    for (int i = 0; i < len - 1; ++i) {
        //外层循环控制趟数
        //每次都找出一个最小的 交换那么  只需要找len-1次
        //记录最小值位置
        min=i;
        //内层循环从未确定的序列中找最小的位置 因此从i+1开始到结束
        for (int j = i+1; j < len; ++j) {
            //找到那么就记录该位置--必须写在这  因为我们要把后续的位置找全  找出最小
            //如果写在循环条件处那么 它就会找到一个就交换一次  而不是最小才交换  注意最小条件
            if (A[j]<A[min]){
                min=j;
            }
        }
        //进行交换
        swap(A[min],A[i]);
    }
}

2.堆排序


演示地址:Heap Sort Visualization

每次调整大根堆的时间复杂度为树的高度  调整n次  因此为n*logn

 

 

 注意:

        1.循环调整子树为大根堆的循环条件(son<len)--注意调整完后要重置dad与son

           因为这颗子树可能下面还有子树 

           我们需要让dad=son的 son=2*dad+1 这这颗子树也满足大根堆依次往复

        2.注意len是代表什么

        3.注意建立大根堆的循环条件  i是从最后一个父节点开始到0

        4.注意循环剩余元素为大根堆的循环条件 

        i代表无序的个数 i从len-1到1 直到调整到剩余俩个元素

 

 

//交换
void swap(int &a,int &b){
    int temp=a;
    a=b;
    b=temp;
}

/**
 * 调整一个子树为大根堆
 * @param A
 * @param dad 最后一个节点的父节点位置
 * @param len 需要调整的长度
 */
void adjustMaxTree(int A[],int last,int len){
    int dad=last;
    int son=2*dad+1;
    while (son<len){
        if (son+1<len&&A[son]<A[son+1]){
            //比较左 右 孩子中最大的元素
            //如果左孩子 小于 右孩子--最大元素为右孩子
            son++;//拿右孩子
        }
        //得到最大元素为A[son]
        if (A[son]>A[dad]){//如果孩子大于父亲 交换
            //将孩子中最大的放到根节点上
            swap(A[son],A[dad]);
            //重置父子节点位置
            dad=son;//son重新作为dad去验证下面的子树是否为大根堆--
            son=2*dad+1;
            //继续循环重新进行调整我们交换完的下面的那颗子树是否满足大根堆
        } else{
            //这个子树中的所有的子树全部满足大根堆
            break;
        }

    }
}

//堆排序
void heapSort(int A[],int len){
    //建立大根堆
    for (int i = len/2-1; i >= 0; i--) {
        //从最后一个子树的父亲节点开始到0
        adjustMaxTree(A,i,len);
    }
    //将最大元素放到数组末尾
    swap(A[0],A[len-1]);
    //调整剩余元素为大根堆并从小到大排列--调整到只剩2个元素
    for (int i = len-1; i > 1; i--) {
        //i代表的是无序的个数
        //因为把最大的元素放到了最后一个树节点上 那么每次都要调整 父亲节点地址为0 长度为 i的元素为大跟堆
        adjustMaxTree(A,0,i);
        //调整之后进行交换--交换根部元素
        swap(A[0],A[i-1]);
    }
}

 完整代码

#include <stdio.h>


//交换
void swap(int &a,int &b){
    int temp=a;
    a=b;
    b=temp;
}

/**
 * 调整一个子树为大根堆
 * @param A
 * @param dad 最后一个节点的父节点位置
 * @param len 需要调整的长度
 */
void adjustMaxTree(int A[],int last,int len){
    int dad=last;
    int son=2*dad+1;
    while (son<len){
        if (son+1<len&&A[son]<A[son+1]){
            //比较左 右 孩子中最大的元素
            //如果左孩子 小于 右孩子--最大元素为右孩子
            son++;//拿右孩子
        }
        //得到最大元素为A[son]
        if (A[son]>A[dad]){//如果孩子大于父亲 交换
            //将孩子中最大的放到根节点上
            swap(A[son],A[dad]);
            //重置父子节点位置
            dad=son;//son重新作为dad去验证下面的子树是否为大根堆--
            son=2*dad+1;
            //继续循环重新进行调整我们交换完的下面的那颗子树是否满足大根堆
        } else{
            //这个子树中的所有的子树全部满足大根堆
            break;
        }

    }
}

//堆排序
void heapSort(int A[],int len){
    //建立大根堆
    for (int i = len/2-1; i >= 0; i--) {
        //从最后一个子树的父亲节点开始到0
        adjustMaxTree(A,i,len);
    }
    //将最大元素放到数组末尾
    swap(A[0],A[len-1]);
    //调整剩余元素为大根堆并从小到大排列--调整到只剩2个元素
    for (int i = len-1; i > 1; i--) {
        //i代表的是无序的个数
        //因为把最大的元素放到了最后一个树节点上 那么每次都要调整 父亲节点地址为0 长度为 i的元素为大跟堆
        adjustMaxTree(A,0,i);
        //调整之后进行交换--交换根部元素
        swap(A[0],A[i-1]);
    }
}

int main() {
    int A[10]={58,42,13,58,44,53,73,75,2,69};
    int len=10;
    heapSort(A,len);
    for (int i = 0; i < 10; ++i) {
        printf("%3d",A[i]);
    }
    return 0;
}

四、归并排序

注意:

        1.复制临时数组  static int B[N];

        2.复制的时候for循环从low开始  避免覆盖掉之前的元素

        3.合并的时候  注意合并的那个数组A  k是从low开始  避免覆盖掉之间的元素

        4.不要忘记 剩余元素的合并

#define N 50

void merge(int A[],int low,int mid,int high){
    //注意static无论递归多少次都只有一个B
    static int  B[N];
    //复制临时数组--注意这里是low 到high
    for (int i = low; i <= high; ++i) {
        B[i]=A[i];
    }
    int i,j,k;
    //注意k是从low开始
    for ( i = low,j=mid+1,k=low;i<=mid&&j<=high; k++) {
        //i j 的元素值进行比较 小的放入A中--并且放入的元素的那个向后移动
        if (B[i]<B[j]){
            A[k]=B[i++];
        } else{
            A[k]=B[j++];
        }
    }
    //看哪个有剩余都放入到A中即可
    while (i<=mid){
        A[k++]=B[i++];
    }
    while (j<=high){
        A[k++]=B[j++];
    }
}

void mergeSort(int A[],int low,int high){
    if (low<high){
        int mid=(low+high)/2;
        //排序前半边
        mergeSort(A,low,mid);
        //排序号后半边
        mergeSort(A,mid+1,high);
        //合并为有序数组
        merge(A,low,mid,high);
    }
}

 完整代码

#include <stdio.h>

#define N 50

void merge(int A[],int low,int mid,int high){
    //注意static无论递归多少次都只有一个B
    static int  B[N];
    //复制临时数组--注意这里是low 到high
    for (int i = low; i <= high; ++i) {
        B[i]=A[i];
    }
    int i,j,k;
    //注意k是从low开始
    for ( i = low,j=mid+1,k=low;i<=mid&&j<=high; k++) {
        //i j 的元素值进行比较 小的放入A中--并且放入的元素的那个向后移动
        if (B[i]<B[j]){
            A[k]=B[i++];
        } else{
            A[k]=B[j++];
        }
    }
    //看哪个有剩余都放入到A中即可
    while (i<=mid){
        A[k++]=B[i++];
    }
    while (j<=high){
        A[k++]=B[j++];
    }
}

void mergeSort(int A[],int low,int high){
    if (low<high){
        int mid=(low+high)/2;
        //排序前半边
        mergeSort(A,low,mid);
        //排序号后半边
        mergeSort(A,mid+1,high);
        //合并为有序数组
        merge(A,low,mid,high);
    }
}

int main() {
    int A[10]={58,42,13,58,44,53,73,75,2,69};
    int low=0,high=9;
    mergeSort(A,low,high);
    for (int i = 0; i <10; ++i) {
        printf("%3d",A[i]);
    }
    return 0;
}

五、汇总

六、OJ练习 

注意:

        1.冒泡排序:正确表示前一个数和后一个数   

        j--

#include <stdio.h>

//读取10个整型数据12 63 58 95 41 35 65  0 38 44,
// 然后通过冒泡排序,快速排序,插入排序,分别对该组数据进行排序,输出3次有序结果,每个数的输出占3个空格

//交换
void swap(int &a,int &b){
    int temp=a;
    a=b;
    b=temp;
}

void print_A(int A[],int len){
    //排序完成
    for (int i = 0; i < len; ++i) {
        printf("%3d",A[i]);
    }
    printf("\n");
}

//冒泡排序
void BubbleSort(int A[],int len){
    bool flag= false;
    for (int i = 0; i < len ; ++i) {
        for (int j = len-1; j > i; j--) {
            //从小到大 如果前面比后面大交换
            if (A[j-1]>A[j]){
                swap(A[j-1],A[j]);
                flag= true;
            }
        }
        if (!flag){
            return;
        }
    }
    print_A(A,len);
}

//挖坑法--分割
int patition(int A[],int low,int high){
    //先将low的位置作为分割值
    int provt=A[low];
    while (low<high){
        //从后往前找比分隔值小的数进行覆盖
        while (low<high&&A[high]>=provt){
            high--;
        }
        //此时A[high]<provt
        A[low]=A[high];
        //从前往后找比分隔值大数进行覆盖
        while (low<high&&A[low]<=provt){
            low++;
        }
        //此时A[low]>provt
        A[high]=A[low];
    }
    //填入分隔值
    A[low]=provt;
    return low;
}

//快速排序--分治
void quickSort(int A[],int low,int high){
    if (low>high){
        return;
    }
    //确定一个分割位置
    int position=patition(A,low,high);
    //排序左边
    quickSort(A,low,position-1);
    //排序右边
    quickSort(A,position+1,high);
}

//插入排序
void inserSort(int A[],int len){
    int i,j,insertVal;
    for (i = 1; i < len; ++i) {
        insertVal=A[i];
        for (j = i-1; j >=0&&A[j]>insertVal; j--) {
            //交换
            A[j+1]=A[j];
        }
        //插入
        A[j+1]=insertVal;
    }
    print_A(A,len);
}


int main() {
    int A[10];
    for (int i = 0; i < 10; ++i) {
        int x;
        scanf("%d",&x);
        A[i]=x;
    }
    int len=10;
    BubbleSort(A,len);
    quickSort(A,0,len-1);
    print_A(A,len);
    inserSort(A,len);
    return 0;
}

2.选择、堆、归并

选择排序:注意  找到最小的后是交换 而不是覆盖

堆排序:  注意第一次建立完大根堆后  将根节点(最大)与最后一个节点进行交换

                然后再依次进行 大根堆的建立 建立的时候 因为最后都改变了根节点与最后一个元                  素的值  那么每次建立大根堆的父节点都是从0开始  注意起始条件

归并排序:注意不要忘记剩余节点也要合为一个数组

//交换
void swap(int &a,int &b){
    int temp=a;
    a=b;
    b=temp;
}

//选择排序--找最小的放到前面/找最大的放到后面
void SelectSort(int A[],int len){
    int i=0,min,j;
    int temp=A[i];
    while (i<len){
        min=i;
        for (j = i+1; j < len; ++j) {
            if (A[min]>A[j]){
                min=j;
            }
        }
        //找到了最小值
        swap(A[i++],A[min]);
    }
}

//建立大根堆
void buildMaxTree(int A[],int last,int len){
    int dad=last;
    int son=last*2+1;
    while (son<len){
        if (son+1<len&&A[son]<A[son+1]){
            son++;//拿到右孩子作为最大
        }
        //最大的孩子节点值与父节点比较替换
        if (A[son]>A[dad]){
            swap(A[son],A[dad]);
            //重置dad与son 为下一个子树
            dad=son;
            son=2*dad+1;
        } else{
            //全部变为大根堆 没有任何交换后--退出循环
            break;
        }
    }
}

//堆排序
void heapSort(int A[],int len){
    //对于初始数组建立大根堆
    for (int i = len/2-1; i >= 0; i--) {
        buildMaxTree(A,i,len);
    }
    //之后交换根节点与最后一个节点
    swap(A[0],A[len-1]);
    //堆剩余元素进行大根堆的依次建立--直到仅剩余2个节点
    for (int i = len-1; i >1 ; i--) {//i为当今剩余的无序节点数量
        //因为交换了 那么改变的就是A[0]节点开始 的大根堆--因此此时父节点为0
        buildMaxTree(A,0,i);
        //交换改变
        swap(A[0],A[i-1]);
        //继续上述操作
    }
}
//归并排序--合并有序数组
void merge(int A[],int low,int mid,int high){
    static int B[N];
    for (int i = low; i <= high; ++i) {
        B[i]=A[i];
    }
    int i,j,k;
    for (i = low,j=mid+1,k=low;i<=mid&&j<=high; k++) {
        if (B[i]<B[j]){
            A[k]=B[i++];
        } else{
            A[k]=B[j++];
        }
    }
    //不要忘记还有剩余元素
    while (i<=mid){
        A[k++]=B[i++];
    }
    while (j<=high){
        A[k++]=B[j++];
    }
}
//归并排序
void mergeSort(int A[],int low,int high){
    if (low>=high){
        return;
    }
    int mid=(low+high)/2;
    //归并前半部分
    mergeSort(A,low,mid);
    //归并后半部分
    mergeSort(A,mid+1,high);
    //合并为有序数列
    merge(A,low, mid,high);
}

void printSort(int A[],int len){
    for (int i = 0; i < len; ++i) {
        printf("%3d",A[i]);
    }
}

完整代码 

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

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

相关文章

Transformer模型引领NLP革新之路

在不到4 年的时间里&#xff0c;Transformer 模型以其强大的性能和创新的思想&#xff0c;迅速在NLP 社区崭露头角&#xff0c;打破了过去30 年的记录。BERT、T5 和GPT 等模型现在已成为计算机视觉、语音识别、翻译、蛋白质测序、编码等各个领域中新应用的基础构件。因此&#…

2、功能安全入门之ISO26262说人话版本GB_T 34590

目录 0. 一些功能安全资料 1. 什么是功能安全? 1.1 安全三剑客 1.2 功能安全如何解决问题: 2. ISO26262说人话版本 3-5 相关项 3-7 危害分析和风险评估 3-8功能安全方案 4-5 系统层面 5-5 硬件级产品开发 6-5 软件层面 6-6 软件架构安全设计要求 功能监控层安全…

嵌入式面经-ARM体系架构-计算机基础

嵌入式系统分层 操作系统的作用&#xff1a;向下管理硬件&#xff0c;向上提供接口&#xff08;API&#xff09; 应用开发&#xff1a;使用操作系统提供的接口&#xff08;API&#xff09;&#xff0c;做上层的应用程序开发&#xff0c;基本不用去关内核操作硬件是怎么实现的 …

数据库管理-第159期 Oracle Vector DB AI-10(20240311)

数据库管理159期 2024-03-11 数据库管理-第159期 Oracle Vector DB & AI-10&#xff08;20240311&#xff09;1 其他distance函数2 实例演示使用其他函数寻找最近向量点函数变体简写语法 总结 数据库管理-第159期 Oracle Vector DB & AI-10&#xff08;20240311&#x…

02 THU大模型之 Neural Network

1 Neural Network 1.1 Neural Network Components Simple Neuron单个神经元 A neuron is a computational unit with n inputs and 1 output and parameters W(权重) , b 具体来说, 输入向量( Xi )和权重向量( Wi )进行点乘得到标量值, 标量值加上偏置值b后送入激活函数acti…

【机器学习】科学库使用第1篇:机器学习(常用科学计算库的使用)基础定位、目标【附代码文档】

机器学习&#xff08;科学计算库&#xff09;完整教程&#xff08;附代码资料&#xff09;主要内容讲述&#xff1a;机器学习&#xff08;常用科学计算库的使用&#xff09;基础定位、目标&#xff0c;机器学习概述&#xff0c;1.1 人工智能概述&#xff0c;1.2 人工智能发展历…

HCIA-Datacom题库(自己整理分类的)_54_聚合判断【8道题】

1.路由器的聚合端口可以配置路由器子接口。√ 2.Eth-Trunk 两端的负载分担模式可以不一致。√ 3.链路聚合接口只能作为二层接口。 4.在园区网络中通过使用链路聚合、堆叠技术可以提高网络可靠性。√ 5.园区网可以通过链路聚合和堆叠提高网络可靠性。√ 6.交换机通过堆叠、…

部署ELK日志分析系统

简介 在大型运维环境中&#xff0c;管理员通常面对大量的服务器&#xff0c;对于这些服务器的维护&#xff0c;一个很重要的工作就是查看每台服务器的日志信息&#xff0c;而每天逐台检查的方式显然效率比较低下。传统的方式是通过搭建日志服务器&#xff0c;将所有服务器的日志…

VB编程技术笔记

连续赋值 at:tb:ba 分支语句&#xff1a;

Python 导入Excel三维坐标数据 生成三维曲面地形图(面) 3、线条平滑曲面但有条纹

环境和包: 环境 python:python-3.12.0-amd64包: matplotlib 3.8.2 pandas 2.1.4 openpyxl 3.1.2 scipy 1.12.0 代码: import pandas as pd import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D from scipy.interpolate import griddata im…

C++之对象模型和this 指针,友元,和运算符重载

1&#xff0c;对象模型和this 指针 1.1成员变量和成员函数分开存储 在C中&#xff0c;类内的成员变量和成员函数分开存储 只有非静态成员变量才属于类的对象上 示例&#xff1a; #include<iostream> using namespace std;//成员变量 和 成员函数 分开存储 class Per…

Vue3全家桶 - Vue3 - 【6】组件(注册组件 + 组件通信 + 透传属性和事件 + 插槽 + 单文件CSS + 依赖注入)

组件 一、 注册组件 1.1 ❌ 全局注册 目标文件&#xff1a;main.js&#xff1b;语法&#xff1a;import { createApp } from vue import App from ./App.vue const app createApp(App)// 全局注册 app.component(组件名字, 需要注册组件)app.mount(#app)缺陷&#xff1a; 全…

怎样在CSDN赚点零花钱

请教一下各位大佬&#xff0c;看到你们在CSDN很多都几万粉丝以上&#xff0c;能不能分享一下有什么涨粉的经验&#xff0c;还有怎样转化为额外收益……感谢各位提供宝贵的经验&#xff0c;谢谢……

多目灰度cam手势追踪系统——MegaTrack

一、前言 本文是对Facebook Oculus发布的一篇VR方向&#xff08;手势追踪&#xff09;论文的解读。Oculus是一家做VR的公司&#xff0c;2014年被FaceBook收购了&#xff0c;本次参考的论文就是FaceBook Oculus团队的最新论文。论文2020年7月发表于SIGGRAPH。 因为最终是要给大…

Go语言简介

一.Go语言简介 1.1 优点 自带gc静态编译&#xff0c;编译好后&#xff0c;扔服务器直接运行简单思想&#xff0c;没有继承&#xff0c;多态和类等丰富的库和详细开发文档语法层支持并发&#xff0c;和拥有同步并发的channel类型&#xff0c;使并发开发变得非常方便简洁语法&am…

手机和电脑同步的好用记事本软件有哪些

我常常需要随手记录各种信息&#xff0c;以便随时查阅和使用。比如&#xff0c;在下班路上&#xff0c;我会用手机记录明天要处理的工作事项、购物清单&#xff0c;或是某个突然迸发的创意想法&#xff1b;而在办公室&#xff0c;我则需要在电脑上整理会议纪要、项目计划&#…

[AutoSar]BSW_Com012 CAN TP 模块介绍

目录 关键词平台说明一、知识储备二、缩写对照表三、CAN TP 所在架构位置四、CAN TP 的主要作用五、CAN TP 在 autosar 架构中的基本概念5.1、CAN TP 的处理模式5.2 数据一致性5.3 静态配置 六、功能规范6.1 Services provided to upper layer6.1.1 Initialization and shutdow…

基于cnn的卷机神经网络的项目毕业课题实践应用(毕业选题-深度学习-卷及神经网络)

这些项目可以作为毕业课题选择&#xff0c;共计超过20个&#xff1a; 往期热门项目回顾&#xff1a; 计算机视觉项目大集合 改进的yolo目标检测-测距测速 路径规划算法 图像去雨去雾目标检测测距项目 交通标志识别项目 yolo系列-重磅yolov9界面-最新的yolo 姿态识别…

Mybatis操作sql报错ibatis.binding.BindingException: Parameter ‘empId‘ not found.

你们好&#xff0c;我是金金金。 场景 在使用Mybatis操作sql语句过程当中&#xff0c;更新操作&#xff0c;报错信息如下&#xff1a;Caused by: org.apache.ibatis.binding.BindingException: Parameter ‘empId’ not found. Available parameters are [arg1, arg0, param1, …

PyTorch搭建AlexNet训练集

本次项目是使用AlexNet实现5种花类的识别。 训练集搭建与LeNet大致代码差不多&#xff0c;但是也有许多新的内容和知识点。 1.导包&#xff0c;不必多说。 import torch import torch.nn as nn from torchvision import transforms, datasets, utils import matplotlib as p…