排序2(万字详细版)

一 快速排序

        快速排序是Hoare于1962年提出的⼀种⼆叉树结构的交换排序⽅法,其基本思想为:任取待排序元素 序列中的某元素作为基准值,按照该排序码将待排序集合分割成两⼦序列,左⼦序列中所有元素均⼩ 于基准值,右⼦序列中所有元素均⼤于基准值,然后最左右⼦序列重复该过程,直到所有元素都排列 在相应位置上为⽌。

        快速排序也分为三个常用的,分别是hoare版本,挖坑法,lomuto前后指针。

1.1 hoare版本

        

算法思路 :

1)创建左右指针,确定基准值

2)从右向左找出⽐基准值⼩的数据,从左向右找出⽐基准值⼤的数据,左右指针数据交换,进⼊下次 循环

问题1:为什么跳出循环后right位置的值⼀定不⼤于key?

left > right 时,即right⾛到left的左侧,⽽left扫描过的数据均不⼤于key,因此right此时指

向的数据⼀定不⼤于key。

        

        先看第二个函数,基本思路就是每次找到基准值,然后再左右递归直至出现left>right的情况。

        我们来拿这个数组来试一下。

        首先先让right找到比key小的,就是3,再让left找到比key大的。

        此时left<right,交换就得到下面这个数组了,让left++和right--

        然后right在移动,left再移动。

        

        此时right<left,出循环了,此时让arr[right]和arr[key]位置的值交换一下,此时就找到基准值的位置了。

        然后再返回到另外一个函数中继续执行这个,进行递归调用,每次都是通过这种方法找到每一部分的基准值,进行对它们的调整。

        swap(&arr[left++],&arr[right--]);这个语句中的++和--可以不写吗?答案是不可以,因为如果一个无序数组全是2 2 2 2 的时候,此时left和right都不会移动了,此时就陷入了死循环,还有上面的必须严格大于arr[key]才能交换,否则时间复杂度可能达到o(n的平方)。



        1.2 挖坑法

        

        

思路:

创建左右指针。⾸先从右向左找出⽐基准⼩的数据,找到后⽴即放⼊左边坑中,当前位置变为新

的"坑",然后从左向右找出⽐基准⼤的数据,找到后⽴即放⼊右边坑中,当前位置变为新的"坑",结 束循环后将最开始存储的分界值放⼊当前的"坑"中,返回当前"坑"下标(即分界值下标)。

        

        我们还用这个图来讲解一下吧。

        此时我们先让坑位hole指向left,key的作用是存储开始坑位的值的,首先我们要先让right移动,找到比key小的值。

        

        找到了3比key要小,所以直接让3把原来的坑位给覆盖掉,此时就实现了小的元素在左边了,再让right位置重新生成坑位,然后left开始找到比key大的。

        此时发现没找到就出了循环,然后再让坑位等于key即可,此时把hole返回。

        现在我们有几个问题来解决一下,为什么开始的时候不能让left++呢?

        

        我们可以拿这个例子来看一下,如果直接让left++的话,此时在3的位置就会停下来,此时right和left都指向3那个位置,此时再执行下面的语句的话,此时我们就用3把1给覆盖了,然后hole指向3的位置,此时出去循环又执行了arr[hole]=key这个语句了,此时就出现了问题,发现基准值1的左边有比1大的数,此时就出现了问题,如果不++的话,就没有这个问题了。

        还有第二个问题,为什么left=right也要停止呢?

        还用上面那个,如果left=right还不停止,此时right=-1了,此时让arr[hole]=arr[right],就会出现数组越界了。

        这里的arr[right]和arr[left]为什么都要有=呢,单纯大于或者小于key不行吗?

        答案是不行的,我现在举个简单的例子。

        

        让我们对这一个数组来排序,如果仅仅大于或者小于的话,此时就无法进入到right--和left++那个循环之中,此时整个系统就陷入了死循环了。

