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

数据结构奇妙旅程之七大排序

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱
ʕ̯•͡˔•̯᷅ʔ大家好,我是xiaoxie.希望你看完之后,有不足之处请多多谅解,让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客
本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN 如需转载还请通知˶⍤⃝˶
个人主页:xiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客
系列专栏:xiaoxie的JAVA系列专栏——CSDN博客●'ᴗ'σσணღ*
我的目标:"团团等我💪( ◡̀_◡́ ҂)" 

( ⸝⸝⸝›ᴥ‹⸝⸝⸝ )欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​+关注(互三必回)!

 

一.排序的概念

  排序的概念
排序 :所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。
稳定性 :假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持
不变,即在原序列中, r[i]=r[j] ,且 r[i] r[j] 之前,而在排序后的序列中, r[i] 仍在 r[j] 之前,则称这种排序算法是稳 定的;否则称为不稳定的。
内部排序 :数据元素全部放在内存中的排序。
外部排序 :数据元素太多不能同时放在内存中,根据排序过程的要求不能在内外存之间移动数据的排序。

二.插入排序

1.直接插入排序

直接插入排序是一种简单的插入排序法,其基本思想是:
把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到 一个新的有序序列 。实际中我们玩扑克牌时,就用了插入排序的思想。

1.过程

假设我们有一个数组array{15,87,63,5,98,23,1,82,10} ;我们如果使用直接插入排序的过程如下:

原始:    15  87  63 5 98 23 1 82 10

第一趟: 15  87  63 5 98 23 1 82 10

第二趟: 15  87  63 5 98 23 1 82 10

第三趟:15   63  87  5 98 23 1 82 10

......

第n(9)趟:  1 5 10 15 23 63 82 87 98

2.代码 

我们可以把他写为Java代码如下:

public class Sort {public static void insertSort(int[] array) {insert(array,0, array.length-1);}private static void insert(int[] array,int start,int end) {for (int i = start+1; i <= end; i++) {int tmp = array[i];int j = i-1;for (;j >= start; j--) {if(array[j] > tmp) {array[j+1] = array[j];}else {break;}}array[j+1] = tmp;}}
}

C++版本如下

#include <iostream>
using namespace std;class Sort {
public:static void insertSort(int array[], int size) {insert(array, 0, size-1);}private:static void insert(int array[], int start, int end) {for (int i = start+1; i <= end; i++) {int tmp = array[i];int j = i-1;for (; j >= start; j--) {if (array[j] > tmp) {array[j+1] = array[j];} else {break;}}array[j+1] = tmp;}}
};

3.时间复杂度

最好情况下:

直接插入排序在最好情况下也就是在数据都有序的情况下为O(n)

最坏情况下:

直接插入排序的最坏情况也就是在数据为逆序的情况下为O(n^2)

4.空间复杂度

因为直接插入排序是在本数组中实现的没有借用辅助空间所以为O(1)

5.稳定性

该算法为稳定

值得注意的是元素集合越接近有序,直接插入排序算法的时间效率越高。

2. 希尔排序( 缩小增量排序 )

希尔排序法又称缩小增量法。希尔排序法的基本思想是: 将待排序的数组按照一定的增量分组,对每个分组进行直接插入排序,然后逐步缩小增量,重复进行分组和直接插入排序的操作,直到增量缩小为1,最后进行最后一次直接插入排序。

1.过程

2.代码

java

public class Sort {public static void shellSort(int[] array) {int gap = array.length;while (gap > 1) {gap /= 2;Shell(array,gap);}}private static void Shell(int[] array,int gap) {for (int i = gap; i < array.length; i++) {int tmp = array[i];int j = i-gap;for (; j >= 0; j-=gap) {if(array[j] > tmp) {array[j+gap] = array[j];}else {break;}}array[j+gap] = tmp;}}
}

C++

#include <iostream>
using namespace std;void shellSort(int array[], int size) {int gap = size;while (gap > 1) {gap /= 2;Shell(array, size, gap);}
}void Shell(int array[], int size, int gap) {for (int i = gap; i < size; i++) {int tmp = array[i];int j = i - gap;for (; j >= 0; j -= gap) {if (array[j] > tmp) {array[j + gap] = array[j];} else {break;}}array[j + gap] = tmp;}
}

 3.时间复杂度

