【数据结构】六种排序实现方法及区分比较

文章目录

  • 前言
  • 插入排序
  • 希尔排序
  • 选择排序
  • 堆排序
  • 快速排序
  • 冒泡排序
  • 总结


前言

众所周知,存在许多种排序方法,作为新手,最新接触到的就是冒泡排序,这种排序方法具有较好的教学意义,但是实用意义不高,原因就在于它的时间复杂度太高了,为 O(n^2) 即便后来我们使用 flag 去优化它,也不过也不过少了一点,如果序列完全倒序,就没什么用。

所以为了使代码运行效率更高,人们就设计了许多种排序方法,这里笔者将比较常用的六种进行介绍,并对其的一些使用情景及效率进行一下比较。

默认实现时都为升序

  • 插入排序
  • 希尔排序
  • 选择排序
  • 堆排序
  • 冒泡排序
  • 快速排序

为了等下便于比较我们可以建立多个存有相同大小的数组,利用 c l o c k ( ) clock() clock() 来记录排序十万或一百万数据所需的时间,这样就可以直观地比较了,代码如下

void TestOP()
{srand((unsigned)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);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];}int begin1 = clock();InsertSort(a1, N);int end1 = clock();int begin2 = clock();//ShellSort(a2, N);int end2 = clock();int begin3 = clock();//SelectSort(a3, N);int end3 = clock();int begin4 = clock();//HeapSort(a4, N);int end4 = clock();int begin5 = clock();//QuickSort(a5, N);int end5 = clock();int begin6 = clock();//BubbleSort(a6, N);int end6 = clock();printf("InsertSort:%d\n", end1 - begin1);printf("ShellSort:%d\n", end2 - begin2);printf("SelectSort:%d\n", end3 - begin3);printf("HeapSort:%d\n", end4 - begin4);printf("QuickSort:%d\n", end5 - begin5);printf("BubbleSort:%d\n", end6 - begin6);free(a1);free(a2);free(a3);free(a4);free(a5);free(a6);
}

插入排序

插入排序的平均时间复杂度为 O ( n 2 ) O(n^2) O(n2),最坏情况下的时间复杂度也为 O ( n 2 ) O(n^2) O(n2)

关于希尔排序的时间复杂度,是很难计算的。要准确计算希尔排序的时间复杂度,需要考虑具体的增量序列和数据分布情况。不同的增量序列可能会导致不同的时间复杂度。

需要注意的是,这些时间复杂度估计是基于理论分析和实验结果得出的,但实际情况可能会有所不同。在实际应用中,希尔排序的性能还会受到硬件、数据特点等因素的影响。

插入排序的思想就是把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列。

在这里插入图片描述

在插入排序的过程中,每次插入一个元素时,都需要在已经有序的序列中找到合适的位置插入该元素。这个过程需要进行比较和移动操作,因此插入排序的时间复杂度主要取决于比较和移动操作的次数。

具体思路:

  1. 从左往右插入排序
  2. 建立临时变量 e n d end end标志当前的有序末尾
  3. 不断将 e n d + 1 end+1 end+1的值插入到有序序列中
//插入排序,升序
// 时间复杂度:O(N^2)  什么情况最坏:逆序
// 最好:顺序有序,O(N)
void InsertSort(int* a, int n)
{for (int i = 0; i < n - 1; i++){int end = i;int tmp = a[end + 1];while (end >= 0){if (tmp < a[end]){a[end + 1] = a[end];end--;}elsebreak;}a[end + 1] = tmp;}
}

我们尝试排序一下十万个数据,用时3点多秒,还算可以
在这里插入图片描述

但是当我们把数据改成一百万个时,笔者等了两分多种都没出结果,可见这个插入排序的漏洞还是很大的


希尔排序

希尔排序(Shell Sort)是插入排序的一种。也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。

希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至 1 时,整个文件恰被分成一组,算法便终止。

希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。

在这里插入图片描述

希尔排序的具体步骤如下:

  1. 选择一个增量序列 t1,t2,…,tk,其中 ti > tj, tk = 1;
  2. 按增量序列个数 k,对序列进行 k 趟排序;
  3. 每趟排序,根据对应的增量 ti,将待排序列分割成若干长度为 m 的子序列,分别对各子表进行直接插入排序。仅增量因子为 1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。

