当前位置: 首页 > news >正文

【算法】排序算法总结

文章目录

  • 内排序
    • 一、插入排序
      • 1.1 直接插入排序
      • 1.2 折半插入排序
      • 1.3 希尔排序
    • 二、选择排序
      • 2.1 简单选择排序
      • 2.2 堆排序
    • 三、交换排序
      • 3.1 冒泡排序
      • 3.2 快速排序
        • Hoare版
        • 挖坑法
        • 快速排序前后指针法
        • 快速排序的非递归
    • 四、归并排序
      • 递归版本
      • 非递归版本
    • 五、基数排序
    • 六、计数排序
    • 内排序总结


内排序

一、插入排序

插入排序包括:直接插入排序和希尔排序

1.1 直接插入排序

算法思想:

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

用一个形象的比喻:摸牌与插牌。
在这里插入图片描述
下面进行动图演示
请添加图片描述


算法的代码实现

在这里插入图片描述

void insert_sort(int a[], int n)
{// tmp表示要插入的元素// end表示已插入元素最后一个元素的下标int tmp, end;// 1个元素默认有序,因此从1开始for (int i = 1; i < n; i++){tmp = a[i];end = i - 1;while (end >= 0){// 1. 如果a[end] > tmp, 则a[end]向后移, end--// 如果a[end] <= tmp,则a[end+1] = tmp// 特殊情况:如果tmp是最小的数,则end = -1会跳出循环,因此在循环体外赋值if (a[end] > tmp){a[end + 1] = a[end];end--;}else{break;}}a[end + 1] = tmp;}
}

算法评价:

  1. 元素集合越接近有序,直接插入排序算法的时间效率越高

  2. 时间复杂度:O(N^2)

  3. 空间复杂度:O(1),它是一种稳定的排序算法

  4. 稳定性:稳定

改进:插入排序效率的重点:减少比较的次数,如何减少比较的次数?2的方向

  1. 快速定位新插入的元素在已排序好的位置 --> 折半查找

  2. 让原来的序列趋近于有序 --> 希尔排序

1.2 折半插入排序

算法思想

直接插入排序中将无序区的开头元素Ri插入到有序区 R[0…i-1]是采用顺序比较的方法。由于有序区的元素是有序的,可以采用折半查找方法先在R0…i-1中找到插入位置,再通过移动元素进行插入,这样的插入排序称为折半插入排序(binary insertion sort)或二分插人排序

算法实现

