内排序算法小结

PCL 模型滤波器【2025最新版】 根据给定的模型系数在点云中提取对应于模型的点云数据。博客长期更新,本文最新更新时间为:2025年6月17日。 阅读详情

从以下几个方面来比较排序算法:

1. 算法的时间和空间复杂度

2. 排序的稳定性

3. 算法结构的复杂度

4. 参加排序的数据规模


排序的稳定性:

稳定排序方法: 插入排序、冒泡排序、二路归并排序、基数排序是稳定排序算法;

不稳定排序方法: 选择排序、谢尔排序、快速排序、堆积排序是不稳定排序算法。


算法复杂度比较:

各种内排序算法的时间、空间复杂度
排序方法平均时间最坏情况辅助空间
插入排序O(n*n)O(n*n)O(1)
谢尔排序O(n*log2n)O(n*log2n)O(1)
泡排序O(n*n)O(n*n)O(1)
快速排序O(n*log2n)O(n*n)O(log2n)
选择排序O(n*n)O(n*n)O(1)
堆积排序O(n*log2n)O(n*log2n)O(1)
归并排序O(n*log2n)O(n*log2n)O(n)
基数排序O(d*(n+r))O(d*(n+r))O(n+r)


有结论如下:

1. 平均情况下,谢尔排序、快速排序、堆积排序、归并排序都能达到较快的排序速度,快速排序最快,堆积排序空间消费最省。

2. 平均情况下,插入排序和泡排序的排序速度较慢,但当参加排序的序列开始就局部有序时,这两种排序算法就能够达到较快的排序速度。最后情况下速度为O(n), 比情况 1 中叙述的4中方法都好,辅助空间消费也少。所以当 n 较小或者序列开始就局部有序时,可选择这两种方法。

3. 基数排序方法消费的辅助空间较多,但其时间复杂度可简化为O(dn); 当元素的位数较少时,可继续简化为O(n), 这种情况下也能达到较快的排序速度,另外,归并排序需要的辅助空间也较多。

4. 从算法结构的简单性来看,插入排序、泡排序、选择排序比较简单和直接;而谢尔排序、快速排序、堆积排序以及归并排序都可以看做对某一种排序算法的进一步改进,相对而言,改进后的算法都比较复杂。

5. 从参加排序的数据序列的规模大小来看,n越小,采用简单排序方法就越合适;n越大,采用改进的排序方法越合适。这是因为n越小,n*n 与 log2n 的差距越小。


以下是在考虑内排序算法的优缺点后,在某些情况下比较适合的算法选择:

1. 当参加排序的数据规模较大,关键字元素分布比较随机,并且不要求排序稳定性时,宜采用快速排序法。

2. 当参加排序的数据规模较大,内存空间又允许,并且有排序稳定性要求,宜采用归并排序法。

3. 当参加排序的数据规模较大,元素分布可能出现升序或者逆序的情况,并且对排序的稳定性无要求时,宜采用插入排序方法。

4. 当参加排序的数据规模较小(如小于100),元素基本有序(升序),或者分布也比较随机,并且有排序稳定性要求时,宜采用插入排序方法。

5. 当参加排序的数据规模n较小,对排序稳定性又不要求时,宜采用选择排序。


插入排序、选择排序、归并排序都比较容易在链表上实现,当利用链表作为存储结构时,可以避免将大量时间花费在元素的位置移动上。


算法描述:

1. 插入排序:

  1. /* 简单插入排序 
  2.  * |data|中存储数组元素 
  3.  * |len|是数组大小 
  4.  * 1.  
  5.  *  需要 |len - 1| 趟排序,每一趟排序将未排序的序列中第一个元素插入到已排序的序列中 
  6.  * 2. 
  7.  *  每一趟排序寻找插入位置的比较次数不定,但是至少需要一次 
  8.  * 3. 
  9.  *  最好的情况,原序列已是升序排列,则需要|n-1|趟排序,每一趟排序进行一次元素间的比较,时间复杂度O(n) 
  10.  * 4. 
  11.  *  最坏的情况,原序列是降序排列,同样需要|n-1|趟排序,第 i(i>=1 && i<len)趟排序需进行 i 次元素间比较,时间复杂度O(n*n) 
  12.  * 5. 
  13.  *  平均时间复杂度O(n*n) 
  14.  * 6. 
  15.  *  插入排序是稳定性排序 
  16.  * */  
  17. void simple_insert(int *data, int len)  
  18. {  
  19.     if(data == NULL || len < 1)  
  20.         return;  
  21.   
  22.     int temp, i, j;  
  23.     for(i = 1; i < len; ++i) {  
  24.         temp = data[i];  
  25.         j = i - 1;  
  26.         while(j >= 0 && temp < data[j]) {  
  27.             data[j+1] = data[j--];  
  28.         }  
  29.         data[j+1] = temp;  
  30.     }  
  31. }  
  32.   
  33. /* 折半插入排序 
  34.  * 与简单插入排序相比 
  35.  *  1. 折半插入排序减少了寻找插入位置时的元素之间的比较次数 
  36.  *  2. 并未减少元素的移动次数和排序所需的趟数 
  37.  *  3. 时间复杂度降为O(n*log2n) 
  38.  */  
  39. void binary_insert(int *data, int len)  
  40. {  
  41.     if(data == NULL || len < 1)  
  42.         return;  
  43.   
  44.     int temp, i, j, low, mid, high;  
  45.     for(i = 1; i < len; ++i) {  
  46.         temp = data[i];  
  47.         low = 0;  
  48.         high = i - 1;  
  49.         while(low <= high) {  
  50.             mid = (low + high)/2;  
  51.             if(temp < data[mid])  
  52.                 high = mid - 1;  
  53.             else  
  54.                 low = mid + 1;  
  55.         }  
  56.   
  57.         for(j = i; j > low; --j)  
  58.             data[j] = data[j-1];  
  59.   
  60.         data[low] = temp;  
  61.     }  
  62. }  

2. 谢尔排序

  1. /* 谢尔排序,又称缩小增量排序法,是对直接插入排序法的一种改进 
  2.  * 1. 
  3.  *  时间复杂度在O(n*log2n) 和 O(n*n)之间 
  4.  * 2. 
  5.  *  谢尔排序是一种不稳定排序,不适合在链表结构上实现的排序算法 
  6.  * */  
  7. void shellSort(int *data, int len)  
  8. {  
  9.     if(data == NULL || len < 1)  
  10.         return;  
  11.   
  12.     unsigned int gap = len;  
  13.     int i,j,temp;  
  14.     while(gap > 0) {  
  15.         gap >>= 1;  
  16.         for(i = gap; i < len; ++i) {  
  17.             j = i - gap;  
  18.             temp = data[i];  
  19.             while(j >= 0 && temp < data[j]) {  
  20.                 data[j+gap] = data[j];  
  21.                 j -= gap;  
  22.             }  
  23.   
  24.             data[j+gap] = temp;  
  25.         }  
  26.     }  
  27. }  

3. 泡排序

  1. /* 冒泡排序 
  2.  * 1. 
  3.  *  至少需要进行一趟排序,此时是原始序列已经升序排列的情况,需进行|len - 1|次元素间的比较,时间复杂度O(n) 
  4.  * 2. 
  5.  *  最多进行|len - 1|趟排序(最小值处于原始序列最后),第 i(i>=1 && i<=len-1) 趟排序需要进行|len - i|次元素间的比较, 时间复杂度O(n*n) 
  6.  * 3. 
  7.  *  平均时间复杂度是O(n*n) 
  8.  * 4. 
  9.  *  冒泡排序是稳定性排序,适用于参加排序的数据量较小并且序列的初始状态为基本有序的情况 
  10.  * */  
  11. void bubbleSort(int *data, int len)  
  12. {  
  13.     if(data == NULL || len < 1)  
  14.         return;  
  15.   
  16.     int flag = 1;  
  17.     int i, j, temp;  
  18.     i = len - 1;  
  19.     while(i > 0 && flag == 1) {  
  20.         flag = 0;  
  21.         for(j = 0; j < i; ++j) {  
  22.             if(data[j] > data[j+1]) {  
  23.                 temp = data[j];  
  24.                 data[j] = data[j+1];  
  25.                 data[j+1] = temp;  
  26.   
  27.                 flag = 1;  
  28.             }  
  29.         }  
  30.   
  31.         --i;  
  32.     }  
  33. }  