1.3 双指针法

        

        这个是通过两个指针来寻找,一个cur去前面探路,找到比基准值小的,找到之后我们要判断这个++prev是否等于cur,如果等于先不交换,因为防止做一些不必要的交换,我们主要就是让小的在基准值前面就行了,cur>right的时候,说明此时已经找完了,此时prev指向的一定是最后一个小于基准值的数据,然后和基准值交换一下就完成了。

        我们来通过下图来讲解一下。

        

        我们现在这个图就可以很好解释++prev为什么不能等于cur了,我们来移动一下。

        这里发现1就符合,但是++prev此时和cur相等,不能交换,如果此时交换,发现2也要交换,此时效率就会很低,如果是一个降序的,那么此时时间复杂度就会达到o(n的平方)了,效率很低,所以我们要限制一下,接下来我们继续移动。

        这时候,我们发现此时大于了基准值了,此时只让cur移动。

        找到下一个比基准值小的,此时++prev!=cur了,此时就要交换了,此时prev还是要执行++,此时就指向了7的位置,直接就把小的换到前面了,大的就去后面了,然后再继续进行这个过程,最后就完成了排序。

        



        二 . 归并排序

        

归并排序算法思想:

        归并排序(MERGE-SORT)是建⽴在归并操作上的⼀种有效的排序算法,该算法是采⽤分治法(Divide and Conquer)的⼀个⾮常典型的应⽤。将已有序的⼦序列合并,得到完全有序的序列;即先使每个

        ⼦序列有序,再使⼦序列段间有序。若将两个有序表合并成⼀个有序表,称为⼆路归并。 归并排序核 ⼼步骤:

        

        这个排序的思想就是通过把一个无序的数组给分解,一直分解到不能再分解,然后再进行比较排序,逐渐合并的过程。

        代码实现:

        

       

        我们先看一下这个过程,一直分解把一个数组分解剩下一个元素,也就是left=right的时候。

        此时我们先看左边,此时分解完成了,此时begin1和end1都指向6,begin2和end2都指向了10的位置,此时我们就要比较6和10的大小进行排序,此时把数据存入到tmp数组中,下面的两个while语句是防止哪个序列中的元素没有完全放入数组中,最后的for循环是吧tmp数组中的内容拷贝给arr数组。

        此时执行完了这次函数栈帧的代码了,此时就会返回到上一层,再执行右边的递归然后把1和7完成了排序,此时返回到上一层函数栈帧了此时begin1就指向了6,end1指向了10,begin2指向了1,end2指向了7,此时就要排这几个的序列了,发现是1 2 7 10的序列,再次返回到上层函数栈帧,再对右边的序列进行递归,循环这个过程最终就会完成了排序了。

        



三 . 非比较排序

        

计数排序

计数排序⼜称为鸽巢原理,是对哈希直接定址法的变形应⽤。 操作步骤:

1)统计相同元素出现次数

2)根据统计的结果将序列回收到原来的序列中

        

        这个就是把相应的数放在他所对应的下标处,让这个下标++,表示数的数量,然后再对它进行打印。

        但是现在又有了一个问题,如果我们的数是{100 , 101 , 110}类似于这样的数据,我们说的是要把它们放在对应的下标下面,但是这个难道要创建到下标为110的吗,如果这样的话,前面的100个位置不久荒废了吗,造成了极大的空间浪费,我们应该怎么解决呢?

        我来提出一个想法,我们只开辟max-min+1个空间大小的数组即可,让第0个位置存放min的位置,中间存放中间数据,max-min+1的位置存放最大的那个数据即可,此时我们上面那个数组只需要开辟110-100+1个位置即可,此时0的位置可以放100,1的位置放101,以此类推最后一个10的位置就放110了,我们只需要开辟11个空间,极大的节约了空间。

        这样我们就完成了代码的编写了,我们首先要找到最大值和最小值,为count数组分配指定的空间,然后再次遍历我们的数组,让其值所在的对应位置++,统计每个值的数量,此时我们就完成了100放在0处,110放在10处了,统计完成数量之后,我们再次进入循环,此时i要小于range,此时我们要遍历count数组了,此时较小的值就放在的下标比较小的位置了,此时我们再次通过一个while循环,把它们的值放入我们的arr数组中,此时它们的值正好就是等于i+min的值的,此时通过while循环控制放入的数量,此时就完成了排序。

        


四. 算法时间效率的比较

        