希尔排序的时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn),空间复杂度为 O ( 1 ) O(1) O(1)。希尔排序是一种不稳定的排序算法。

//希尔排序
void ShellSort(int* a, int n)
{int gap = n;while (gap > 1){gap = gap / 3 + 1;for (size_t i = 0; i < n - gap; i++){int end = i;int tmp = a[end + gap];while (end >= 0){if (a[end] > tmp){a[end + gap] = a[end];end -= gap;}else{break;}a[end + gap] = tmp;}}}
}

如果比较难理解可以看下图,假设我们当前是 g a p = 3 gap = 3 gap=3,就相当于每三个元素提取出来一个放进一个数组里,这样的数组有3个
在这里插入图片描述

之后在对这三个元素分别进行插入排序,这样的好处是分担了大量元素一次排序的性能,并且在多次这样预排序后会整个数组都趋近于有序,这样一来,越后面的排序基本就不需要交换了,性能也就更高。

可以直观感受一下对十万个数据两者的差距
在这里插入图片描述
即便改成了排序一百万个数据,也只消耗了0.2秒。
在这里插入图片描述


选择排序

选择排序(Selection Sort)是一种简单直观的排序算法。它首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

选择排序的基本思想是:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

在这里插入图片描述

选择排序的具体步骤如下:

  1. 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置;
  2. 然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾;
  3. 以此类推,直到所有元素均排序完毕。

选择排序的时间复杂度为 O ( n 2 ) O(n^2) O(n2),空间复杂度为 O ( 1 ) O(1) O(1)。选择排序是一种不稳定的排序算法。

//选择排序
void SelectSort(int* a, int n)
{int begin = 0;int end = n - 1;while (begin < end){int mini = begin;int maxi = begin;for (size_t i = begin + 1; i < end; i++){if (a[i] < a[mini])mini = i;if (a[i] > a[maxi])maxi = i;}Swap(&a[mini], &a[begin]);if (begin == maxi)maxi = mini;Swap(&a[maxi], &a[end]);begin++;end--;}
}

但是这种算法的时间复杂度还是太高,要比较和交换的次数太多了,相比于冒泡排序,这种甚至连教学意义都没有,仅仅需要了解一下其中的思想就行了,一般代码中都不会用这种排序。
在这里插入图片描述


堆排序

堆排序(Heap Sort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

堆排序的基本思想是:将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余 n-1 个元素重新构造成一个堆,这样会得到 n 个元素的次小值。如此反复执行,便能得到一个有序序列了。

在这里插入图片描述

堆排序的具体步骤如下:

  1. 构建初始堆:将待排序序列构造成一个大顶堆;
  2. 交换堆顶元素和末尾元素:将堆顶元素与末尾元素进行交换;
  3. 调整堆结构:对交换后的堆进行调整,使其重新成为一个大顶堆;
  4. 重复步骤 2 和 3,直到整个序列有序。

堆排序的时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn),空间复杂度为 O ( 1 ) O(1) O(1)。堆排序是一种不稳定的排序算法。

建堆的过程可以通过从最后一个非叶子节点开始,逐步向上调整堆的结构来实现。这个过程的时间复杂度为 O ( n ) O(n) O(n),其中 n n n是待排序元素的数量。

排序的过程是通过不断地将堆顶元素与末尾元素交换,并调整堆结构来实现的。每次交换和调整堆结构的时间复杂度为 O ( l o g n ) O(logn) O(logn),因为堆的高度为 l o g n logn logn

因此,堆排序的总时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)

代码实现如下

//堆排序
void AdjustDown(int* a, int parent, int n)
{//建大堆int child = parent * 2 + 1;while (child < n){if (child + 1 < n && a[child + 1] > a[child])child++;if (a[parent] < a[child]){Swap(&a[parent], &a[child]);parent = child;child = parent * 2 + 1;}else{break;}}
}void HeapSort(int* a, int n)
{//建大堆 O(n^2)for (int i = (n - 1 - 1) / 2 ; i > 0; i--){AdjustDown(a, i, n);}int end = n - 1;//O(logn)while (end > 0){Swap(&a[end], &a[0]);AdjustDown(a, 0, end);end--;}
}