4. 快速排序

  1. /* randomInRange函数: 
  2.  * 产生[start, end] 之间的随机数,包括start, end两个数 
  3.  * */  
  4. int randomInRange(int start, int end)  
  5. {  
  6.     srand(time(NULL));  
  7.   
  8.     return start + rand()%(end-start+1);  
  9. }  
  10.   
  11. /*  
  12.  * 交换elem1, elem2的值 
  13.  */  
  14. void swapElem(int *elem1, int *elem2)  
  15. {  
  16.     int temp = *elem1;  
  17.     *elem1 = *elem2;  
  18.     *elem2 = temp;  
  19. }  
  20.   
  21. /* partition函数: 
  22.  * 在data序列的[start, end]之间随机选取一个元素值作为分界元素vp, 
  23.  * 该分界元素vp左边的值都小于等于vp, 右边的值都大于等于vp, 
  24.  * 函数返回该分界元素在序列中的索引位置 
  25.  * */  
  26. int partition(int *data, int len, int start, int end)  
  27. {  
  28.     if(data == NULL || len < 1 || start < 0 || end >= len) {  
  29.         printf("invalid parameters.");  
  30.         exit(1);  
  31.     }  
  32.   
  33.     int index = randomInRange(start, end);  
  34.     swapElem(&data[index], &data[end]);  
  35.     int small = start - 1;  
  36.   
  37.     for(index = start; index < end; ++index) {  
  38.         if(data[index] < data[end]) {  
  39.             ++small;  
  40.             if(small != index)  
  41.                 swapElem(&data[index], &data[small]);  
  42.         }  
  43.     }  
  44.     swapElem(&data[++small], &data[end]);  
  45.   
  46.     return small;  
  47. }  
  48.   
  49. /* 快速排序递归算法: 
  50.  * 1.  
  51.  *  时间复杂度是O(n*log2n) 
  52.  * 2.  
  53.  *  快速排序是不稳定排序,不适合在链表结构上实现的排序算法 
  54.  * 3. 
  55.  *  每次排序时如果各个部分的分界元素恰好就是最大值元素时,快速排序就会倒退为"慢速排序", 此时并未把序列分界为两个子序列 
  56.  * */  
  57. void quickSort(int *data, int len, int start, int end)  
  58. {  
  59.     if(start == end)  
  60.         return;  
  61.   
  62.     int index = partition(data, len, start, end);  
  63.     if(index > start)  
  64.         quickSort(data, len, start, index - 1);  
  65.     if(index < end)  
  66.         quickSort(data, len, index + 1, end);  
  67. }  

5. 选择排序

  1. /* 选择排序 
  2.  * 1.  
  3.  *  总共需要|len - 1|趟排序,且第 i(i>=1 && i<=len-1) 趟排序需要进行 |len - i|次元素间的比较 
  4.  * 2. 
  5.  *  时间复杂度与初始序列的状态无关,都是O(n*n) 
  6.  * 3. 
  7.  *  选择排序是不稳定排序,例如(49, 38, 65, 97, 49, 13, 27) 
  8.  * */  
  9. void selectSort(int *data, int len)  
  10. {  
  11.     if(data == NULL || len < 1)  
  12.         return;  
  13.   
  14.     int i, j, minIndex;  
  15.     for(i = 0; i < len - 1; ++i) {  
  16.         minIndex = i;  
  17.         j = i + 1;  
  18.         while(j < len) {  
  19.             if(data[j] < data[minIndex])  
  20.                 minIndex = j;  
  21.             ++j;  
  22.         }  
  23.   
  24.         if(minIndex != i) {  
  25.             int temp = data[i];  
  26.             data[i] = data[minIndex];  
  27.             data[minIndex] = temp;  
  28.         }  
  29.     }  
  30. }  