void TestOP()
{
    srand(time(0));
    const int N = 100000;
    int* a1 = (int*)malloc(sizeof(int) * N);
    int* a2 = (int*)malloc(sizeof(int) * N);
    int* a3 = (int*)malloc(sizeof(int) * N);
    int* a4 = (int*)malloc(sizeof(int) * N);
    int* a5 = (int*)malloc(sizeof(int) * N);
    int* a6 = (int*)malloc(sizeof(int) * N);
    int* a7 = (int*)malloc(sizeof(int) * N);
    int* a8 = (int*)malloc(sizeof(int)* N);
    int* a9 =(int*)malloc(sizeof(int)*N);
    int* a10=(int*)malloc(sizeof(int)*N);
    for (int i = 0; i < N; ++i)
    {
        a1[i] = rand();
        a2[i] = a1[i];
        a3[i] = a1[i];
        a4[i] = a1[i];
        a5[i] = a1[i];
        a6[i] = a1[i];
        a7[i] = a1[i];
        a8[i] =  a1[i];
        a9[i]=a1[i];
    }
    int begin1 = clock();
    InsertSort(a1, N);
    int end1 = clock();

    int begin2 = clock();
    ShellSort(a2, N);
    int end2 = clock();
    int begin3 = clock();
    SeclectSort(a3, N);
    int end3 = clock();
    int begin4 = clock();
    HeapSort(a4, N);
    int end4 = clock();

    int begin5 = clock();
    QuickSort(a5, 0, N-1);
    int end5 = clock();
    int begin6 = clock();
    MergeSort(a6, N);
    int end6 = clock();
    int begin7 = clock();
    BubbleSort(a7, N);
    int end7 = clock();
    int begin8=clock();
    QuickSort2(a8,0,N-1);
    int end8=clock();
    int begin9=clock();
    QuickSort3(a9,0,N-1);
    int end9=clock();
    int begin10=clock();
    CountSort(a10   ,N);
    int end10=clock();
    printf("InsertSort:%d ms\n", end1 - begin1);
    printf("ShellSort:%d ms\n", end2 - begin2);
    printf("SelectSort:%d ms\n", end3 - begin3);
    printf("HeapSort:%d ms\n", end4 - begin4);
    printf("horeQuickSort:%d ms\n", end5 - begin5);
    printf("MergeSort:%d ms\n", end6 - begin6);
    printf("BubbleSort:%d ms\n", end7 - begin7);
    printf("wa keng QuickSort:%d ms\n", end8 - begin8);
    printf("QucickSort3:%d ms\n", end9 - begin9);
    printf("CountSort:%d ms\n", end10 - begin10);
    free(a1);
    free(a2);
    free(a3);
    free(a4);
    free(a5);
    free(a6);
    free(a7);
    free(a8);
    free(a9);
    free(a10);
}

        代码太长了,我就不截图了,此时我们可以用这个代码可以清晰的看到算法时间效率的差异

        

        如图所示,发现同时处理100000条数据的时候希尔排序,堆排序,三种快排和归并排序和非比较排序的效率是比较高的。

        

        五.源代码

        

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
//╤яеепР
void swap(int* a,int* b){
    int temp=*a;
    *a=*b;
    *b=temp;
}
void AdjustDown(int* arr,int parent,int n){
    int child=parent*2+1;
    while(child<n){
        if(child+1<n&&arr[child]<arr[child+1]){
            child++;
        }
        if(arr[parent]<arr[child]){
            swap(&arr[parent],&arr[child]);
            parent=child;
            child=parent*2+1;
        }
        else{
            break;
        }
    }
}
void HeapSort(int* arr,int n){
    for(int i=(n-1-1)/2;i>=0;i--){
        AdjustDown(arr,i,n);
    }
    int end=n-1;
    while(end>0){
        swap(&arr[0],&arr[end]);
        AdjustDown(arr,0,end);
        end--;
    }
}
void InsertSort(int* arr,int n){
    for(int i=0;i<n-1;i++){
        int end=i;
        int tmp=arr[end+1];
        while(end>=0){
            if(arr[end]>tmp){
                arr[end+1]=arr[end];
                end--;
            }
            else{
                break;
            }
        }
        arr[end+1]=tmp;
    }
}
//оё╤ШеепР
void ShellSort(int* arr, int n){
    int gap=n;
    while(gap>1){
        gap=gap/3+1;
        for(int i=0;i<n-gap;i++){
            int end=i;
            int tmp=arr[end+gap];
            while(end>=0){
                if(arr[end]>tmp){
                    arr[end+gap]=arr[end];
                    end-=gap;
                }
                else{
                    break;
                }
            }
            arr[end+gap]=tmp;
        }
    }
    }