在十万个数据下,它进行的也是比较快的

在这里插入图片描述

更改为1000万个数据后,堆排序的性能还是可以的,仅次于希尔排序

在这里插入图片描述


快速排序

快速排序(Quick Sort)是一种常用的排序算法。它的平均时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn),空间复杂度为 O ( l o g n ) O(logn) O(logn)。快速排序的基本思想是通过选择一个基准元素,将数组分为两部分,使得左边的元素都小于等于基准元素,右边的元素都大于等于基准元素。然后,对左右两部分分别进行快速排序,直到整个数组有序。

快速排序的时间复杂度主要取决于划分的过程。

在快速排序中,每次选择一个基准元素,将数组分为两部分,使得左边的元素都小于等于基准元素,右边的元素都大于等于基准元素。这个过程的时间复杂度为 O ( n ) O(n) O(n),其中 n n n是数组的长度。

然后,对左右两部分分别进行快速排序,这个过程的时间复杂度也为 O ( n ) O(n) O(n)

因此,快速排序的总时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)

需要注意的是,这是快速排序的平均时间复杂度。在最坏情况下,快速排序的时间复杂度可能会达到 O ( n 2 ) O(n^2) O(n2),例如当数组已经有序时。但是,在大多数情况下,快速排序的时间复杂度都非常接近 O ( n l o g n ) O(nlogn) O(nlogn)

在这里插入图片描述

快速排序的具体步骤如下:

  1. 选择一个基准元素,可以选择数组的第一个元素、最后一个元素或中间元素等。
  2. 将数组分为两部分,使得左边的元素都小于等于基准元素,右边的元素都大于等于基准元素。可以通过交换元素的位置来实现。
  3. 对左右两部分分别进行快速排序,直到整个数组有序。

快速排序的优点是平均时间复杂度较低,空间复杂度也较低,而且实现简单。但是,快速排序在最坏情况下的时间复杂度为 O ( n 2 ) O(n^2) O(n2),当数组已经有序或接近有序时,快速排序的性能会下降。为了避免这种情况,可以选择随机选择基准元素或使用其他改进的快速排序算法。

void QuickSort(int* a, int left, int right)
{if (left >= right){return NULL;}int ret = left;int begin = left;int end = right;while (begin < end){while (end > begin && a[end] >= a[ret])end--;while (end > begin && a[begin] <= a[ret])begin++;Swap(&a[end], &a[begin]);}Swap(&a[begin], &a[ret]);QuickSort(a, left, begin - 1);QuickSort(a, begin + 1, right);
}

在这里插入图片描述

这里利用递归的方法不断对左右两边进行排序,直至有序

但是我们可以发现上述过程还是可以优化的

  1. 当数组元素小于10个时,用插入排序(注意插入排序的起始位置)
  2. 每次都是那最左边的元素作为基准元素,在整个数组趋于有序时定然左少右多,找左右中元素中间的那个值作为基准元素更有效