6. 堆积排序

  1. /* adjust函数: 
  2.  * |len| 数组序列的大小 
  3.  * |root| 数组中某一元素的索引 
  4.  * 以结点root为根结点的子树不是堆积,但结点root的左右子树都是堆积, 
  5.  * adjust函数将把第root个结点作为根结点的子树调整为一个新的堆积 
  6.  * */  
  7. void adjust(int *data, int len, int root)  
  8. {  
  9.     int temp = data[root];  
  10.     int i = root * 2;  
  11.   
  12.     while(i <= len) {  
  13.         if(i < len && data[i] < data[i + 1])  
  14.             ++i;  
  15.   
  16.         if(temp >= data[i])  
  17.             break;  
  18.   
  19.         data[i/2] = data[i];  
  20.         i *= 2;  
  21.     }  
  22.   
  23.     data[i/2] = temp;  
  24. }  
  25.   
  26. /* 堆排序: 
  27.  * |len| data序列中最后一个元素的索引号, 也是参加排序的元素个数, 
  28.  * 注意不是data序列的元素个数 
  29.  * 1.  
  30.  *  data序列中第1个元素(data[0])不参加排序 
  31.  * 2.  
  32.  *  总共执行|len - 1|趟排序,每一趟排序确定未排序序列中的最大值的位置,并执行一次adjust函数 
  33.  * 3. 
  34.  *  无论是最坏情况还是平均情况,堆积排序的时间复杂度都是O(n*log2n) 
  35.  * 4. 
  36.  *  堆积排序的空间复杂度是O(1), 适合于len较大的序列排序 
  37.  * 5. 
  38.  *  堆积排序不适合在链表上实现 
  39.  * 6. 
  40.  *  堆积排序是不稳定排序,例如(5, 4, 3, 2, 2, 2, 1) 
  41.  */  
  42. void heapSort(int *data, int len)  
  43. {  
  44.     if(data == NULL || len < 1)  
  45.         return;  
  46.   
  47.     int i;  
  48.     for(i = len/2; i > 0; --i) {  
  49.         adjust(data, len, i);  
  50.     }  
  51.   
  52.     int temp;  
  53.     for(i = len; i > 1; --i) {  
  54.         temp = data[1];  
  55.         data[1] = data[i];  
  56.         data[i] = temp;  
  57.   
  58.         adjust(data, i-1, 1);  
  59.     }  
  60. }  

7. 归并排序

  1. /* merge函数: 
  2.  * 将source[start..mid]和source[mid+1..end]中的元素归并有序序列des[start..end] 
  3.  * 
  4.  * */  
  5. void merge(int *source, int *des, int start, int mid, int end)  
  6. {  
  7.     int i = start;  
  8.     int j = mid + 1;  
  9.     int k = start;  
  10.   
  11.     while(i <= mid && j <= end) {  
  12.        // if(source[i] <= source[j])  
  13.        //     des[k++] = source[i++];  
  14.        // else  
  15.        //     des[k++] = source[j++];  
  16.         des[k++] = source[i] <= source[j] ? source[i++] : source[j++];  
  17.     }  
  18.   
  19.     while(i <= mid)  
  20.         des[k++] = source[i++];  
  21.     while(j <= end)  
  22.         des[k++] = source[j++];  
  23. }  
  24.   
  25. /* mpass函数: 
  26.  * 将参加排序的序列分成若干个长度为t的,且各自按值有序的子序列, 
  27.  * 然后多次调用归并子算法merge将所有两两相邻成对的子序列合并成 
  28.  * 若干个长度为2t的,且各自按值有序的子序列。 
  29.  *  
  30.  * 若最后一趟排序时,剩下的元素不足2t个元素: 
  31.  * 1. 
  32.  *  若剩余元素个数大于t,则再调用一次merge算法将剩余的两个不等长子序列合并为一个子序列 
  33.  * 2. 
  34.  *  若剩余元素个数小于等于t,则直接将所有剩余元素依次复制到前一个子序列的后面 
  35.  * */  
  36. void mpass(int *source, int *des, int len, int t)  
  37. {  
  38.     int i = 0;  
  39.     if(len - i >= 2*t) {  
  40.         merge(source, des, i, i + t - 1, i + 2 * t - 1);  
  41.         i += 2 * t;  
  42.     }  
  43.   
  44.     if(len - i > t)  
  45.         merge(source, des, i, i + t - 1, len - 1);  
  46.     else {  
  47.         for(; i < len; ++i)  
  48.             des[i] = source[i];   
  49.     }  
  50. }  
  51.   
  52. /* mergeSort排序: 
  53.  * |flag|,若flag = -1,则表示输入参数错误; 
  54.  * 若flag = 1, 则表示排好序的元素存放于data序列中 
  55.  * 若flag = 0,则表示排好序的元素存放于des序列中 
  56.  * 1.  
  57.  *  总共会进行log2n趟排序,每趟排序调用mpass函数,mpass的时间复杂度为O(n),二路归并排序的时间复杂度为O(nlog2n) 
  58.  * 2. 
  59.  *  排序过程中需要同原始序列同等大小的辅助空间,空间复杂度为O(n) 
  60.  * 3. 
  61.  *  二路归并排序是稳定性排序 
  62.  * 4. 
  63.  *  二路归并排序的时间复杂度与序列的初始状态无关 
  64.  */  
  65. int mergeSort(int *data, int *des, int len)  
  66. {  
  67.     int flag = -1;  
  68.     if(data == NULL || len < 1)  
  69.         return flag;  
  70.   
  71.     int t = 1;  
  72.     flag = 1;  
  73.     while(t < len) {  
  74.         mpass(data, des, len, t);  
  75.         flag = 0;  
  76.   
  77.         t *= 2;  
  78.         if(t < len) {  
  79.             mpass(des, data, len, t);  
  80.             t *= 2;  
  81.             flag = 1;  
  82.         }  
  83.     }  
  84.   
  85.     return flag;  
  86. }  