希尔排序的时间复杂度不好计算,因为 gap 的取值方法很多,导致很难去计算,因此在不同的书中给出的希尔排序的时间复杂度都不固定
《数据结构 (C 语言版 ) --- 严蔚敏

《数据结构-用面向对象方法与C++描述》--- 殷人昆

 

 4.空间复杂度

因为希尔排序是直接插入排序的优化所以是在本数组中实现的没有借用辅助空间所以为O(1)

5.稳定性

不稳定 

6.希尔排序的特性

1. 希尔排序是对直接插入排序的优化。
2. gap > 1 时都是预排序,目的是让数组更接近于有序。当 gap == 1 时,数组已经接近有序的了,这样就会很快。这样整体而言,可以达到优化的效果。

三.选择排序

3.直接选择排序

每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完 。

1.过程

1.在元素集合array[i]--array[n-1]中选择关键码最大()的数据元素
2.若它不是这组元素中的最后一个(第一个)元素,则将它与这组元素中的最后一个(第一个)元素交换
3.在剩余的array[i]--array[n-2]array[i+1]--array[n-1])集合中,重复上述步骤,直到集合剩余1个元素

2.代码

Java

public class Sort {public static void selectSort(int[] array) {select(array,0, array.length-1);}private static void select(int[] array,int start,int end) {for (int i = 0; i <= end ; i++) {int minIndex = i;for (int j = i+1; j <= end ; j++) {if(array[j] < array[minIndex]) {minIndex = j;}}swap(array,i,minIndex);}}private static void swap(int[]array,int i,int j) {int tmp = array[i];array[i] = array[j];array[j] = tmp;}
}
C++
#include <iostream>
using namespace std;
void selectSort(int array[], int size) {select(array, 0, size - 1);
}void select(int array[], int start, int end) {for (int i = 0; i <= end; i++) {int minIndex = i;for (int j = i + 1; j <= end; j++) {if (array[j] < array[minIndex]) {minIndex = j;}}swap(array, i, minIndex);}
}void swap(int array[], int i, int j) {int tmp = array[i];array[i] = array[j];array[j] = tmp;
}

3.时间复杂度

最好情况和最坏情况都为:O(n^2) 所以不是很推荐使用

4.空间复杂度

因为直接选择排序是在本数组中实现的没有借用辅助空间所以为O(1)

5.稳定性

不稳定

直接选择排序思考非常好理解,但是效率不是很好。实际中很少使用

4.堆排序(需要重点掌握)

堆排序 (Heapsort) 是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。它是通过堆来进行选择数据。 需要注意的是排升序要建大堆,排降序建小堆

1.过程

2.代码

Java