void BubbleSort(int* arr,int n){
    for (int i = 0; i < n - 1; i++) {
    for (int j = 0; j < n - i - 1; j++) {
        if (arr[j] > arr[j + 1]) {
            int temp = arr[j];
            arr[j] = arr[j + 1];
            arr[j + 1] = temp;
        }
    }
}
}
void SeclectSort(int* arr,int n){
    int begin=0,end=n-1;
    while(begin<end){
        int min=begin,max=begin;
        for(int i=begin+1;i<=end;i++){
            if(arr[min]>arr[i]){
                min=i;
            }
            if(arr[max]<arr[i]){
                max=i;
            }
        }
        if(max==begin){
            max=min;
        }
        swap(&arr[min],&arr[begin]);
        swap(&arr[max],&arr[end]);
        begin++;
        end--;
    }
}
//双指针法快排
int _QuickSort3(int* arr,int left,int right){
    int prev=left,cur=left+1;
    int key=left;
    while(cur<=right){
        if(arr[cur]<arr[key]&&++prev!=cur){
            swap(&arr[prev],&arr[cur]);
        }
        ++cur;
    }
    swap(&arr[prev],&arr[key]);
    return prev;
}
void QuickSort3(int* arr,int left,int right){
    if(left>right){
        return;
    }
    int key=_QuickSort3(arr,left,right);
    QuickSort3(arr,left,key-1);
    QuickSort3(arr,key+1,right);
}
//挖坑法
int _QuickSort2(int* arr, int left, int right)
{
    int hole = left;
    int key = arr[hole];
    //left++;

    while (left < right)
    {
        while (left < right && arr[right] >= key)
        {
            right--;
        }
        arr[hole] = arr[right];
        hole = right;
        while (left < right && arr[left] <= key)
        {
            left++;
        }
        arr[hole] = arr[left];
        hole = left;
    }
    arr[hole] = key;
    return hole;
}
void QuickSort2(int* arr,int left,int right){
    if(left>=right){
        return;
    }
    int key=_QuickSort2(arr,left,right);
    QuickSort2(arr,left,key-1);
    QuickSort2(arr,key+1,right);
}
//霍尔快排
int _QuickSort(int* arr, int left, int right)
{
    int key=left;
    ++left;
    while(left<=right){
        while(left<=right&&arr[right]>arr[key]){
            right--;
        }
        while(left<=right&&arr[left]<arr[key]){
            left++;
        }
        if(left<=right){
            swap(&arr[left++],&arr[right--]);
        }
    }
    swap(&arr[right],&arr[key]);
    return right;
}