8. 基数排序
  1. /* 
  2.  * 定义的存储数据元素的结点 
  3.  */  
  4. typedef struct Node {  
  5.     int data;  
  6.     struct Node *next;  
  7. }QLink;  
  8.   
  9. /* maxDig函数: 
  10.  * 找出data序列所有元素中最长的位数maxd并返回 
  11.  * */  
  12. int maxDig(int *data, int len)  
  13. {  
  14.     int maxd = 0;  
  15.     int maxCurD = 1;  
  16.   
  17.     int base = 10;  
  18.     for(int i = 0; i < len; ++i) {  
  19.         maxCurD = 1;  
  20.         base = 10;  
  21.         while(data[i] >= base) {  
  22.             ++maxCurD;  
  23.             if(maxd < maxCurD)  
  24.                 maxd = maxCurD;  
  25.             base *= 10;  
  26.         }  
  27.     }  
  28.   
  29.     return maxd;  
  30. }  
  31.   
  32. /* 
  33.  * 将data序列中所有元素均存储到链表中,并返回链表头结点head 
  34.  */  
  35. QLink* transferArrToQLink(int *data, int len)  
  36. {  
  37.     if(data == NULL || len < 1)  
  38.         return NULL;  
  39.   
  40.     QLink *head = NULL;  
  41.     QLink *rear = NULL;  
  42.   
  43.     for(int i = 0; i < len; ++i) {  
  44.         QLink *cur = (QLink *)malloc(sizeof(QLink));  
  45.         cur->data = data[i];  
  46.         cur->next = NULL;  
  47.         if(head == NULL)  
  48.             head = cur;  
  49.         else  
  50.             rear->next = cur;  
  51.         rear = cur;  
  52.     }  
  53.   
  54.     return head;  
  55. }  
  56.   
  57. /* 
  58.  * 释放链表中所有元素结点 
  59.  */  
  60. void freeQLink(QLink *phead)  
  61. {  
  62.     QLink *toFree = NULL;  
  63.     while(phead != NULL) {  
  64.         toFree = phead;  
  65.         phead = phead->next;  
  66.         free(toFree);  
  67.     }  
  68. }  
  69.   
  70. /* 
  71.  * 获取num 中从右边数第index位的数字,index从0 开始计数 
  72.  * 
  73.  */  
  74. int getCurPlaceV(int num, int index)  
  75. {  
  76.     int placeValue;  
  77.     int i = 0;  
  78.     while(i <= index) {  
  79.         placeValue = num%10;  
  80.         num /= 10;  
  81.         ++i;  
  82.     }  
  83.   
  84.     return placeValue;  
  85. }  
  86.   
  87. /* 
  88.  * |data| 数据元素序列,|len|数据元素的个数,|radix|是基数 
  89.  */  
  90. void radixSort(int *data, int len, int radix)  
  91. {  
  92.     int maxd = maxDig(data, len);  
  93.     printf("maxd = %d\n", maxd);  
  94.     QLink *phead = transferArrToQLink(data, len);  
  95.   
  96.     QLink *Front[radix], *End[radix];  
  97.     QLink *q, *rear;  
  98.     int i, j, curplaceV;  
  99.     for(i = 0; i < maxd; ++i) {  
  100.         printf("the %d times sort\n", i);  
  101.         for(j = 0; j < radix; ++j)  
  102.             Front[j] = End[j] = NULL;  
  103.   
  104.         q = phead;  
  105.         while(q != NULL) {  
  106.             curplaceV = getCurPlaceV(q->data, i);  
  107.             if(Front[curplaceV] == NULL)  
  108.                 Front[curplaceV] = q;  
  109.             else  
  110.                 End[curplaceV]->next = q;  
  111.             End[curplaceV] = q;  
  112.   
  113.             q = q->next;  
  114.         }  
  115.   
  116.         j = 0;  
  117.         while(Front[j] == NULL)  
  118.             ++j;  
  119.   
  120.         phead = Front[j];  
  121.         rear = End[j];  
  122.         ++j;  
  123.         for(; j < radix; ++j) {  
  124.             if(Front[j] != NULL) {  
  125.                 rear->next = Front[j];  
  126.                 rear = End[j];  
  127.             }  
  128.         }  
  129.         rear->next = NULL;  
  130.     }  
  131.   
  132.     q = phead;  
  133.     i = 0;  
  134.     while(q != NULL) {  
  135.         data[i++] = q->data;  
  136.         q = q->next;  
  137.     }  
  138.   
  139.     freeQLink(phead);  
  140.     phead = NULL;  
  141. }  