private static void swap(int[]array,int i,int j) {int tmp = array[i];array[i] = array[j];array[j] = tmp;}public static  void heapSort(int[] array) {crateHeap(array);//首先创建大根堆int end = array.length-1;while (end >= 0) {swap(array,0,end);siftDown(array,0,end);end--;}}// 创建大根堆private static void crateHeap(int[] array) {for (int parent = (array.length-1-1)/2; parent >= 0; parent--) {siftDown(array,parent,array.length);}}// 向下调整private static void siftDown(int[] array,int parent,int len) {int child = 2*parent+1;while (child < len) {if(child+1 < len && array[child] < array[child+1]) {child++;}if(array[child] > array[parent]) {swap(array,child,parent);parent = child;child = 2*parent+1;}else {break;}}}

C++

#include <iostream>
using namespace std;void swap(int array[], int i, int j) {int tmp = array[i];array[i] = array[j];array[j] = tmp;
}void heapSort(int array[], int length) {createHeap(array, length); // 首先创建大根堆int end = length - 1;while (end >= 0) {swap(array, 0, end);siftDown(array, 0, end);end--;}
}// 创建大根堆
void createHeap(int array[], int length) {for (int parent = (length - 2) / 2; parent >= 0; parent--) {siftDown(array, parent, length);}
}// 向下调整
void siftDown(int array[], int parent, int len) {int child = 2 * parent + 1;while (child < len) {if (child + 1 < len && array[child] < array[child + 1]) {child++;}if (array[child] > array[parent]) {swap(array, child, parent);parent = child;child = 2 * parent + 1;} else {break;}}
}

 3.时间复杂度

 因为堆是一颗完全二叉树所以他的时间复杂度为:O(n*logN)

4.空间复杂度

没有借助辅助空间所以空间复杂度为:O(1)

5.稳定性

不稳定

四.交换排序

基本思想:所谓交换,就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置,交换排序的特点是: 将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动

5.冒泡排序

1.过程

2.代码

Java

 private static void swap(int[]array,int i,int j) {int tmp = array[i];array[i] = array[j];array[j] = tmp;}public static void bubbleSort(int[] array) {//10个元素遍历9趟for (int i = 0; i < array.length-1; i++) {boolean flag = false;for (int j = 0; j < array.length-1-i; j++) {if(array[j] > array[j+1]) {swap(array,j,j+1);flag = true;}}//没有交换就证明有序if(flag == false) {return;}}}

C++

#include <iostream>
using namespace std;void swap(int array[], int i, int j) {int tmp = array[i];array[i] = array[j];array[j] = tmp;
}void bubbleSort(int array[], int length) {// 对于10个元素,遍历9趟for (int i = 0; i < length - 1; i++) {bool flag = false;for (int j = 0; j < length - 1 - i; j++) {if (array[j] > array[j + 1]) {swap(array, j, j + 1);flag = true;}}// 若没有交换发生,则证明数组已有序if (!flag) {return;}}
}

3.时间复杂度

最好情况下:

冒泡排序在最好情况下也就是在数据都有序的情况下为O(n)

最坏情况下:

冒泡排序的最坏情况也就是在数据为逆序的情况下为O(n^2)

4.空间复杂度

没有借助辅助空间所以空间复杂度为:O(1)

5.稳定性

稳定

6.快速排序(重点掌握)

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

1.1Hoare法过程

需要注意的是快速排序需要进行优化,防止出现像{1,2,3,4,5,6,7,8,9}这样的情况如果出现这种情况,二叉树会变成一颗斜树,降低排序速率这时候我们需要使用1 .三数取中法选基准值
如果 . 递归到小的子区间时,可以考虑使用插入排序 (这里就不优化了感兴趣的可以自己下去实现)

1.2Hoare法代码

  private static void swap(int[]array,int i,int j) {int tmp = array[i];array[i] = array[j];array[j] = tmp;}public static void quickSort(int[] array) {quick(array,0, array.length-1);}private static void quick(int[] array,int left,int right) {if(right-left <= 1) {return;}//三数取中法int index = middleNum(array,left,right);swap(array,left,index);int pivot = partitionHoare(array,left,right);quick(array,left,pivot-1);//递归左边quick(array,pivot+1,right);//递归右边}//三数取中private static int middleNum(int[] array,int start,int end) {int mid = start+((end-start)>>1);if(array[start] <  array[end]) {if(array[mid] > array[end]) {return end;} else if (array[mid] < array[start]) {return start;}else {return mid;}}else {if(array[mid] < array[end]) {return end;} else if (array[mid] > array[start]) {return start;}else {return mid;}}}//获取基准值的位置使用Hoare法private static int partitionHoare(int[] array,int left ,int right) {int tmp = array[left];//基准值int i = left;//记录下来基准值开始的下标while (left < right) {while (left < right && array[right] >= tmp) {right--;}while (left < right && array[left] <= tmp) {left++;}swap(array,left,right);}swap(array,left,i);return left;}

C++版本

#include <iostream>
using namespace std;void swap(int array[], int i, int j) {int tmp = array[i];array[i] = array[j];array[j] = tmp;
}void quickSort(int array[], int length) {quick(array, 0, length - 1);
}void quick(int array[], int left, int right) {if (right - left <= 1) {return;}// 三数取中法int index = middleNum(array, left, right);swap(array, left, index);int pivot = partitionHoare(array, left, right);quick(array, left, pivot - 1); // 递归左边quick(array, pivot + 1, right); // 递归右边
}// 三数取中
int middleNum(int array[], int start, int end) {int mid = start + ((end - start) >> 1);if (array[start] < array[end]) {if (array[mid] > array[end]) {return end;} else if (array[mid] < array[start]) {return start;} else {return mid;}} else {if (array[mid] < array[end]) {return end;} else if (array[mid] > array[start]) {return start;} else {return mid;}}
}// 获取基准值的位置使用Hoare法
int partitionHoare(int array[], int left, int right) {int tmp = array[left]; // 基准值int i = left; // 记录下来基准值开始的下标while (left < right) {while (left < right && array[right] >= tmp) {right--;}while (left < right && array[left] <= tmp) {left++;}swap(array, left, right);}swap(array, left, i);return left;
}

2.1挖坑法过程(重点掌握)考试选择题过程一般使用挖坑法

2.2 挖坑法代码(重点掌握)

Java

 private static void swap(int[]array,int i,int j) {int tmp = array[i];array[i] = array[j];array[j] = tmp;}public static void quickSort(int[] array) {quick(array,0, array.length-1);}private static void quick(int[] array,int left,int right) {if(right-left <= 1) {return;}//三数取中法int index = middleNum(array,left,right);swap(array,left,index);int pivot = partition(array,left,right);quick(array,left,pivot-1);//递归左边quick(array,pivot+1,right);//递归右边}//三数取中private static int middleNum(int[] array,int start,int end) {int mid = start+((end-start)>>1);if(array[start] <  array[end]) {if(array[mid] > array[end]) {return end;} else if (array[mid] < array[start]) {return start;}else {return mid;}}else {if(array[mid] < array[end]) {return end;} else if (array[mid] > array[start]) {return start;}else {return mid;}}}//获取基准值的位置使用挖坑法private static int partition(int[] array,int left ,int right) {int tmp = array[left];//记录基准值while (left < right) {while (left < right && array[right] >=  tmp) {right--;}array[left] = array[right];while (left < right && array[left] <= tmp) {left++;}array[right] = array[left];}array[left] = tmp;// 将基准值放入正确位置return left;}

C++

#include <iostream>
using namespace std;void swap(int array[], int i, int j) {int tmp = array[i];array[i] = array[j];array[j] = tmp;
}void quickSort(int array[], int length) {quick(array, 0, length - 1);
}void quick(int array[], int left, int right) {if (right - left <= 1) {return;}// 三数取中法int index = middleNum(array, left, right);swap(array, left, index);int pivot = partition(array, left, right);quick(array, left, pivot - 1); // 递归左边quick(array, pivot + 1, right); // 递归右边
}// 三数取中
int middleNum(int array[], int start, int end) {int mid = start + ((end - start) >> 1);if (array[start] < array[end]) {if (array[mid] > array[end]) {return end;} else if (array[mid] < array[start]) {return start;} else {return mid;}} else {if (array[mid] < array[end]) {return end;} else if (array[mid] > array[start]) {return start;} else {return mid;}}
}// 获取基准值的位置使用挖坑法
int partition(int array[], int left, int right) {int pivot = array[left]; // 基准值while (left < right) {while (left < right && array[right] >= pivot) {right--;}array[left] = array[right];while (left < right && array[left] <= pivot) {left++;}array[right] = array[left];}array[left] = pivot; // 将基准值放入正确位置return left;
}

3.时间复杂度

最好情况下数据为无序的时候为O(n*logN)

最坏情况下数据为有序或者是逆序的时候为O(n^2)。 

4.空间复杂度

在递归调用过程中,需要使用O(log n)的栈空间来存储递归调用的上下文信息所以空间复杂度为:O(logN)

5.稳定性

不稳定

7.归并排序(重点掌握)

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

1.过程

2.代码

Java

public static void mergeSort(int[] array) {mergeFunc(array,0,array.length-1);}private static void mergeFunc(int[] array,int left,int right) {if(left >= right) {return;}int mid = left + ((right-left) >> 1);//开始分解mergeFunc(array,left,mid);mergeFunc(array, mid+1, right);//开始合并merge(array,left,right,mid);}private static void merge(int[] array,int left,int right,int mid) {int s1 = left;int e1 = mid;int s2 = mid+1;int e2 = right;int[] tmp = new int[right-left+1];//创建一个临时数组来储存数据int k = 0;//临时数组下标while (s1 <= e1 && s2 <= e2) {if(array[s1] <= array[s2]) {tmp[k++] = array[s1++];}else {tmp[k++] = array[s2++];}}//看那个数组还有数据就拷贝过去while (s1 <= e1) {tmp[k++] = array[s1++];}while (s2 <= e2) {tmp[k++] = array[s2++];}//3.拷贝到源数组for (int i = 0; i < k; i++) {array[i+left] = tmp[i];}}

C++

#include <iostream>
using namespace std;void mergeSort(int array[], int length) {mergeFunc(array, 0, length - 1);
}void mergeFunc(int array[], int left, int right) {if (left >= right) {return;}int mid = left + ((right - left) >> 1);// 开始分解mergeFunc(array, left, mid);mergeFunc(array, mid + 1, right);// 开始合并merge(array, left, right, mid);
}void merge(int array[], int left, int right, int mid) {int s1 = left;int e1 = mid;int s2 = mid + 1;int e2 = right;int tmp[right - left + 1]; // 创建一个临时数组来储存数据int k = 0; // 临时数组下标while (s1 <= e1 && s2 <= e2) {if (array[s1] <= array[s2]) {tmp[k++] = array[s1++];} else {tmp[k++] = array[s2++];}}// 看那个数组还有数据就拷贝过去while (s1 <= e1) {tmp[k++] = array[s1++];}while (s2 <= e2) {tmp[k++] = array[s2++];}// 3.拷贝到源数组for (int i = 0; i < k; i++) {array[i + left] = tmp[i];}
}

 3.时间复杂度

时间复杂度为O(n*logN)

4.空间复杂度

因为需要借助临时数组所以空间复杂度为O(n)

5.稳定性

稳定

五.各个排序算法的时间复杂度和空间复杂度以及稳定性总结

以上就是关于基于比较排序的所以的内容了,如果有帮助到你,创作不易希望可以给博主一个关注,感谢你的阅读,希望能够对你有所帮助 

 

相关文章:

数据结构奇妙旅程之七大排序

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN …...

【JavaScript】Generator

MDN-Generator Generator对象由生成器函数返回&#xff0c;并且它符合可迭代协议和迭代器协议。 Generator-核心语法 核心语法: 定义生成器函数获取generator对象yield表达式的使用通过for of获取每一个yield的值 // 1. 通过function* 创建生成器函数 function* foo() {//…...

河南省考后天网上确认,请提前准备证件照哦

✔报名时间&#xff1a;2024年1月18号一1月24号 ✔报名确认和缴费&#xff1a;2024年1月 31号一2月4号 ✔准考证打印&#xff1a;2024年3月12号一3月17号 ✔笔试时间&#xff1a;2024年3月16日-2024年3月17日。 ✔面试时间&#xff1a;面试时间拟安排在2024年5月中旬 报名网址&…...

【前端】防抖和节流

防抖 防抖用于限制连续触发的事件的执行频率。当一个事件被触发时,防抖会延迟一定的时间执行对应的处理函数。如果在延迟时间内再次触发了同样的事件,那么之前的延迟执行将被取消,重新开始计时。 总结:在单位时间内频繁触发事件,只有最后一次生效 场景 :用户在输入框输…...

【网络】:网络套接字(UDP)

网络套接字 一.网络字节序二.端口号三.socket1.常见的API2.封装UdpSocket 四.地址转换函数 网络通信的本质就是进程间通信。 一.网络字节序 我们已经知道,内存中的多字节数据相对于内存地址有大端和小端之分, 磁盘文件中的多字节数据相对于文件中的偏移地址也有大端小端之分,网…...

Linux编程 1/2 数据结构

数据结构: 程序 数据结构 算法 1.数据结构: 1.时间复杂度: 数据量的增长与程序运行时间增长所呈现的比例函数,则称为时间渐进复杂度函数简称时间复杂度 O(c) > O(logn)> O(n) > O(nlogn) > O(n^2) > O(n^3) > O(2^n) 2.空间复杂度: 2.类…...

【UE Niagara】实现闪电粒子效果的两种方式

目录 效果 步骤 方式一&#xff08;网格体渲染器&#xff09; &#xff08;1&#xff09;添加网格体渲染器 &#xff08;2&#xff09;修改粒子显示方向 &#xff08;3&#xff09;添加从上到下逐渐显现的效果 &#xff08;4&#xff09;粒子颜色变化 方式二&#xff0…...

js数组/对象的深拷贝与浅拷贝

文章目录 一、js中的深拷贝和浅拷贝二、浅拷贝1、Object.assign()2、利用es6扩展运算符&#xff08;...&#xff09; 二、深拷贝1、JSON 序列化和反序列化2、js原生代码实现3、使用第三方库lodash等 四、总结 一、js中的深拷贝和浅拷贝 在JS中&#xff0c;深拷贝和浅拷贝是针对…...

HCIA学习第六天:OSPF:开放式最短路径优先协议

OSPF&#xff1a;开放式最短路径优先协议 无类别链路状态IGP动态路由协议 1.距离矢量协议&#xff1a;运行距离矢量协议的路由器会周期性的泛洪自己的路由表。通过路由的交互&#xff0c;每台路由器从相邻的路由器学习到路由&#xff0c;并且加载进自己的路由表中&#xff1b…...

从四个方面来解决企业在项目管理中遇到的各类问题

案例背景&#xff1a;某建筑集团有限公司成立于1949年&#xff0c;拥有国家房屋建筑工程施工总承包一级、建筑装修装饰工程专业承包一级、市政公用工程施工总承包一级资质。是一家集建筑施工、设备安装、装饰装潢、仿古建筑、房地产开发、建材试验为一体的具有综合生产能力的建…...

使用代码取大量2*2像素图片各通道均值,存于Excel文件中。

任务是取下图RGB各个通道的均值及标签&#xff08;R, G&#xff0c;B&#xff0c;Label&#xff09;,其中标签由图片存放的文件夹标识。由于2*2像素图片较多&#xff0c;所以将结果放置于Excel表格中&#xff0c;之后使用SVM对他们进行分类。 from PIL import Image import os …...

React16源码: React中commit阶段的commitBeforeMutationLifecycles的源码实现

commitBeforeMutationLifecycles 1 &#xff09;概述 在 react commit 阶段的 commitRoot 第一个while循环中调用了 commitBeforeMutationLifeCycles现在来看下&#xff0c;里面发生了什么 2 &#xff09;源码 回到 commit 阶段的第一个循环中&#xff0c;在 commitRoot 函数…...

压制二元组的总价值

压制二元组的总价值 对于每一个 a i a_i ai​, 看它能压制它前面的多少个元素, 那么它对总价值的贡献就是: 在a数组中: a i a_i ai​压制了x个数, 贡献为: x ∗ i x*i x∗i被 a i a_i ai​所压制的所有数在 a a a中的下标和为 y y y, 贡献为 − y -y −y 树状数组来求: 为了…...

【习题】保存应用数据

判断题 1. 首选项是关系型数据库。 错误(False) 2. 应用中涉及到Student信息&#xff0c;如包含姓名&#xff0c;性别&#xff0c;年龄&#xff0c;身高等信息可以用首选项来存储。 错误(False) 3. 同一应用或进程中每个文件仅存在一个Preferences实例。 正确(True) 单选题 …...

Flask框架小程序后端分离开发学习笔记《5》简易服务器代码

Flask框架小程序后端分离开发学习笔记《5》 Flask是使用python的后端&#xff0c;由于小程序需要后端开发&#xff0c;遂学习一下后端开发。 简易服务器代码 接口解析那一块很关键&#xff0c;学后端服务器这一块&#xff0c;感觉主要就是学习相应地址的接口怎么处理。 然后…...

“计算机视觉处理设计开发工程师”专项培训(第二期)

“人工智能技术与咨询” 发布...

R语言学习case7:ggplot基础画图(核密度图)

step1: 导入ggplot2库文件 library(ggplot2)step2&#xff1a;带入自带的iris数据集 iris <- datasets::irisstep3&#xff1a;查看数据信息 dim(iris)维度为 [150,5] head(iris)查看数据前6行的信息 step4&#xff1a;画图展示 plot2 <- ggplot(iris,aes(Sepal.W…...

Ubuntu18配置Docker

1.基本过程 1.更新软件源列表 sudo apt update2.安装软件包依赖 sudo apt install apt-transport-https ca-certificates curl software-properties-common3.在系统中添加Docker的官方密钥 curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - …...

Keil/MDK平台 - 结构体成员指针注意事项

文章目录 1 . 前言总结2 . 问题现象3 . 解决思路4 . 细节扩展5 . 总结 【极客技术传送门】 : https://blog.csdn.net/Engineer_LU/article/details/135149485 1 . 前言总结 有时候希望通过类定义的类型指向数据包来解析&#xff0c;恰好又想结构体内定义指针指向一段数据&…...

一款超级好用的远程控制APP,你值得拥有

在这个科技日新月异的时代&#xff0c;我们的生活被各种手机软件所包围。几乎每个人都有一个甚至多个手机&#xff0c;你是否也有遇到过需要远程操作自己某一台手机的场景呢&#xff1f;今天&#xff0c;我要向大家推荐一款神奇的手机远程操作神器&#xff0c;让你可以随时随地…...

PCIe设备内存映射IO(MMIO)详解:Non-Prefetchable与Prefetchable到底有啥区别?

PCIe设备内存映射IO&#xff08;MMIO&#xff09;深度解析&#xff1a;Non-Prefetchable与Prefetchable的设计哲学与工程实践 当你第一次在PCIe设备的规格书中看到"Non-Prefetchable"和"Prefetchable"这两个术语时&#xff0c;是否感到困惑&#xff1f;这两…...

通信与导航-技术博客网站上线了-正式

通信与导航-技术博客网站上线了 自2025年3月开始在微信公众号写通信与导航相关技术文章以来&#xff0c;至今已经过11个月。在公众号平台上&#xff0c;积累了相当数量的粉丝&#xff0c;获得了平台的流量推荐&#xff0c;还通过公众号结识了许多业内朋友&#xff0c;线下对接了…...

仅限产线工程师获取:Python网关调试禁忌清单(含12个厂商文档刻意回避的硬件层坑点,第7条致90%项目延期)

第一章&#xff1a;Python网关调试的产线准入机制与权限边界在工业级Python网关部署场景中&#xff0c;产线准入并非简单验证服务可达性&#xff0c;而是融合身份认证、环境隔离、行为审计与动态策略执行的多维控制体系。所有调试接入请求必须通过统一API网关前置鉴权模块&…...

避坑指南:Ubuntu 22.04安装PyTorch时,关于CUDA版本和驱动那些最容易踩的雷

避坑指南&#xff1a;Ubuntu 22.04安装PyTorch时&#xff0c;关于CUDA版本和驱动那些最容易踩的雷 如果你正在Ubuntu 22.04上搭建PyTorch开发环境&#xff0c;很可能已经遇到了几个令人困惑的问题&#xff1a;为什么nvidia-smi和nvcc -V显示的CUDA版本不一致&#xff1f;为什么…...

探索人机协同:在快马平台上用Cursor实践AI辅助开发工作流

最近在尝试用AI辅助开发时&#xff0c;发现了一个特别有意思的工作模式&#xff1a;通过自然语言描述需求&#xff0c;让AI生成代码&#xff0c;然后直接在页面上展示和编辑。这种"描述-生成-调整"的循环&#xff0c;让开发效率提升了不少。今天就来分享一下在InsCod…...

墨语灵犀在操作系统概念教学中的应用:交互式问答与示例生成

墨语灵犀在操作系统概念教学中的应用&#xff1a;交互式问答与示例生成 操作系统课程&#xff0c;对于很多计算机专业的学生来说&#xff0c;就像一座横亘在面前的高山。进程、线程、死锁、内存分页……这些抽象的概念&#xff0c;常常让初学者感到困惑和枯燥。传统的教学方式…...

3个关键步骤让老款Mac重获新生:OpenCore Legacy Patcher终极指南

3个关键步骤让老款Mac重获新生&#xff1a;OpenCore Legacy Patcher终极指南 【免费下载链接】OpenCore-Legacy-Patcher 体验与之前一样的macOS 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 当苹果宣布你的Mac不再支持最新的macOS系统时…...

百川2-13B量化模型调优指南:降低OpenClaw任务失败率的3个技巧

百川2-13B量化模型调优指南&#xff1a;降低OpenClaw任务失败率的3个技巧 1. 为什么需要针对量化模型做特殊调优&#xff1f; 上周我让OpenClaw帮我整理一个包含300多份PDF的文献库&#xff0c;结果连续跑了3次都中途崩溃。查看日志才发现&#xff0c;百川2-13B量化模型在处理…...

华硕笔记本终极性能调校指南:GHelper开源控制工具完全解析

华硕笔记本终极性能调校指南&#xff1a;GHelper开源控制工具完全解析 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops. Control tool for ROG Zephyrus G14, G15, G16, M16, Flow X13, Flow X16, TUF, Strix, Scar and other models 项目…...

bilibili-parse极简工具:三步搞定B站视频解析的高效方案

bilibili-parse极简工具&#xff1a;三步搞定B站视频解析的高效方案 【免费下载链接】bilibili-parse bilibili Video API 项目地址: https://gitcode.com/gh_mirrors/bi/bilibili-parse 您是否曾因想保存B站精彩视频却被复杂的技术门槛劝退&#xff1f;是否在面对AV号/…...