//快速排序
void QuickSort(int* arr, int left, int right)
{
    if(left>=right){
        return;
    }
    int key=_QuickSort(arr,left,right);
    QuickSort(arr,left,key-1);
    QuickSort(arr,key+1,right);
}
//归并排序
void _MergeSort(int* arr, int left, int right,int* tmp)
{
    if (left >= right)
    {
        return;
    }
    int mid = (left + right) / 2;
    //根据mid划分成两个序列:[left,mid] [mid+1,right]
    _MergeSort(arr, left, mid,tmp);
    _MergeSort(arr, mid + 1, right,tmp);

    //合并[left,mid] [mid+1,right]
    int begin1 = left, end1 = mid;
    int begin2 = mid + 1, end2 = right;
    int index = begin1;
    while (begin1 <= end1 && begin2 <= end2)
    {
        if (arr[begin1] < arr[begin2])
        {
            tmp[index++] = arr[begin1++];
        }
        else {
            tmp[index++] = arr[begin2++];
        }
    }
    //可能存在第一个序列中的数据没有全部放到tmp中
    //可能存在第二个序列中的数据没有全部放到tmp中
    while (begin1 <= end1)
    {
        tmp[index++] = arr[begin1++];
    }
    while (begin2 <= end2)
    {
        tmp[index++] = arr[begin2++];
    }
    //将tmp中数据挪回到arr中
    for (int i = left; i <= right; i++)
    {
        arr[i] = tmp[i];
    }
}
//归并排序
void MergeSort(int* a, int n)
{
    int* tmp = (int*)malloc(sizeof(int) * n);
    _MergeSort(a, 0, n - 1, tmp);
    free(tmp);
}
//非比较排序
void CountSort(int* arr,int n){
    int max=0,min=0;
    for(int i=0;i<n;i++){
        if(max<arr[i]){
            max=arr[i];
        }
        if(min>arr[i]){
            min=arr[i];
        }
    }
    int range=max-min+1;
    int* count=(int*)calloc(range,sizeof(int));
    for(int i=0;i<n;i++){
        count[arr[i]-min]++;
    }
    int index=0;
    for(int i=0;i<range;i++){
        while(count[i]--){
            arr[index++]=i+min;
        }
    }
}
void printf1(int* arr,int n){
    for(int i=0;i<n;i++){
        printf("%d ",arr[i]);
    }
}
void TestOP()
{
    srand(time(0));
    const int N = 100000;
    int* a1 = (int*)malloc(sizeof(int) * N);
    int* a2 = (int*)malloc(sizeof(int) * N);
    int* a3 = (int*)malloc(sizeof(int) * N);
    int* a4 = (int*)malloc(sizeof(int) * N);
    int* a5 = (int*)malloc(sizeof(int) * N);
    int* a6 = (int*)malloc(sizeof(int) * N);
    int* a7 = (int*)malloc(sizeof(int) * N);
    int* a8 = (int*)malloc(sizeof(int)* N);
    int* a9 =(int*)malloc(sizeof(int)*N);
    int* a10=(int*)malloc(sizeof(int)*N);
    for (int i = 0; i < N; ++i)
    {
        a1[i] = rand();
        a2[i] = a1[i];
        a3[i] = a1[i];
        a4[i] = a1[i];
        a5[i] = a1[i];
        a6[i] = a1[i];
        a7[i] = a1[i];
        a8[i] =  a1[i];
        a9[i]=a1[i];
    }
    int begin1 = clock();
    InsertSort(a1, N);
    int end1 = clock();

    int begin2 = clock();
    ShellSort(a2, N);
    int end2 = clock();
    int begin3 = clock();
    SeclectSort(a3, N);
    int end3 = clock();
    int begin4 = clock();
    HeapSort(a4, N);
    int end4 = clock();

    int begin5 = clock();
    QuickSort(a5, 0, N-1);
    int end5 = clock();
    int begin6 = clock();
    MergeSort(a6, N);
    int end6 = clock();
    int begin7 = clock();
    BubbleSort(a7, N);
    int end7 = clock();
    int begin8=clock();
    QuickSort2(a8,0,N-1);
    int end8=clock();
    int begin9=clock();
    QuickSort3(a9,0,N-1);
    int end9=clock();
    int begin10=clock();
    CountSort(a10   ,N);
    int end10=clock();
    printf("InsertSort:%d ms\n", end1 - begin1);
    printf("ShellSort:%d ms\n", end2 - begin2);
    printf("SelectSort:%d ms\n", end3 - begin3);
    printf("HeapSort:%d ms\n", end4 - begin4);
    printf("horeQuickSort:%d ms\n", end5 - begin5);
    printf("MergeSort:%d ms\n", end6 - begin6);
    printf("BubbleSort:%d ms\n", end7 - begin7);
    printf("wa keng QuickSort:%d ms\n", end8 - begin8);
    printf("QucickSort3:%d ms\n", end9 - begin9);
    printf("CountSort:%d ms\n", end10 - begin10);
    free(a1);
    free(a2);
    free(a3);
    free(a4);
    free(a5);
    free(a6);
    free(a7);
    free(a8);
    free(a9);
    free(a10);
}