void mid_insert_sort(int a[], int n)
{int tmp, end;for(int i = 1; i < n; i++){tmp = a[i];end = i-1;// 1. 折半查找位置 -- 注意稳定性,令 <= 为l区域int l = -1, r = i;while(l+1 != r){int mid = l + r >> 1;if(a[mid] > tmp) r = mid;else l = mid;}// 2. 后移元素,[0 l] [r i-1], l+1的地方插入,后移[l+1, i-1]一位while(end >= l+1){a[end+1] = a[end];--end; }a[l+1] = tmp;}
}

算法评价

折半插入排序的元素移动次数与直接插入排序相同,不同的仅是变分散移动为集中移动。在R0…i-1中查找插入R[]的位置,折半查找的平均关键字比较次数约为log(i+1)-1,平均移动元素的次数为i/2+2,所以平均时间复杂度为:

在这里插入图片描述
实际上,折半插入排序和直接插入排序相比移动元素的性能没有改善,仅仅减少了关键字的比较次数。就平均性能而言,由于折半查找优于顺序查找,所以折半插入排序也优于直接插入排序。折半插入排序的空间复杂度为(1),也是一种稳定的排序方法。

1.3 希尔排序

算法思想

希尔排序法又称缩小增量法。希尔排序法的基本思想是:先选定一个整数gap,把待排序文件中所有数据分成gap个组,所有距离为gap的数据分在同一组内,并对每一组内的数据进行排序。然后,取 gap = gap/2,重复上述分组和排序的工作。当到达gap=1时,数据将排好序.

请添加图片描述
算法实现

//单组排完,在排下一组
void shell_sort(int a[], int n)
{int gap = n;while (gap > 1){gap /= 2;//gap /= 3 + 1;//1. 分组for (int i = 0; i < gap; i++){// 2. 单组插入排序int tmp, end;for (int j = i+gap; j < n; j += gap){tmp = a[j];end = j - gap;while (end >= i){if (a[end] > tmp){a[end + gap] = a[end];end -= gap;}else break;}a[end+gap] = tmp;}}}
}
//多组并行
void shell_sort(int a[], int n)
{int gap = n;while (gap > 1){gap /= 2;//多组并行for (int i = 0; i + gap < n; i++){int tmp = a[i + gap];int end = i;while (end >= 0){if (a[end] > tmp){a[end + gap] = a[end];end -= gap;}else break;}a[end + gap] = tmp;}}
}

算法评价

希尔排序的空间复杂度:O(1)

希尔排序的时间复杂度:
在这里插入图片描述
在这里插入图片描述
希尔排序法是一种不稳定的排序算法。例如,若希尔排序分为{3,10,7,8,20}和(5,8,2,1,6)两组,显然第1组的8排列在第2组的8的后面,两组采用直接插入排序后的结果为(3,7,8,10,20}和{1,2,5,6,8),这样第1组的8排列到第2组的8的前面,它们的相对位置发生了改变。


二、选择排序

2.1 简单选择排序

算法思想

每次从剩余数中选出最小的数,与已排序的数组后面一个元素换位置

请添加图片描述
算法实现

//原版 -- 每次选出最小
void select_sort(int a[], int n)
{for (int i = 0; i < n; i++){int Min_i = i;// 1. 单趟找最小元素的下标for (int j = i; j < n; j++){if (a[Min_i] > a[j]){Min_i = j;}}// 2. 与i下标对应的元素交换std::swap(a[Min_i], a[i]);}
}
//优化版 -- 每次选出最大和最小
void select_sort(int a[], int n)
{int l = 0, r = n - 1;while(l < r){int Min_i = l, Max_i = r;// 1. 单趟找最小和最大元素的下标for (int j = l; j <= r; j++){if (a[Min_i] > a[j]){Min_i = j;}if (a[Max_i] < a[j]){Max_i = j;}}// 2. 与l,r下标对应的元素交换std::swap(a[Min_i], a[l]);//存在情况:l指向的数就是目前区间的最大值if (l == Max_i){Max_i = Min_i;}std::swap(a[Max_i], a[r]);l++, r--;}
}

算法评价

显然,无论初始数据序列的状态如何,在第i趟排序中选出最小关键字的元素,内for循环需做n-1-(i+1)+1-n-i-1次比较,因此总的比较次数为:

在这里插入图片描述
另外,简单选择排序算法是一个不稳定的排序方法。例如排序序列为(5,3,2,5,4,1,8,7),第1趟排序时选择出最小关键字1,将其与第1个位置上的元素交换,得到(1,3,2,5,4,5,8,7},从中看到两个5的相对位置发生了改变。

2.2 堆排序

算法思想

堆排序(heap sort)是一种树形选择排序方法,它的特点是将 R[1…n](R[i]的关键字为
k;)看成是一棵完全二叉树的顺序存储结构,利用完全二叉树中双亲结点和孩子结点之间的位置关系在无序区中选择关键字最大(或最小)的元素。

算法实现

void AdjustDown(int a[], int n, int father)
{//1. 找左孩子int left = 2 * father + 1;while (left < n){int Maxchild = left;//2. 找右孩子if (left + 1 < n && a[Maxchild] < a[left + 1]) Maxchild = left + 1;//3. 与父亲比较if (a[Maxchild] > a[father]){std::swap(a[Maxchild], a[father]);father = Maxchild;left = 2 * father + 1;}else return;}
}
void heap_sort(int a[], int n)
{for (int i = n / 2; i >= 0; i--){AdjustDown(a, n, i);}for (int i = 0; i < n - 1; i++){std::swap(a[0], a[n - 1 - i]);AdjustDown(a, n-1-i, 0);}
}

算法评价

堆排序的时间主要由建立初始堆和反复重建堆这两部分的时间构成

建堆:O(n)

排序:O(nlogn)

综上所述,堆排序的最坏时间复杂度为O(nlogn)。堆排序的平均性能分析较难,但实验研究表明,它较接近最坏性能。实际上,堆排序和简单选择排序算法一样,其时间性能与初始序列的顺序无关,也就是说,堆排序算法的最好、最坏和平均时间复杂度都是O(nlogn)。由于建初始堆所需的比较次数较多,所以堆排序不适合元素数较少的排序表,堆排序只使用i、i、tmp等辅助变量,其辅助空间复杂度为(1)。另外,在进行筛选时可能把后面相同关键字的元素调整到前面,所以堆排序算法是一种不稳定的排序方法。


三、交换排序

3.1 冒泡排序

算法思想

冒泡排序(bubble sort)也称为气泡排序,是一种典型的交换排序方法,其基本思想是通过无序区中相邻元素关键字间的比较和位置的交换使关键字最小/最大的元素如气泡一般逐渐往上“漂浮”直至“水面”

请添加图片描述
算法实现

void bubble_sort(int a[], int n)
{for (int i = 0; i < n-1; i++){//单趟从左向右,依次比较for (int j = 0; j < n - 1 - i; j++){if (a[j] > a[j + 1]) std::swap(a[j], a[j + 1]);}}
}//优化1:如果某趟没有发生一次交换则证明已经完成排序
void bubble_sort(int a[], int n)
{for (int i = 0; i < n - 1; i++){int exchange = 0;//单趟从左向右,依次比较for (int j = 0; j < n - 1 - i; j++){if (a[j] > a[j + 1]){std::swap(a[j], a[j + 1]);exchange = 1;}}if (exchange == 0) return;}
}
//优化2 -- 双向冒泡
void two_bubble_sort(int a[], int n)
{int l = 0, r = n - 1, flag = 1;while (l < r){for (int i = l; i < r; i++){if (a[i] > a[i + 1]){std::swap(a[i], a[i + 1]);flag = i;}}r = flag;for (int i = r - 1; i >= l; i--){if (a[i] > a[i + 1]){std::swap(a[i], a[i + 1]);flag = i;}}l = flag;}
}

算法评价
在这里插入图片描述
冒泡排序算法辅助空间复杂度为O(1),也就是说它是一个就地排序。另外,当i>i日R[i].key=R[i].key时,两者没有逆序,不会发生交换,也就是说使R[i]和R[i]的相对位置保持不变,所以冒泡排序是一种稳定的排序方法。


3.2 快速排序

Hoare版

算法思想

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

请添加图片描述
再上递归展开图:和二叉树的前序遍历差不多
请添加图片描述
算法实现

void quick_sort(int a[], int l, int r)
{if (l >= r) return;//1. 选key, 假设左边第一个为keyint keyi = l;//2. 找到key的正确位置int st = l, ed = r;while (st < ed){while (ed > st && a[ed] >= a[keyi]) --ed;while (ed > st && a[st] <= a[keyi]) ++st;std::swap(a[st], a[ed]);}//3. 将key交换到正确位置std::swap(a[st], a[keyi]);;keyi = st;//4. 继续下分quick_sort(a, l, keyi - 1);quick_sort(a, keyi + 1, r);
}

在这里插入图片描述
记住上面这三个关键点。
快速排序的时间复杂度是O(nlogn).如下:
在这里插入图片描述

上面是Hoare大佬的原版思路,但有些人认为Hoare的方法有很多小坑,于是又有许多人提出了快速排序的其他实现思路,如挖坑法,前后指针法,下面我们一一道来

挖坑法

算法思想

  1. 先将key保存,将l设置为hole
  2. 然后从右向左找 < key的数, 找到则将其放到hole里,更新hole
  3. 然后从左向右找 > key的数, 找到则将其放到hole里,更新hole
  4. 直到 l >= r, 此时hole为key应放的位置

在这里插入图片描述

算法实现

void quick_sort(int a[], int l, int r)
{if (l >= r) return;//1. 选key, 假设左边第一个为keyint key = a[l];int hole = l;//2. 找到key的正确位置int st = l, ed = r;while (st < ed){while (ed > st && a[ed] >= key) --ed;a[hole] = a[ed];hole = ed;while (ed > st && a[st] <= key) ++st;a[hole] = a[st];hole = st;}//3. 将key交换到正确位置a[hole] = key;//4. 继续下分quick_sort(a, l, hole - 1);quick_sort(a, hole + 1, r);
}
快速排序前后指针法

算法思想
在这里插入图片描述

算法实现

void quick_sort(int a[], int l, int r)
{if (l >= r) return;//1. 选key, 假设左边第一个为keyint cur, prev, keyi;prev = keyi = l;cur = prev + 1;while (cur <= r) {if (a[cur] < a[keyi] && ++prev != cur) {std::swap(a[prev], a[cur]);}cur++;}std::swap(a[keyi], a[prev]);keyi = prev;quick_sort(a, l, keyi - 1);quick_sort(a, keyi + 1, r);
}
快速排序的非递归

用栈来模拟

void quick_sort(int a[], int l, int r)
{std::stack<int> st;st.push(r);st.push(l);while (st.size()){int begin = st.top();st.pop();int end = st.top();st.pop();//单次快排过程int x = a[begin + end >> 1], i = begin - 1, j = end + 1;while (i < j){do i++; while (a[i] < x);do j--; while (a[j] > x);if (i < j) std::swap(a[i], a[j]);}//插入新的划分段if (j + 1 < end){st.push(end);st.push(j + 1);}if (begin < j){st.push(j);st.push(begin);}}
}

四、归并排序

递归版本

算法思想

基本思想:归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide andConquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

请添加图片描述
形象来讲:就是将数组拆成一个个元素,再逐渐将它们组合起来。这符合递归的特性,下面我们通过递归展开图来看。

请添加图片描述
递归展开图虽然看起来像把数组里的元素拆成了一个个新数组,但我们必须要清晰的认识到这些元素还是在原数组里。明白了这点,让我们来好好思考一下如何归并。有人说:交换一下就行了。比如上面最下面一层10 和 6归并回去的时候,大的和小的交换一下位置,不就有序了。但倒数第二层呢?4个数互相交换吗?这就有点复杂化了。
比较好的做法是创建一个临时数组tmp,将需要归并的元素通过直接插入排序插入到临时数组里面,再把临时数组拷贝回去。如下图

在这里插入图片描述
算法实现

void merge_sort(int a[], int l, int r, int tmp[])
{// 1. 终止条件if (l >= r)return;// 2. 不断递归划分int mid = l + r >> 1;merge_sort(a, l, mid, tmp);merge_sort(a, mid + 1, r, tmp);// 3. 开始归并, 左区间[l, mid] 右区间[mid+1, r] 起始位置 end = lint l1 = l, r1 = mid;int l2 = mid + 1, r2 = r;int end = l;while (l1 <= r1 && l2 <= r2){if (a[l1] <= a[l2]) tmp[end++] = a[l1++];else tmp[end++] = a[l2++];}// 3.1 左区间可能有剩余while (l1 <= r1) tmp[end++] = a[l1++];// 3.2 右区间可能有剩余while (l2 <= r2) tmp[end++] = a[l2++];// 3.2 将排序好的数组拷贝到原数组内memcpy(a + l, tmp + l, sizeof(int) * (r - l + 1));
}

非递归版本

归并过程由一一归并到二二归并,再到四四归并…直到gap > n

在这里插入图片描述
在这里插入图片描述

void merge_sort(int* a, int l, int r)
{int n = r - l + 1;int* tmp = new int[n];int gap = 1;//左右区间的大小while (gap < n){for (int i = 0; i < n; i += 2 * gap){// 开始归并, 左区间[i, i+gap-1] 右区间[i+gap, i+gap + gap-1] 起始位置 end = iint l1 = i, r1 = i + gap-1;int l2 = i + gap, r2 = i + 2 * gap - 1;int end = i;//情况1:r1 越界 表明l2,r2都越界了,直接break//情况2:l2 越界 同上,直接break//情况3: r2 越界 更改r2 = n-1//情况4:无越界 if (l2 >= n) break;if (r2 >= n) r2 = n - 1;while(l1 <= r1 && l2 <= r2){if (a[l1] <= a[l2]) tmp[end++] = a[l1++];else tmp[end++] = a[l2++];}// 左区间可能有剩余while (l1 <= r1) tmp[end++] = a[l1++];// 右区间可能有剩余while (l2 <= r2) tmp[end++] = a[l2++];//这里用end - i,不要用2*gap, 因为存在越界的情况,拷贝的大小 <= gap*2memcpy(a + i, tmp + i, sizeof(int) * (end-i));}gap *= 2;}delete[] tmp;
}

五、基数排序

算法思想

基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用,基数排序法是属于稳定性的排序,其时间复杂度为O (nlog®m),其中r为所采取的基数,而m为堆数,在某些时候,基数排序法的效率高于其它的稳定性排序法。

二种方式:

最高位优先(Most Significant Digit first)法,简称MSD法:先按k1排序分组,同一组中记录,关键码k1相等,再对各组按k2排序分成子组,之后,对后面的关键码继续这样的排序分组,直到按最次位关键码kd对各子组排序后。再将各组连接起来,便得到一个有序序列。

最低位优先(Least Significant Digit first)法,简称LSD法:先从kd开始排序,再对kd-1进行排序,依次重复,直到对k1排序后便得到一个有序序列。

算法实现 – LSD

void radix_sort(int a[], int n)
{//确定基数 -- 按个 十...排序,因此基数 0-9 共10个const int radix = 10;std::queue<int> q[radix];int mol = 10;while (1){//1. 分配for (int i = 0; i < n; i++){//1. 求key// 10013 取十位 模100,再除10int k = a[i] % mol;k /= (mol / 10);//2. 入队q[k].push(a[i]);}// 如果都分配到q[0]则表示关键字序号已经超过k1if (q[0].size() == n) break;//2. 回收int end = 0;for (int i = 0; i < radix; i++){while (q[i].size()){int t = q[i].front();q[i].pop();a[end++] = t;}}//3. 开始排序kd-1位mol *= 10;}
}

六、计数排序

算法思想

计数排序是一种非比较排序,其核心是将序列中的元素作为键存储在额外的数组空间中,而该元素的个数作为值存储在数组空间中,通过遍历该数组排序。

在这里插入图片描述
算法实现

void count_sort(int a[], int n)
{int Max = a[0];for (int i = 1; i < n; i++){Max = std::max(Max, a[i]);}int* count = new int[Max]{0};for (int i = 0; i < n; i++){count[a[i]]++;}int end = 0;for (int i = 0; i < Max; i++){while (count[i]){a[end++] = i;count[i]--;}}
}

算法评价

时间复杂度:O (N+Max)

空间复杂度:O (Max)

内排序总结

排序方法时间复杂度空间复杂度稳定性
平均情况最坏情况最好情况
直接插入排序O( n 2 n^2 n2)O( n 2 n^2 n2)O( n n n)O(1)稳定
折半插入排序O( n 2 n^2 n2)O( n 2 n^2 n2)O( n n n)O(1)稳定
希尔排序O( n 1.3 n^{1.3} n1.3)O(1)不稳定
简单选择排序O( n 2 n^2 n2)O( n 2 n^2 n2)O( n 2 n^2 n2)O(1)不稳定
堆排序O( n l o g 2 n nlog_2{n} nlog2n)O( n l o g 2 n nlog_2{n} nlog2n)O( n l o g 2 n nlog_2{n} nlog2n)O(1)不稳定
冒泡排序O( n 2 n^2 n2)O( n 2 n^2 n2)O( n 2 n^2 n2)O(1)稳定
快速排序O( n l o g 2 n nlog_2{n} nlog2n)O( n 2 n^2 n2)O( n l o g 2 n nlog_2{n} nlog2n)O( l o g 2 n log_2{n} log2n)不稳定
归并排序O( n l o g 2 n nlog_2{n} nlog2n)O( n l o g 2 n nlog_2{n} nlog2n)O( n l o g 2 n nlog_2{n} nlog2n)O( n n n)稳定
基数排序O( d ( n + r ) d(n+r) d(n+r))O( d ( n + r ) d(n+r) d(n+r))O( d ( n + r ) d(n+r) d(n+r))O( r r r)稳定
计数排序O( n n n)O( n n n)O( n n n)O( r a n g e range range)不稳定

相关文章:

【算法】排序算法总结

文章目录 内排序一、插入排序1.1 直接插入排序1.2 折半插入排序1.3 希尔排序 二、选择排序2.1 简单选择排序2.2 堆排序 三、交换排序3.1 冒泡排序3.2 快速排序Hoare版挖坑法快速排序前后指针法快速排序的非递归 四、归并排序递归版本非递归版本 五、基数排序六、计数排序内排序…...

双11来了,云计算优惠大集合

京东云 2C2G强烈推荐 连接直达...

13. MapReduce自定义OutputFormat

一. OutputFormat简介 OutputFormat是MapReduce输出的基类&#xff0c;所有MapReduce输出都实现了OutputFormat接口&#xff0c;它接收ReduceTask产生的数据&#xff0c;然后将结果按照指定格式输出。 在MapReduce中&#xff0c;如果不指定&#xff0c;默认使用的是TextOutpu…...

Javase——正则表达式

正则表达式的相关使用 public static void main(String[] args) {//校验QQ号 System.out.println("3602222222".matches("[1-9][0-9]{4,}"));// 校验18位身份证号 System.out.println("11050220240830901X".matches("^([0-9]){7,18}…...

云原生文件系统之JuiceFS

JuiceFS 是一个分布式文件系统&#xff0c;专门为云原生环境设计&#xff0c;支持大规模数据存储和处理&#xff0c;特别适用于处理对象存储和大数据应用。JuiceFS 将元数据和数据分离&#xff0c;元数据保存在数据库中&#xff0c;而文件数据则存储在对象存储中&#xff0c;提…...

C++:输入和输出

一 . DEV C的下载和安装 二 . 第一个C程序 三 . 输出流 四 . 初始的数据类型 3.1、整型变量 3.2、双精度浮点数变量 3.3、字符型变量 3.4、字符串变量 3.5、无符号整型变量 五、输入流...

vue的路由的两种模式 hash与history 详细讲解

文章目录 1. Hash 模式工作原理优点缺点使用示例 2. History 模式工作原理优点缺点服务器配置示例使用示例 总结 Vue Router 是 Vue.js 的官方路由管理器&#xff0c;它支持多种路由模式&#xff0c;其中最常用的两种是 hash 模式和 history 模式。下面我们详细讲解这两种模式的…...

【Linux操作系统】进程间通信之匿名管道与命名管道

目录 一、进程间通信的目的&#xff1a;二、进程间通信的种类三、什么是管道四、匿名管道&#xff08;共同祖先的进程之间&#xff09;1.匿名管道的使用2.匿名管道举例3.匿名管道的原理4.管道特点5.管道的读写规则1. 当管道内没有数据可读时2.当管道满的时候3.管道端被关闭4.数…...

慢sql优化和Explain解析

要想程序跑的快&#xff0c;sql优化不可懈怠&#xff01;今日来总结一下常用的慢sql的分析和优化的方法。 1、慢sql的执行分析&#xff1a; 大家都知道分析一个sql语句执行效率的方法是用explain关键词&#xff1a; 举例&#xff1a;sql:select * from test where bussiness_…...

ALIGN_ Tuning Multi-mode Token-level Prompt Alignment across Modalities

文章汇总 当前的问题 目前的工作集中于单模提示发现&#xff0c;即一种模态只有一个提示&#xff0c;这可能不足以代表一个类[17]。这个问题在多模态提示学习中更为严重&#xff0c;因为视觉和文本概念及其对齐都需要推断。此外&#xff0c;仅用全局特征来表示图像和标记是不…...

【Java SE】代码注释

代码注释 注释&#xff08;comment&#xff09;是用于说明解释程序的文字&#xff0c;注释的作用在于提高代码的阅读性&#xff08;可读性&#xff09;。Java中的注释类型包括3种&#xff0c;分别是&#xff1a; 单行注释多行注释文档注释 ❤️ 单行注释 基本格式&#xff…...

如何在算家云搭建Llama3-Factory(智能对话)

一、Llama3-Factory 简介 当地时间 4 月 18 日&#xff0c;Meta 在官网上宣布公布了旗下最新大模型 Llama 3。目前&#xff0c;Llama 3 已经开放了 80 亿&#xff08;8B&#xff09;和 700 亿&#xff08;70B&#xff09;两个小参数版本&#xff0c;上下文窗口为 8k。Llama3 是…...

操作数据表

创建表 创建表语法&#xff1a; CREATE TABLE table_name ( field1 datatype [COMMENT 注释内容], field2 datatype [COMMENT 注释内容], field3 datatype ); 注意&#xff1a; 1. 蓝色字体为关键字 2. CREATE TABLE 是创建数据表的固定关键字&#xff0c;表…...

C# 实现进程间通信的几种方式(完善)

目录 引言 一、基本概念 二、常见的IPC方法 1. 管道&#xff08;Pipes&#xff09; 2. 共享内存&#xff08;Shared Memory&#xff09; 3. 消息队列&#xff08;Message Queues&#xff09; 4. 套接字&#xff08;Sockets&#xff09; 5. 信号量&#xff08;Semaphore…...

MySQL Workbench Data Import Wizard:list index out of range

MySQL Workbench的Data Import Wizard功能是用python实现的&#xff0c;MySQL Workbench自带了一个python&#xff0c;数据导入的时候出现错误提示 22:55:51 [ERR][ pymforms]: Unhandled exception in Python code: Traceback (most recent call last): File "D…...

微信支付宝小程序SEO优化的四大策略

在竞争激烈的小程序市场中&#xff0c;高搜索排名意味着更多的曝光机会和潜在用户。SEO即搜索引擎优化&#xff0c;对于小程序而言&#xff0c;主要指的是在微信小程序商店中提高搜索排名&#xff0c;从而增加曝光度和用户访问量。有助于小程序脱颖而出&#xff0c;提升品牌知名…...

AutoDIR: Automatic All-in-One Image Restoration with Latent Diffusion论文阅读笔记

AutoDIR: Automatic All-in-One Image Restoration with Latent Diffusion 论文阅读笔记 这是ECCV2024的论文&#xff0c;作者单位是是港中文和上海AI Lab 文章提出了一个叫AutoDIR的方法&#xff0c;包括两个关键阶段&#xff0c;一个是BIQA&#xff0c;基于vision-language…...

SQLite 数据库设计最佳实践

SQLite特点 SQLite是一款功能强大的 轻量级嵌入式数据库 ,具有以下显著特点: 体积小 :最低配置仅需几百KB内存,适用于资源受限环境。 高性能 :访问速度快,运行效率高于许多开源数据库。 高度可移植 :兼容多种硬件和软件平台。 零配置 :无需复杂设置,开箱即用。 自给自…...

【论文精读】ID-like Prompt Learning for Few-Shot Out-of-Distribution Detection

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;论文精读_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 注&#xff1a;下文…...

Android 10.0 根据包名禁用某个app的home事件

1.前言 在10.0的系统rom定制化开发中,在某些app中,需要禁用home事件,在普通的app中又无法 禁用home事件,所以就需要从系统中来根据包名禁用home事件了,接下来分析下 系统中处理home事件的相关流程 2.根据包名禁用某个app的home事件的核心类 frameworks/base/services/c…...

Rust 文档生成与发布

目录 第三节 文档生成与发布 1. 使用 RustDoc 生成项目文档 1.1 RustDoc 的基本使用 1.2 文档注释的格式与实践 1.3 生成文档的其他选项 1.4 在 CI/CD 中生成文档 2. 发布到 crates.io 的步骤与注意事项 2.1 创建 crates.io 账户 2.2 配置 Cargo.toml 2.3 生成发布版…...

【C++动态规划】有效括号的嵌套深度

本文涉及知识点 C动态规划 LeetCode1111. 有效括号的嵌套深度 有效括号字符串 定义&#xff1a;对于每个左括号&#xff0c;都能找到与之对应的右括号&#xff0c;反之亦然。详情参见题末「有效括号字符串」部分。 嵌套深度 depth 定义&#xff1a;即有效括号字符串嵌套的层…...

2024年优秀的天气预测API

准确、可操作的天气预报对于许多组织的成功至关重要。 事实上&#xff0c;在整个行业中&#xff0c;天气条件会直接影响日常运营&#xff0c;包括航运、按需、能源和供应链&#xff08;仅举几例&#xff09;。 以公用事业为例。根据麦肯锡的数据&#xff0c;在 1.4 年的时间里…...

Android和iOS有什么区别?

Android 和 iOS 有以下区别&#xff1a; 开发者与所属公司&#xff1a; Android&#xff1a;由谷歌公司开发以及开放手机联盟维护。它是基于 Linux 内核和其他开源软件的修改版本&#xff0c;代码开源程度较高&#xff0c;许多厂商都可以基于 Android 源代码进行深度定制和开发…...

NVR小程序接入平台/设备EasyNVR多个NVR同时管理多平台级联与上下级对接的高效应用

政务数据共享平台的建设正致力于消除“信息孤岛”现象&#xff0c;打破“数据烟囱”&#xff0c;实现国家、省、市及区县数据的全面对接与共享。省市平台的“级联对接”工作由多级平台共同构成&#xff0c;旨在满足跨部门、跨层级及跨省数据共享的需求&#xff0c;推动数据流通…...

Spring Cloud Sleuth(Micrometer Tracing +Zipkin)

分布式链路追踪 分布式链路追踪技术要解决的问题&#xff0c;分布式链路追踪&#xff08;Distributed Tracing&#xff09;&#xff0c;就是将一次分布式请求还原成调用链路&#xff0c;进行日志记录&#xff0c;性能监控并将一次分布式请求的调用情况集中展示。比如各个服务节…...

人工智能:机遇与挑战

人工智能&#xff08;AI&#xff09;作为当今世界科技发展的前沿领域&#xff0c;正在以前所未有的速度和规模影响着我们的生活和工作方式。AI技术的应用前景广阔&#xff0c;从医疗健康到金融服务&#xff0c;从教育到交通&#xff0c;再到娱乐和家庭生活&#xff0c;AI正在逐…...

mac电脑设置crontab定时任务,以及遇到的问题解决办法

crontab常用命令 crontab -u user&#xff1a;用来设定某个用户的crontab服务&#xff1b; crontab file&#xff1a;file是命令文件的名字,表示将file做为crontab的任务列表文件并载入crontab。如果在命令行中没有指定这个文件&#xff0c;crontab命令将接受标准输入&#xf…...

Backtrader 数据篇 02

Backtrader 数据篇 本系列是使用Backtrader在量化领域的学习与实践&#xff0c;着重介绍Backtrader的使用。Backtrader 中几个核心组件&#xff1a; Cerebro&#xff1a;BackTrader的基石&#xff0c;所有的操作都是基于Cerebro的。Feed&#xff1a;将运行策略所需的基础数据…...

视频转场素材资源网站分享

视频剪辑者常常为找不到合适的转场素材而苦恼。合适的转场素材能让视频更流畅&#xff0c;给观众带来惊喜。下面就为大家介绍几个宝藏网站&#xff0c;提供丰富的转场剪辑素材&#xff0c;让你的视频瞬间高大上。 蛙学网 首先重磅推荐蛙学网&#xff0c;堪称视频素材界的“翘楚…...

沈阳好的男科医院是哪一家/站长seo查询

描述 小新经常陪小白去公园玩&#xff0c;也就是所谓的遛狗啦…在小新家附近有一条“公园路”&#xff0c;路的一边从南到北依次排着n个公园&#xff0c;小白早就看花了眼&#xff0c;自己也不清楚该去哪些公园玩了。 一开始&#xff0c;小白就根据公园的风景给每个公园打了分-…...

b2b开发/seo 网站优化推广排名教程

接口测试的目的是为了测试接口&#xff08;听起来怪怪的&#xff09;&#xff0c;尤其是那些与系统相关联的外部接口&#xff0c;测试的重点是要检查数据的交换&#xff0c;传递和控制管理过程&#xff0c;还包括处理的次数。本文主要介绍了接口测试用例类型&#xff0c;让我们…...

博客园网站开发/百度一下网页版浏览器

https://blog.csdn.net/q5706503/article/details/82910428 首先要明确的是JAVA中没有引用传递, 全部是按值调用 令大家所费解的 当对象引用作为参数时 函数为什么能修改真实的对象呢?这不是引用传递的特征吗? 尤其先学习C再学习JAVA的同学(比如说我自己)会这样认为, 用…...

国内网站制作特点/bt磁力

插件可以在http://addons.maxthon.cn/item/index/id/289下载。 支持常用微博功能&#xff0c;例如自动更新、发表、转发、评论等等。 功能 1、支持自动更新、发表、转发、评论、新未读消息通知等常用功能。 2、支持每个浏览器账号使用不同的新浪微博账号登录。 3、支持微博信…...

做网站属于程序员吗/百度竞价推广有哪些优势

春华秋衣请注意&#xff0c;我们正在逐行将流程输出读取到StringBuilder。由于该try-with-resources语句&#xff0c;我们不需要手动关闭流。该ProcessBuilder班让我们提交程序名和参数&#xff0c;以它的构造函数的数量。import java.io.BufferedReader;import java.io.IOExce…...

沈阳定制网站/搜索引擎优化方法总结

今天做了很多的工作&#xff0c;前段时间的问题换了种方式解决掉了。完成了各个界面的servlet跳转&#xff0c;招聘信息的写入读取与显示。转载于:https://www.cnblogs.com/messi2017/p/8098058.html...