//快速排序
int midi(int* a, int left, int right)
{int mid = (left + right) / 2;if (a[mid] > a[left]){if (a[mid] < a[right])return mid;else{if (a[left] > a[right])return left;elsereturn right;}}else{if (a[mid] > a[right])return mid;else{if (a[left] < a[right])return left;elsereturn right;}}
}
void QuickSort(int* a, int left, int right)
{if (left >= right){return NULL;}if ((right - left + 1) < 10){InsertSort(a+left, right - left + 1);//加上left,从第left个元素开始}else{int mid = midi(a, left, right);Swap(&a[mid], &a[left]);int ret = left;int begin = left;int end = right;while (begin < end){while (end > begin && a[end] >= a[ret])end--;while (end > begin && a[begin] <= a[ret])begin++;Swap(&a[end], &a[begin]);}Swap(&a[begin], &a[ret]);QuickSort(a, left, begin - 1);QuickSort(a, begin + 1, right);}
}

冒泡排序

冒泡排序(Bubble Sort)是一种简单的排序算法。它重复地走访要排序的数列,一次比较两个数据元素,如果顺序不对则进行交换,并一直重复这样的走访操作,直到没有要交换的数据元素为止。

冒泡排序的基本思想是:通过相邻元素之间的比较和交换,将最大的元素逐步“冒泡”到数列的末尾。具体来说,冒泡排序的每一轮都会比较相邻的两个元素,如果它们的顺序错误,就将它们交换位置。这样,每一轮都会将一个最大的元素“冒泡”到数列的末尾。经过若干轮比较和交换后,整个数列就会变得有序。

在这里插入图片描述

冒泡排序的时间复杂度为 O ( n 2 ) O(n^2) O(n2),空间复杂度为 O ( 1 ) O(1) O(1)。它是一种稳定的排序算法,即相同元素的相对顺序在排序前后不会改变。

冒泡排序的优点是实现简单,容易理解。缺点是效率较低,对于大规模数据的排序不太适用。在实际应用中,冒泡排序通常用于对小规模数据进行排序,或者作为其他排序算法的辅助步骤。

void BubbleSort(int* a, int n)
{for (size_t i = 0; i < n - 1; i++){int flag = 0;for (size_t j = 0; j < n - 1 - i; j++){if (a[j] > a[j + 1])Swap(&a[j], &a[j + 1]);flag = 1;}if (flag == 0)break;}
}

排序一万个数据就可以看到冒泡与别的排序方法的差距

在这里插入图片描述
笔者尝试排序十万个,可是冒泡排序等了2分钟都没出结果就不管它了,别的排序算法比较如下
在这里插入图片描述


总结

以下是对插入排序、希尔排序、选择排序、堆排序、快速排序和冒泡排序的比较分析总结:

  1. 插入排序

    • 基本思想:将未排序元素逐个插入已排序序列的合适位置。
    • 时间复杂度:平均情况和最坏情况均为 O ( n 2 ) O(n^2) O(n2)
    • 空间复杂度: O ( 1 ) O(1) O(1)
    • 稳定性:稳定。
    • 优点:简单直观,适用于小规模数据。
    • 缺点:效率较低。
  2. 希尔排序

    • 基本思想:通过将数组分成较小的子数组,并对每个子数组进行插入排序来改进插入排序。
    • 时间复杂度:取决于增量序列的选择,平均情况和最坏情况的时间复杂度较为复杂。
    • 空间复杂度: O ( 1 ) O(1) O(1)
    • 稳定性:不稳定。
    • 优点:在某些情况下比插入排序更快。
    • 缺点:增量序列的选择对性能影响较大。
  3. 选择排序

    • 基本思想:在未排序序列中找到最小元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
    • 时间复杂度:平均情况和最坏情况均为 O ( n 2 ) O(n^2) O(n2)
    • 空间复杂度: O ( 1 ) O(1) O(1)
    • 稳定性:不稳定。
    • 优点:简单直观,交换次数较少。
    • 缺点:效率较低。
  4. 堆排序

    • 基本思想:利用堆这种数据结构来进行排序。堆是一种完全二叉树,其每个节点的值都大于等于(或小于等于)其左右子节点的值。
    • 时间复杂度:平均情况和最坏情况均为 O ( n l o g n ) O(nlogn) O(nlogn)
    • 空间复杂度: O ( 1 ) O(1) O(1)
    • 稳定性:不稳定。
    • 优点:效率较高。
    • 缺点:实现相对复杂。
  5. 快速排序

    • 基本思想:通过选择一个基准元素,将数组分为两部分,使得左边的元素都小于等于基准元素,右边的元素都大于等于基准元素。然后,对左右两部分分别进行快速排序,直到整个数组有序。
    • 时间复杂度:平均情况为 O ( n l o g n ) O(nlogn) O(nlogn),最坏情况为 O ( n 2 ) O(n^2) O(n2)
    • 空间复杂度:平均情况为 O ( l o g n ) O(logn) O(logn),最坏情况为 O ( n ) O(n) O(n)
    • 稳定性:不稳定。
    • 优点:效率高,平均情况下性能较好。
    • 缺点:最坏情况下时间复杂度较高。
  6. 冒泡排序

    • 基本思想:通过反复比较相邻的元素并交换它们的位置,将最大的元素逐步“冒泡”到数组的末尾。
    • 时间复杂度:平均情况和最坏情况均为 O ( n 2 ) O(n^2) O(n2)
    • 空间复杂度: O ( 1 ) O(1) O(1)
    • 稳定性:稳定。
    • 优点:简单易懂,容易实现。
    • 缺点:效率较低。

综上所述,不同的排序算法在时间复杂度、空间复杂度、稳定性和实现难度等方面存在差异。在实际应用中,应根据具体情况选择合适的排序算法。对于小规模数据,插入排序和冒泡排序可能是简单有效的选择;对于大规模数据,快速排序和堆排序通常具有较好的性能。希尔排序和选择排序在某些情况下也可能表现良好

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用互斥锁解决缓存击穿

我先说一下正常的业务流程&#xff1a;需要查询店铺数据&#xff0c;我们会先从redis中查询&#xff0c;判断是否能命中&#xff0c;若命中说明redis中有需要的数据就直接返回&#xff1b;没有命中就需要去mysql数据库查询&#xff0c;在数据库中查到了就返回数据并把该数据存入…

【Ardiuno】实验使用ESP32连接Wifi(图文)

ESP32最为精华和有特色的地方当然是wifi连接&#xff0c;这里我们就写程序实验一下适使用ESP32主板连接wifi&#xff0c;为了简化实验我们这里只做了连接部分&#xff0c;其他实验在后续再继续。 由于本实验只要在串口监视器中查看结果状态即可&#xff0c;因此电路板上无需连…

FFmpeg播放器的相关概念【1】

播放器框架 相关术语 •容器&#xff0f;文件&#xff08;Conainer/File&#xff09;&#xff1a;即特定格式的多媒体文件&#xff0c;比如mp4、flv、mkv等。 • 媒体流&#xff08;Stream&#xff09;&#xff1a;表示时间轴上的一段连续数据&#xff0c;如一段声音数据、一段…

竞拍商城系统源码后端PHP+前端UNIAPP

下载地址&#xff1a;竞拍商城系统源码后端PHP前端UNIAPP

【数据结构】初识数据结构之复杂度与链表

【数据结构】初识数据结构之复杂度与链表 &#x1f525;个人主页&#xff1a;大白的编程日记 &#x1f525;专栏&#xff1a;C语言学习之路 文章目录 【数据结构】初识数据结构之复杂度与链表前言一.数据结构和算法1.1数据结构1.2算法1.3数据结构和算法的重要性 二.时间与空间…

【计算机毕业设计】基于SSM++jsp的在线医疗服务系统【源码+lw+部署文档】

包含论文源码的压缩包较大&#xff0c;请私信或者加我的绿色小软件获取 免责声明&#xff1a;资料部分来源于合法的互联网渠道收集和整理&#xff0c;部分自己学习积累成果&#xff0c;供大家学习参考与交流。收取的费用仅用于收集和整理资料耗费时间的酬劳。 本人尊重原创作者…

Ubuntu server 24.04 (Linux) 搭建DNS服务器 通过Nginx实现UDP/TCP负载均衡 轻量级dnsmasq服务器

一 系统运行环境 testtest:~$ cat /etc/os-release PRETTY_NAME"Ubuntu 24.04 LTS" NAME"Ubuntu" VERSION_ID"24.04" VERSION"24.04 LTS (Noble Numbat)" VERSION_CODENAMEnoble IDubuntu ID_LIKEdebian HOME_URL"https://www.…

国际货币基金组织警告:网络攻击影响全球金融稳定

近日&#xff0c;在一份关于金融稳定的报告中&#xff0c;国际货币基金组织&#xff08;IMF&#xff09;用了一章&#xff08;共三章&#xff09;的篇幅描述了网络攻击对金融环境的影响&#xff0c;并警告称&#xff0c;全球金融稳定正受到日益频繁和复杂的网络攻击的威胁。同时…

Python的登录注册界面跳转汽车主页面

1.登录注册界面的代码&#xff1a; import tkinter as tk from tkinter import messagebox,ttk from tkinter import simpledialog from ui.car_ui import start_car_ui# 设置主题风格 style ttk.Style() style.theme_use("default") # 可以根据需要选择不同的主题…

你可以直接和数据库对话了!DB-GPT 用LLM定义数据库下一代交互方式,数据库领域的GPT、开启数据3.0 时代

✨点击这里✨&#xff1a;&#x1f680;原文链接&#xff1a;&#xff08;更好排版、视频播放、社群交流、最新AI开源项目、AI工具分享都在这个公众号&#xff01;&#xff09; 你可以直接和数据库对话了&#xff01;DB-GPT 用LLM定义数据库下一代交互方式&#xff0c;数据库领…

网页文档下载不了怎么办 网页文档下载方法

一个方法&#xff0c;搞定所有网页文档下载。如果你也需要从网页下载各种文档&#xff0c;那么本文一定可以帮到你。无须充值会员&#xff0c;各大平台文档下到爽。看到就是赚到&#xff0c;还不赶快学起来。有关网页文档下载不了怎么办&#xff0c;网页文档下载方法的问题&…

LabVIEW控制PLC的实现方式

LabVIEW与PLC的结合可以充分发挥两者的优点&#xff0c;实现更高效、灵活和可靠的自动化控制系统。本文将详细介绍LabVIEW控制PLC的实现方式&#xff0c;包括通信接口、数据交换、编程方法及实际应用案例&#xff0c;帮助用户理解并应用这一技术。 通信接口 常见通信协议 La…

Linux下线程的互斥与同步详解

&#x1f916;个人主页&#xff1a;晚风相伴-CSDN博客 &#x1f496;如果觉得内容对你有帮助的话&#xff0c;还请给博主一键三连&#xff08;点赞&#x1f49c;、收藏&#x1f9e1;、关注&#x1f49a;&#xff09;吧 &#x1f64f;如果内容有误或者有写的不好的地方的话&…

HIP的应用可移植性

Application portability with HIP — ROCm Blogs (amd.com) 许多科学应用程序在配备AMD的计算平台和超级计算机上运行&#xff0c;包括Frontier&#xff0c;这是世界上第一台Exascale系统。这些来自不同科学领域的应用程序通过使用Heterogeneous-compute Interface for Portab…

tomcat8w.exe指向了别的tomcat

这种情况通常发生是因为Tomcat服务在注册表中的配置指向了错误的可执行文件路径。tomcat8w.exe是一个Windows服务配置工具&#xff0c;它用于管理Tomcat服务&#xff0c;包括设置Path to executable&#xff0c;即指向Tomcat服务实际启动的.exe文件的路径。如果Path to executa…

Windows下对于Qt中带 / 的路径的处理

在Windows下&#xff0c;如果你想使用操作系统的分隔符显示用户的路径&#xff0c;请使用 toNativeSeparators()。 请看以下代码&#xff1a; void Player::on_playBtn_clicked() {if (this->m_url.isEmpty()) {openMedia();if (this->m_url.isEmpty())return;}qDebug(…

如何使用Python的Turtle模块绘制小猪

一、前置条件 在开始学习如何使用Python的Turtle模块进行绘画之前&#xff0c;请确保你的电脑已安装Python环境。如果尚未安装Python&#xff0c;你可以从Python官网下载并安装最新版本。 Turtle模块是Python内置的一个用于绘图的库&#xff0c;通常不需要额外安装。如果你发…

反转链表 (oj题)

一、题目链接 https://leetcode.cn/problems/reverse-linked-list/submissions/538124207 二、题目思路 1.定义三个指针&#xff0c;p1先指向NULL p2指向头结点 p3指向第二个结点 2.p2的next指向p1。然后移动指针&#xff0c;p1来到p2的位置&#xff0c;p2来到p3的位置&…

Latex中表格(3)

Latex中的表格 一、多行或多列单元格 这篇主要说Latex中表格出现多行或者多列单元格的形式. 一、多行或多列单元格 可能用到的宏包 \usepackage{booktabs}\usepackage{multirow} 代码&#xff1a; \begin{table}[h!] \centering \caption{Your caption here} \begin{tabul…

LabVIEW与PLC的区别

LabVIEW和PLC是工业自动化领域中常见的两种控制和测控方案&#xff0c;各自有独特的优点和适用场景。本文将从多角度比较两者&#xff0c;帮助用户在选择控制系统时做出更明智的决策。 技术背景 LabVIEW LabVIEW是由National Instruments公司开发的图形化编程环境&#xff0…