int main(){
    /*int arr[6];
    for(int i=0;i<6;i++){
        scanf("%d",&arr[i]);
    }
    int n=sizeof(arr)/sizeof(arr[0]);
    CountSort(arr,n);*/
    //InsertSort(arr,n);
    //HeapSort(arr,n);
    //ShellSort(arr,n);
    //BubbleSort(arr,n);
    //SeclectSort(arr,n);
    //QuickSort2(arr,0,n-1);
    //MergeSort(arr,n);*/
    //printf1(arr,n);
    TestOP();
}
 

六. 结束语

         感谢大家的查看,希望可以帮助到大家,做的不是太好还请见谅,其中有什么不懂的可以留言询问,我都会一一回答。  感谢大家的一键三连。

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

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

相关文章

[ACTF2020 新生赛]Include

感觉毫无头绪e一下&#xff0c;发现要使用伪协议 伪协议&#xff1a;是PHP自己支持的一种协议与封装协议&#xff0c;简单说就是PHP定义的一种特殊访问资源的方法。 2.什么时候用PHP伪协议? 可能遇到的文件包含函数&#xff1a; 1、include 2、require 3、include_once 4、r…

链表【Lecode_HOT100】

1.相交链表No.160 public ListNode getIntersectionNode(ListNode headA, ListNode headB) {if(headAnull||headBnull) return null;ListNode pAheadA;ListNode pBheadB;while(pA!pB){pA(pAnull)?headB:pA.next;pB(pBnull)?headA:pB.next;}return pA; }2.反转链表No.206 pu…

时频转换 | Matlab格拉姆角和场Gramian angular summation field一维数据转二维图像方法

目录 基本介绍程序设计参考资料获取方式 基本介绍 时频转换 | Matlab格拉姆角和场Gramian angular summation field一维数据转二维图像方法 程序设计 clear clc % close all load x.mat % 导入数据 x x(1:5120); % 本数据只选择5120个点进行分析 fs 6400 ; % 数据采样频…

试题转excel;pdf转excel;试卷转Excel,word试题转excel

一、问题描述 一名教师朋友&#xff0c;偶尔会需要整理一些高质量的题目到excel中 以往都是手动复制搬运&#xff0c;几百道题几乎需要一个下午的时间 关键这些事&#xff0c;枯燥无聊费眼睛&#xff0c;实在是看起来就很蠢的工作 就想着做一个工具&#xff0c;可以自动处理…

借助vector实现进制转换详解

进制转换&#xff0c;没什么可说的&#xff0c;大一级别的水平&#xff0c;不过在某些考研题目中可能会涉及到顺序栈的实现&#xff0c;本贴不使用顺序栈&#xff0c;用STL里面的vector模拟一下&#xff1a;关键在于想清楚【除留取余】的逻辑&#xff0c;至于用什么结构存放中间…

快速构建NLP理论知识体系

NLP理论知识体系 一句话解释NLPNLP模型及原理简述1、Rag 一句话解释NLP 如果我们要实现机器翻译、情感分析、问答系统、文本摘要、聊天机器人、构造智能化的辅助文件填写模板&#xff0c;NLP可以通过现成的模型对输入的语音、文字、图片进行处理&#xff08;分词、标词性、去停…

iptables防火墙(DNAT、SNAT)小实验

这篇是iptables服务器当中DNAT、SNAT的部分 网络拓扑图&#xff1a; 实验要求&#xff1a; 实现内外网web互访问将内web的网关指向iptables服务器ens33的IPiptables服务器添加两块网卡&#xff0c;外web服务器要跟iptables的ens36同一块网卡内部web&#xff1a;192.168.180.1…

Oracle ASM特性介绍和增删盘操作

1. 介绍 1.1. 在没有ASM之前ORACLE数据库靠什么去解决存储问题&#xff1a; 裸设备:裸设备就是没有被文件系统格式化的分区或者是直接挂载到操作系统上的磁盘。ORACLE可以直接将数据写入到裸设备中&#xff0c;读写能非常优异。像ORACLE的数据文件、控制文件、REDO日志在过去…

UiPath API接口说明

Swagger网址 私有云网址&#xff08;企业版&#xff09; https://企业/swagger/index.html 公有云网址&#xff08;社区版&#xff09; https://cloud.uipath.com/linan/LinanZhang/orchestrator_/swagger/index.html#/ 常见问题 Swagger页面测试请求时报错“You are not a…