2xmax96717+max96724+agx orin驱动代码 说明:这里主要解决max96717的设备地址和sensor地址映射,vc0->vc1多颗max96717+max96724使用配置思路如下: 1、改变max96717的pipez stream id,然后max96724的pipe绑定使用相应的stream id 2、max96717默认是vc0,把vc0改写成vc1\vc2\vc3,然后max96724再重新映射vc输出 阅读详情

相关推荐

从CMT2300A实战出发:Sub1G射频匹配电路设计要点与315MHz应用详解

本文从CMT2300A芯片实战出发,详细解析Sub1G射频匹配电路设计要点,特别针对315MHz应用场景。内容涵盖频段划分逻辑、调制方式选择、晶体振荡器设计等基础认知,以及315MHz匹配电路物料选型、巴伦网络处理等实战技巧,并分享PCB布局防干扰设计和实测验证方法,助力开发者优化射频通信性能。

weixin_29238147的博客 165

常见七种排序算法对比(超全!!!)

一,冒泡排序 最常见的排序实现起来很简单,不过实际应用很少,复杂度O(n²)。 原理:一趟一趟的比,每一趟中,循环剩余的数,和后一个进行比较,若比它小则交换。这样一趟下来最小的在第一个,最大的在最后一个。总共需要比n-1趟。 public static void BubbleSort(int []array){ for(int i=1;i<array.length;i++) { for(int j=0;j<array.length-1;j++) .

qq_54850622的博客 1万+

保姆级教程:从零到飞,用QGC地面站搞定PX4无人机全流程配置(含避坑指南)

本文提供了一份详细的QGC地面站使用教程,指导用户从零开始配置PX4无人机,涵盖固件烧录、传感器校准、遥控器设置及航点规划等关键步骤,并包含实用的避坑指南,帮助新手顺利完成首飞。

weixin_30329623的博客 221

排序算法的详解和分析对比(详细讲解)

排序算法各式各样,每种排序算法的思想也大同小异。读者应该深度了解每种算法的基本思想、排序每一步过程细节和每种排序的特性,看到特定的序列,应该立马想到最适合的排序方法。一些简单的排序算法中,虽然效率不高,但是在低数量规模情况下,就比如一万数量级以下,一般运行时间还能可以被人们所接受,零点几秒左右很难被察觉出来。但是如果到了十万数量级,排序就需要非常久的时间,可能会导致我们一些系统会出现误差,从而引起巨大的麻烦和问题。

gongjunbox的博客 9593

Hopfield神经网络(HNN)详解

Hopfield神经网络是一种比较特殊的网络,它不像一般的神经网络那样有输入层和输出层,并且通过训练来改变神经网络中的参数,最终实现预测、识别等功能。Hopfield网络只有一群神经元节点,所有节点之间相互连接,形式如下: 虽然有些文章会画出像深度神经网络那样有输入输出的图,并且输出后又返回输入,但本质上就是多个节点之间的全连接,也就是上面的图形。Hopfield神经网络主要有两个应用:一是起到类似储存器的作用,也就是我们把多个序列或图片输入这个网络,最终这个网络会以神经元之间连接权重的形式储存这

weixin_60737527的博客 4万+

RYU+mininet——RYU

1. 使用RYU做mininet的控制器 1.1 RYU介绍与安装 RYU是一款基于python的控制器,你可用Ryu实现各种想要实现的网络功能,它可以下发或接收流表进行各种路由运算。 建议使用高版本的Ubuntu系统安装ryu,否则会有各种错误,安装过程比较简单,如下: apt install gcc libffi-dev libssl-dev libxml2-dev libxslt1-...

qq_34415266的博客 1万+

【数据结构从青铜到王者】第九篇:数据结构之排序

系列文章目录 文章目录系列文章目录前言一、排序的概念1.排序的概念二、常见排序算法的实现1.插入排序1.基本思想2.代码实现2.希尔排序1.基本思想2.代码实现3.选择排序1.基本思想2.代码实现4.堆排序1.基本思想2.代码实现5.冒泡排序1.基本思想2.代码实现6.快速排序递归思想1.左右指针法1.基本思想2.代码实现2.挖坑法1.基本思想2.代码实现3.前后指针法1.基本思想2.代码实现4.快速排序优化方法1.三数取中法2.小区间排序优化7.快速排序非递归思想1.基本思想2.代码实现8.归并排序递.

森明帮大于黑虎帮的博客 2324

Modbus RTU/TCP协议栈手写实现:主从站设计、功能码、CRC、异常响应

本文从协议栈架构、帧结构、功能码、CRC校验、异常响应、主从站设计等多个维度,完整阐述了Modbus RTU/TCP协议栈的手写实现方案。帧间隔机制是RTU的核心,T3.5超时检测决定了帧边界识别CRC16查表法以512字节ROM换取8倍性能提升,适合嵌入式功能码路由表实现可扩展的代码架构,便于新增功能异常响应机制保障协议健壮性,每个错误都有明确反馈Modbus TCP在RTU基础上增加MBAP头,实现以太网扩展多核RTOS环境下的并发访问与线程安全RS-485总线的电气隔离与浪涌保护。

从事移动开发八年,csdn博客专家,阿里云特邀专家,华为云云享专家,高级网络信息安全工程师,大数据工程师(高级),python技术开发(高级),HarmonyOS 应用开发者高级认证,现在某学校任教。 1万+

9种排序算法对比

本文章中所有代码均为本人原创,能力有限,若有错误,请指正!

m0_74133913的博客 1516

基于matlab的阈值分割的车牌定位识别系统

车牌自动识别模块是现代社会智能交通系统(ITS)的重要组成部分,是图像处理和模式识别技术研究的热点,具有非常广泛的应用。车牌识别主要包括以下三个主要步骤:车牌区域定位、车牌字符分割、车牌字符识别。本案例通过对采集的车牌图像进行灰度变换、边缘检测、腐蚀及平滑等过程进行车牌图像预处理,并由此得到一种基于车牌颜色纹理特征的车牌定位方法,最终实现了车牌区域定位。车牌字符分割是为了方便后续对车牌字符进行匹配,从而对车牌进行识别。

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 970

基于YOLOv8的违规抽烟/打电话检测系统:从数据集构建到部署实战

模型优点缺点精度高速度慢(5 FPS)SSD速度快小目标检测差YOLOv5平衡性好官方支持停止YOLOv8最新、最快、最准需要PyTorch环境YOLOv8相比前代:骨干网络升级(C2f模块)无锚框检测(Anchor-Free)动态任务对齐分配(TaskAlignedAssigner)支持分类/检测/分割/姿态估计。

YOLO 98

算法设计(1)--内排序算法小结

内排序算法 William Yi 完成于2016/10/18 Email: williamyi96@gmail.com 排序算法可以大致分为两种类型: 内排序 外排序 两者之间的区别是内排序是在内存中进行的排序,而外排序则可以借助磁盘空间。我们通过之前的学习了解到:内存中的排序时间代价与空间代价是成反比的,也就是说时间的缩短是以空间增长为代价的,空间的减少是以时间延长为代价的;而磁盘中

博观而约取,深研而广求 1423

【系统分析师】第2章-基础知识:数学与工程基础(核心总结)

数学与工程基础

数据知道的博客 6814

排序算法小结(五)——在线性时间内排序(Java实现):计数排序、基数排序。

1.计数排序 一文弄懂计数排序算法! 2.基数排序

xx2014301318的博客 307

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

内部排序算法小结

排序算法大体上可分为内部排序和外部排序。所谓外部排序,就是指计算机的内存有限,不能将庞大的序列全部加载到内存中进行排序,就需要访问外部存储设备来进行排序。内部排序,当数据量不是非常大时,可以一次性加载到内存中进行排序的统称。 按照排序依据的不同原则,可将内部排序算法分为插入排序、交换排序、选择排序、归并排序和基数排序。下面我主要讲各种排序算法的原理,实现由小到大的排序,具体的实现方式可以参见我的

在路上...... 918

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

NJUPT南京邮电大学数据结构实验四(各种内排序算法的实现及性能比较)

仅提供思路,请勿照抄!!!

AZCJXT的博客 1697

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

[数据结构] 排序算法小结

排序算法

shengxia_lx的博客 361

【数据结构】内排序小结

“ Ctrl AC!一起 AC!”目录排序码与关键码插入排序直接插入排序二分法插入排序 表插入排序Shell插入排序(希尔排序)选择排序直接选择排序树型选择排序堆排序 交换排序冒泡排序快速排序快速排序归并排序基数排序排序码:以此码作为比较进行排序 关键码:能唯一标识一个记录的字段称为关键码比如(可能不恰当)a b c d 这一序列排序码是它们在字母表中的顺序关键码是它们本身"a" "b" "c" "d"插入排序的基本方法是:将待排序文件中的记录,逐个地按其排序码值的大小插入到目前已经排好序的若干个记录组成的

Ctrl AC的博客 480

内排序小结

冒泡排序是一种交换排序,基本思想是:两两比较相邻记录的关键字,如果反序则交换,直到没有反序的记录为止。

辉 951

数据结构与算法之排序

不同的排序算法适用于不同的场景,选择合适的排序算法可以提高程序的效率。例如,插入排序适用于部分有序的数据,而归并排序适用于大规模数据的排序.外排序适用于数据量较大的情况,通常需要将数据分块处理,然后合并排序结果。设待排序的表有10个元素,其关键字分别为(9,8,7,6,5,4,3,2,1,0):每次从未排序区取出一个元素,插入到有序区的适当位置,使得有序区仍然保持有序。:初始时,有序区只有一个元素(通常是第一个元素),无序区包含其余所有元素。:将数据分成多个小部分进行排序,然后将排序好的部分合并。

yuange1666的博客 1326

内部排序算法总结-第一篇

内部排序算法总结-第一篇 首先看一下内部排序分类以及各个算法的时间复杂度、空间复杂度和稳定性 一、插入排序   1、直接插入排序 (Straight Insertion Sort)的基本思想是:把n个待排序的元素看成为一个有序表和一个无序表。开始时有序表中只包含1个元素,无序表中包含有n-1个元素,排序过程中每次从无序表中取出第一...

hequnwang10的博客 315

【算法】排序算法小结(上)

        排序算法是算法中的基础,通常是解决其他算法的第一步。排序是将一组对象按照某种逻辑顺序重新排列的过程,本文将经典的排序算法根据《算法第四版》进行整理。以备复习使用。最后,结合leetcode经典题目,进行应用。另外值得注意的是,排序算法有内排序和外排序之分,在排序过程中,全部记录存放在内存,则称为内排序,如果排序过程中需要使用外存,则称为外排序。外排序一般来说外排序分为两个步骤:预处...

Biyoner的博客 464
上一篇: 数组分割问题-详细版
下一篇: 应聘时最漂亮的回答! 留着 早晚用的上
otuhacker
博客等级 码龄18年 21粉丝 84原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值