【机械加工】数字化软件打造,如何实现3D交互可视化?

机械加工是制造业的重要领域之一&#xff0c;随着制造技术和工艺的不断发展&#xff0c;机械加工的精度和效率要求越来越高。HOOPS作为一款专业的3D图形引擎&#xff0c;可以为机械加工行业提供高效、灵活的3D建模、可视化和交互工具。下面将从以下几个方面介绍HOOPS技术在机械…

CAMAv2: A Vision-Centric Approach for Static Map Element Annotation

CAMAv2: 摘要简介相关工作A. 视觉为中心的地图构建&#xff08;Vision-centric HD Map Construction&#xff09;B. 地图元素数据集&#xff08;Map Element Datasets&#xff09;1. nuScenes 数据集2. Argoverse2 数据集3. 车道线数据集 CAMAv2A. 场景重建&#xff08;Scene R…

大数据新视界 -- 大数据大厂之 Hive 临时表与视图:灵活数据处理的技巧(上)(29 / 30)

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

Python批量生成个性化Word录用通知书

你是一名人力资源部门的员工&#xff0c;你需要根据一份Excel表格中的员工信息&#xff0c;为每位员工生成一份录用通知书。 Excel表格中包含了员工的姓名、性别、职位、入职日期等信息&#xff0c;你需要将这些信息填充到Word模板中&#xff0c;并生成独立的录用通知书文件。…

Android显示系统(05)- OpenGL ES - Shader绘制三角形(使用glsl文件)

一、前言&#xff1a; 上一篇文章我们使用了Shader绘制了一个基本的三角形&#xff0c;但是&#xff0c;发现那样写Shader程序特别麻烦&#xff0c;各种加双引号&#xff0c;还没有语法高亮提示。因为glsl也和java、c一样是一门语言&#xff0c;实际工程项目都是单独的glsl文件…

Linux显卡驱动安装

前言 使用Windows配置环境失败&#xff0c;其中有一个包只有Linux版本&#xff0c;Windows版本的只有python3.10的&#xff0c;所以直接选用Linux来配置环境&#xff0c;显卡安装比较麻烦&#xff0c;单独出一期。 显卡驱动安装 参考文章&#xff1a;Ubuntu显卡驱动安装和这…

【Linux】进程控制

目录 一、进程创建1.1 fork函数1.2 fork函数返回值1.3 写时拷贝1.4 fork常规用法1.5 fork调用失败的原因1.6 使用fork创建多进程 二、进程退出2.1 进程退出场景2.1.1 进程运行完毕2.1.2 代码异常终止2.1.3 小结 2.2 进程常见退出方法2.2.1 return2.2.2 调用exit函数2.2.3 调用_…

smart-doc 使用

文档地址 添加插件 <plugin><groupId>com.ly.smart-doc</groupId><artifactId>smart-doc-maven-plugin</artifactId><version>3.0.9</version><configuration><includes><!--格式为&#xff1a;groupId:artifactId;…

Spring04——注解开发

Spring3.0启用了纯注解开发模式&#xff0c;使用Java类替代配置文件&#xff0c;开启了Spring快速开发赛道 Java类代替Spring核心配置文件&#xff0c; 配置类&#xff08;Configuration&#xff09; Configuration注解用于设定当前类为配置类ComponentScan注解用于设定扫描路…

ImportError: cannot import name ‘implements‘ from ‘zope.interface‘

ImportError: cannot import name ‘implements’ from ‘zope.interface’ 1. 问题分析 问题原因&#xff1a; /home/user/.conda/envs/vectornet/lib/python3.8/site-packages/apex/interfaces.py中在使用zope.interace中使用了老表达。 2. 解决办法 原文件内容&#xff…

多线程的操作

1、Thread类 1.1 Thread类的作用 上篇博文中我们了解了线程与操作系统的关系&#xff1a;线程是操作系统中的概念&#xff0c;操作系统内核实现了线程这样的机制, 并且对用户层提供了一些 API 供用户使用&#xff0c;Java 标准库中 Thread 类可以视为是对操作系统提供的 API 进…