排序算法时间复杂度、空间复杂度、稳定性比较

排序算法分类

这里写图片描述

排序算法比较表格填空

排序算法平均时间复杂度最坏时间复杂度空间复杂度是否稳定
冒泡排序:————-::—–::—–::—–:
选择排序:————-::—–::—–::—–:
直接插入排序:————-::—–::—–::—–:
归并排序:————-::—–::—–::—–:
快速排序:————-::—–::—–::—–:
堆排序:————-::—–::—–::—–:
希尔排序:————-::—–::—–::—–:
计数排序:————-::—–::—–::—–:
基数排序:————-::—–::—–::—–:

排序算法比较表格

排序算法平均时间复杂度最坏时间复杂度空间复杂度是否稳定
冒泡排序O(n2)O(n2)O(n2)O(n2)O(1)O(1)
选择排序O(n2)O(n2)O(n2)O(n2)O(1)O(1)不是
直接插入排序O(n2)O(n2)O(n2)O(n2)O(1)O(1)
归并排序O(nlogn)O(nlogn)O(nlogn)O(nlogn)O(n)O(n)
快速排序O(nlogn)O(nlogn)O(n2)O(n2)O(logn)O(logn)不是
堆排序O(nlogn)O(nlogn)O(nlogn)O(nlogn)O(1)O(1)不是
希尔排序O(nlogn)O(nlogn)O(ns)O(ns)O(1)O(1)不是
计数排序O(n+k)O(n+k)O(n+k)O(n+k)O(n+k)O(n+k)
基数排序O(N∗M)O(N∗M)O(N∗M)O(N∗M)O(M)O(M)

注:

1 归并排序可以通过手摇算法将空间复杂度降到O(1),但是时间复杂度会提高。

2 基数排序时间复杂度为O(N*M),其中N为数据个数,M为数据位数。

辅助记忆

  • 时间复杂度记忆- 
    • 冒泡、选择、直接 排序需要两个for循环,每次只关注一个元素,平均时间复杂度为O(n2)O(n2)(一遍找元素O(n)O(n),一遍找位置O(n)O(n))
    • 快速、归并、希尔、堆基于二分思想,log以2为底,平均时间复杂度为O(nlogn)O(nlogn)(一遍找元素O(n)O(n),一遍找位置O(logn)O(logn))
  • 稳定性记忆-“快希选堆”(快牺牲稳定性) 
    • 排序算法的稳定性:排序前后相同元素的相对位置不变,则称排序算法是稳定的;否则排序算法是不稳定的。

原理理解

1 冒泡排序

1.1 过程

冒泡排序从小到大排序:一开始交换的区间为0~N-1,将第1个数和第2个数进行比较,前面大于后面,交换两个数,否则不交换。再比较第2个数和第三个数,前面大于后面,交换两个数否则不交换。依次进行,最大的数会放在数组最后的位置。然后将范围变为0~N-2,数组第二大的数会放在数组倒数第二的位置。依次进行整个交换过程,最后范围只剩一个数时数组即为有序。

1.2 动图

1.3 核心代码(函数)

//array[]为待排序数组,n为数组长度
void BubbleSort(int array[], int n)
{int i, j, k;for(i=0; i<n-1; i++)for(j=0; j<n-1-i; j++){if(array[j]>array[j+1]){k=array[j];array[j]=array[j+1];array[j+1]=k;}}
}

2 选择排序

2.1 过程

选择排序从小到大排序:一开始从0~n-1区间上选择一个最小值,将其放在位置0上,然后在1~n-1范围上选取最小值放在位置1上。重复过程直到剩下最后一个元素,数组即为有序。

2.2 动图

 

2.3 核心代码(函数)

//array[]为待排序数组,n为数组长度
void selectSort(int array[], int n)
{int i, j ,min ,k;for( i=0; i<n-1; i++){min=i; //每趟排序最小值先等于第一个数,遍历剩下的数for( j=i+1; j<n; j++) //从i下一个数开始检查{if(array[min]>array[j]){min=j;}}if(min!=i){k=array[min];array[min]=array[i];array[i]=k;}}
}

3 插入排序

3.1 过程

插入排序从小到大排序:首先位置1上的数和位置0上的数进行比较,如果位置1上的数大于位置0上的数,将位置0上的数向后移一位,将1插入到0位置,否则不处理。位置k上的数和之前的数依次进行比较,如果位置K上的数更大,将之前的数向后移位,最后将位置k上的数插入不满足条件点,反之不处理。

3.2 动图

 

3.3 核心代码(函数)

//array[]为待排序数组,n为数组长度
void insertSort(int array[], int n)
{int i,j,temp;for( i=1;i<n;i++){if(array[i]<array[i-1]){temp=array[i];for( j=i;array[j-1]>temp;j--){array[j]=array[j-1];}array[j]=temp;}}
}

4 归并排序

4.1 过程

归并排序从小到大排序:首先让数组中的每一个数单独成为长度为1的区间,然后两两一组有序合并,得到长度为2的有序区间,依次进行,直到合成整个区间。

4.2 动图

 

4.3 核心代码(函数)

  • 递归实现
实现归并,并把数据都放在list1里面 
void merging(int *list1, int list1_size, int *list2,  int list2_size)
{int i=0, j=0, k=0, m=0;int temp[MAXSIZE];while(i < list1_size && j < list2_size){if(list1[i]<list2[j]){temp[k++] = list1[i++];}else{temp[k++] = list2[j++];}}while(i<list1_size){temp[k++] = list1[i++];}while(j<list2_size){temp[k++] = list2[j++];}for(m=0; m < (list1_size+list2_size); m++){list1[m]=temp[m];}
}
//如果有剩下的,那么说明就是它是比前面的数组都大的,直接加入就可以了 
void mergeSort(int array[], int n)
{if(n>1){int *list1 = array;int list1_size = n/2;int *list2 = array + n/2;int list2_size = n-list1_size;mergeSort(list1, list1_size);mergeSort(list2, list2_size);merging(list1, list1_size, list2, list2_size);}
}
//归并排序复杂度分析:一趟归并需要将待排序列中的所有记录  
//扫描一遍,因此耗费时间为O(n),而由完全二叉树的深度可知,  
//整个归并排序需要进行[log2n],因此,总的时间复杂度为  
//O(nlogn),而且这是归并排序算法中平均的时间性能  
//空间复杂度:由于归并过程中需要与原始记录序列同样数量级的  
//存储空间去存放归并结果及递归深度为log2N的栈空间,因此空间  
//复杂度为O(n+logN)  
//也就是说,归并排序是一种比较占内存,但却效率高且稳定的算法 
  • 迭代实现
void MergeSort(int k[],int n)  
{  int i,next,left_min,left_max,right_min,right_max;  //动态申请一个与原来数组一样大小的空间用来存储int *temp = (int *)malloc(n * sizeof(int));  //逐级上升,第一次比较2个,第二次比较4个,第三次比较8个。。。  for(i=1; i<n; i*=2)  {  //每次都从0开始,数组的头元素开始  for(left_min=0; left_min<n-i; left_min = right_max)  {  right_min = left_max = left_min + i;  right_max = left_max + i;  //右边的下标最大值只能为n  if(right_max>n)  {  right_max = n;  }  //next是用来标志temp数组下标的,由于每次数据都有返回到K,  //故每次开始得重新置零  next = 0;  //如果左边的数据还没达到分割线且右边的数组没到达分割线,开始循环  while(left_min<left_max&&right_min<right_max)  {  if(k[left_min] < k[right_min])  {  temp[next++] = k[left_min++];  }  else  {  temp[next++] = k[right_min++];  }  }  //上面循环结束的条件有两个,如果是左边的游标尚未到达,那么需要把  //数组接回去,可能会有疑问,那如果右边的没到达呢,其实模拟一下就可以  //知道,如果右边没到达,那么说明右边的数据比较大,这时也就不用移动位置了  while(left_min < left_max)  {  //如果left_min小于left_max,说明现在左边的数据比较大  //直接把它们接到数组的min之前就行  k[--right_min] = k[--left_max];   }  while(next>0)  {  //把排好序的那部分数组返回该k  k[--right_min] = temp[--next];        }  }  }  
}  
//非递归的方法,避免了递归时深度为log2N的栈空间,
//空间只是用到归并临时申请的跟原来数组一样大小的空间,并且在时间性能上也有一定的提升,
//因此,使用归并排序是,尽量考虑用非递归的方法。

5 快速排序

5.1 过程

快速排序从小到大排序:在数组中随机选一个数(默认数组首个元素),数组中小于等于此数的放在左边,大于此数的放在右边,再对数组两边递归调用快速排序,重复这个过程。

5.2 动图

 

5.3 核心代码(函数)

推荐程序(好理解)

//接口调整
void adjust_quicksort(int k[],int n)  
{  quicksort(k,0,n-1);  
}  
void quicksort(int a[], int left, int right)  
{  int i,j,t,temp;  if(left>right)   //(递归过程先写结束条件)return;  temp=a[left]; //temp中存的就是基准数  i=left;  j=right;  while(i!=j)  {  //顺序很重要,要先从右边开始找(最后交换基准时换过去的数要保证比基准小,因为基准                               //选取数组第一个数,在小数堆中) while(a[j]>=temp && i<j)  j--;  //再找右边的  while(a[i]<=temp && i<j)  i++;  //交换两个数在数组中的位置  if(i<j)  {  t=a[i];  a[i]=a[j];  a[j]=t;  }  }  //最终将基准数归位 (之前已经temp=a[left]过了,交换只需要再进行两步)a[left]=a[i];  a[i]=temp;  quicksort(left,i-1);//继续处理左边的,这里是一个递归的过程  quicksort(i+1,right);//继续处理右边的 ,这里是一个递归的过程  
}  

6 堆排序

6.1 过程

堆排序从小到大排序:首先将数组元素建成大小为n的大顶堆,堆顶(数组第一个元素)是所有元素中的最大值,将堆顶元素和数组最后一个元素进行交换,再将除了最后一个数的n-1个元素建立成大顶堆,再将最大元素和数组倒数第二个元素进行交换,重复直至堆大小减为1。

  • 注:完全二叉树 
    假设二叉树深度为n,除了第n层外,n-1层节点都有两个孩子,第n层节点连续从左到右。如下图 
    这里写图片描述

  • 注:大顶堆 
    大顶堆是具有以下性质的完全二叉树:每个节点的值都大于或等于其左右孩子节点的值。 
    即,根节点是堆中最大的值,按照层序遍历给节点从1开始编号,则节点之间满足如下关系: 
    这里写图片描述 (1<=i<=n/2)

6.2 动图

 
 

6.3 核心代码(函数)

这里写图片描述
注意!!!数组从1开始,1~n

void heapSort(int array[], int n)
{int i;for (i=n/2;i>0;i--){HeapAdjust(array,i,n);//从下向上,从右向左调整}for( i=n;i>1;i--){swap(array, 1, i);HeapAdjust(array, 1, i-1);//从上到下,从左向右调整}
}
void HeapAdjust(int array[], int s, int n )
{int i,temp;temp = array[s];for(i=2*s;i<=n;i*=2){if(i<n&&array[i]<array[i+1]){i++;}if(temp>=array[i]){break;}array[s]=array[i];s=i;}array[s]=temp;
}
void swap(int array[], int i, int j)
{int temp;temp=array[i];array[i]=array[j];array[j]=temp;
}

7 希尔排序

7.1 过程

希尔排序是插入排序改良的算法,希尔排序步长从大到小调整,第一次循环后面元素逐个和前面元素按间隔步长进行比较并交换,直至步长为1,步长选择是关键。

7.2 动图

这里写图片描述 

7.3 核心程序(函数)

//下面是插入排序
void InsertSort( int array[], int n)
{int i,j,temp;for( i=0;i<n;i++ ){if(array[i]<array[i-1]){temp=array[i];for( j=i-1;array[j]>temp;j--){array[j+1]=array[j];}array[j+1]=temp;}}
}
//在插入排序基础上修改得到希尔排序
void SheelSort( int array[], int n)
{int i,j,temp;int gap=n; //~~~~~~~~~~~~~~~~~~~~~do{gap=gap/3+1;  //~~~~~~~~~~~~~~~~~~for( i=gap;i<n;i++ ){if(array[i]<array[i-gap]){temp=array[i];for( j=i-gap;array[j]>temp;j-=gap){array[j+gap]=array[j];}array[j+gap]=temp;}}}while(gap>1);  //~~~~~~~~~~~~~~~~~~~~~~}

8 桶排序(基数排序和基数排序的思想)

8.1 过程

桶排序是计数排序的变种,把计数排序中相邻的m个”小桶”放到一个”大桶”中,在分完桶后,对每个桶进行排序(一般用快排),然后合并成最后的结果。

8.2 图解

8.3 核心程序

#include <stdio.h>
int main()
{int a[11],i,j,t;for(i=0;i<=10;i++)a[i]=0;  //初始化为0for(i=1;i<=5;i++)  //循环读入5个数{scanf("%d",&t);  //把每一个数读到变量t中a[t]++;  //进行计数(核心行)}for(i=0;i<=10;i++)  //依次判断a[0]~a[10]for(j=1;j<=a[i];j++)  //出现了几次就打印几次printf("%d ",i);getchar();getchar(); //这里的getchar();用来暂停程序,以便查看程序输出的内容//也可以用system("pause");等来代替return 0;
}

9 计数排序

9.1 过程

算法的步骤如下: 
- 找出待排序的数组中最大和最小的元素 
- 统计数组中每个值为i的元素出现的次数,存入数组C的第i项 
- 对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加) 
- 反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1

9.2 图解

这里写图片描述

9.3 核心程序(函数)

程序1:
#define NUM_RANGE (100)    //预定义数据范围上限,即K的值void counting_sort(int *ini_arr, int *sorted_arr, int n)  //所需空间为 2*n+k
{  int *count_arr = (int *)malloc(sizeof(int) * NUM_RANGE);  int i, j, k;  //初始化统计数组元素为值为零 for(k=0; k<NUM_RANGE; k++){  count_arr[k] = 0;  }  //统计数组中,每个元素出现的次数    for(i=0; i<n; i++){  count_arr[ini_arr[i]]++;  }  //统计数组计数,每项存前N项和,这实质为排序过程for(k=1; k<NUM_RANGE; k++){  count_arr[k] += count_arr[k-1];  }  //将计数排序结果转化为数组元素的真实排序结果for(j=n-1 ; j>=0; j--){  int elem = ini_arr[j];          //取待排序元素int index = count_arr[elem]-1;  //待排序元素在有序数组中的序号sorted_arr[index] = elem;       //将待排序元素存入结果数组中count_arr[elem]--;              //修正排序结果,其实是针对算得元素的修正}  free(count_arr);  
}  程序2:C++(最大最小压缩桶数)
public static void countSort(int[] arr) {if (arr == null || arr.length < 2) {return;}int min = arr[0];int max = arr[0];for (int i = 1; i < arr.length; i++) {min = Math.min(arr[i], min);max = Math.max(arr[i], max);}int[] countArr = new int[max - min + 1];for (int i = 0; i < arr.length; i++) {countArr[arr[i] - min]++;}int index = 0;for (int i = 0; i < countArr.length; i++) {while (countArr[i]-- > 0) {arr[index++] = i + min;}
}

10 基数排序

10.1 过程

基数排序是基于数据位数的一种排序算法。 
它有两种算法 
①LSD–Least Significant Digit first 从低位(个位)向高位排。 
②MSD– Most Significant Digit first 从高位向低位(个位)排。 
时间复杂度O(N*最大位数)。 
空间复杂度O(N)。

10.2 图解

这里写图片描述 
对a[n]按照个位0~9进行桶排序: 
这里写图片描述 
对b[n]进行累加得到c[n],用于b[n]中重复元素计数 
!!!b[n]中的元素为temp中的位置!!!跳跃的用++补上: 
这里写图片描述 
temp数组为排序后的数组,写回a[n]。temp为按顺序倒出桶中的数据(联合b[n],c[n],a[n]得到),重复元素按顺序输出: 
这里写图片描述

10.3 核心程序

//基数排序  
//LSD  先以低位排,再以高位排  
//MSD  先以高位排,再以低位排  
void LSDSort(int *a, int n)  
{  assert(a);  //判断a是否为空,也可以a为空||n<2返回int digit = 0;   //最大位数初始化for (int i = 0; i < n; ++i)  {   //求最大位数while (a[i] > (pow(10,digit)))  //pow函数要包含头文件math.h,pow(10,digit)=10^digit{  digit++;  }  }  int flag = 1;   //位数for (int j = 1; j <= digit; ++j)  {  //建立数组统计每个位出现数据次数(Digit[n]为桶排序b[n])  int Digit[10] = { 0 };  for (int i = 0; i < n; ++i)  {  Digit[(a[i] / flag)%10]++;  //flag=1时为按个位桶排序}  //建立数组统计起始下标(BeginIndex[n]为个数累加c[n],用于记录重复元素位置//flag=1时,下标代表个位数值,数值代表位置,跳跃代表重复)int BeginIndex[10] = { 0 };  for (int i = 1; i < 10; ++i)  {  //累加个数BeginIndex[i] = BeginIndex[i - 1] + Digit[i - 1];  }  //建立辅助空间进行排序 //下面两条可以用calloc函数实现int *tmp = new int[n];  memset(tmp, 0, sizeof(int)*n);//初始化  //联合各数组求排序后的位置存在temp中for (int i = 0; i < n; ++i)  {  int index = (a[i] / flag)%10;  //桶排序和位置数组中的下标//计算temp相应位置对应a[i]中的元素,++为BeginIndex数组数值加1//跳跃间隔用++来补,先用再++tmp[BeginIndex[index]++] = a[i];  }  //将数据重新写回原空间  for (int i = 0; i < n; ++i)  {  a[i] = tmp[i];  }  flag = flag * 10;  delete[] tmp;  }  
}  

附:

1 完整程序框架(冒泡排序举例)

1.1 VS2010程序

#include "stdafx.h"
#include "stdio.h"
#include <stdlib.h>void BubbleSort(int array[], int n){int i,j,k,count1=0, count2=0;for(i=0; i<n-1; i++)for(j=n-1; j>i; j--){count1++;if(array[j-1]>array[j]){count2++;k=array[j-1];array[j-1]=array[j];array[j]=k;}}printf("总共的循环次序为:%d,  总共的交换次序为:%d\n\n", count1, count2);
}int main(int argc, _TCHAR* argv[])
{int as[]={0,1,2,3,4,6,8,5,9,7};BubbleSort(as, 10);for(int i=0; i<10; i++){printf("%d", as[i]);}printf("\n\n");system("pause");return 0;
}

1.2 执行程序(OJ)

#include <stdio.h>void BubbleSort(int array[], int n){int i,j,k,count1=0, count2=0;for(i=0; i<n-1; i++)for(j=n-1; j>i; j--){count1++;if(array[j-1]>array[j]){count2++;k=array[j-1];array[j-1]=array[j];array[j]=k;}}printf("总共的循环次序为:%d,  总共的交换次序为:%d\n\n", count1, count2);
}int main()
{int as[]={0,1,2,3,4,6,8,5,9,7};BubbleSort(as, 10);int i=0;for(i=0; i<10; i++){printf("%d", as[i]);}return 0;
}

2 关于交换的优化

不用中间变量进行交换

if(A[j] <= A[i]){A[j] = A[j] + A[i];A[i] = A[j] - A[i];A[j] = A[j] - A[i];
}

3 C语言实现数组动态输入

#include <stdio.h>  
#include <assert.h>  //断言头文件
#include <stdlib.h>  int main(int argc, char const *argv[])  
{  int size = 0;  scanf("%d", &size);   //首先输入数组个数assert(size > 0);     //判断数组个数是否非法int *array = (int *)calloc(size, sizeof(int));  //动态分配数组if(!R1)  {  return;           //申请空间失败  }  int i = 0;  for (i = 0; i < size; ++i) {  scanf("%d", &array[i]);  }  mergeSort(array, size);  printArray(array, size);  free(array);  return 0;  
} 

注: 
1.colloc与malloc类似,但是主要的区别是存储在已分配的内存空间中的值默认为0,使用malloc时,已分配的内存中可以是任意的值. 
2.colloc需要两个参数,第一个是需要分配内存的变量的个数,第二个是每个变量的大小.

欢迎关注微信公众号:嵌入式Linux  

 

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

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

相关文章

基于Springboot外卖系统05:用户非登陆状态的页面拦截器实现

1. 完善登录功能 1.1 问题分析 用户访问接口验证&#xff0c;如果用户没有登录&#xff0c;则不让他访问除登录外的任何接口。 1.前端登录&#xff0c;后端创建session&#xff0c;返给前端 2.前端访问其他接口&#xff0c;失效或不存在&#xff0c;则返回失效提示&#xff…

python删除指定行_关于csv:删除python中的特定行和对应文件

我想删除90%的"转向"值等于0的行。这三个图像都有一个对应的图像文件&#xff0c;中间&#xff0c;左边和右边。我也要删除它们。csv文件如下&#xff1a;我编写了以下代码&#xff0c;以至少获取转向值为0的文件。我所需要的就是随机获取90%的文件并删除它们的代码。…

I2C总线传输协议

简介 I2C&#xff08;Inter-integrated Circuit&#xff09;总线支持设备之间的短距离通信&#xff0c;用于处理器和一些外围设备之间的接口&#xff0c;它只需要两根信号线来完成信息交换。I2C最早是飞利浦在1982年开发设计并用于自己的芯片上&#xff0c;一开始只允许100kHz…

基于Springboot外卖系统06: 新增员工功能+全局异常处理器

2. 新增员工 2.1 需求分析 后台系统中可以管理员工信息&#xff0c;通过新增员工来添加后台系统用户。点击[添加员工]按钮跳转到新增页面&#xff0c;如下 当填写完表单信息, 点击"保存"按钮后, 会提交该表单的数据到服务端, 在服务端中需要接受数据, 然后将数据保…

spring aop实现原理_Spring 异步实现原理与实战分享

最近因为全链路压测项目需要对用户自定义线程池 Bean 进行适配工作&#xff0c;我们知道全链路压测的核心思想是对流量压测进行标记&#xff0c;因此我们需要给压测的流量请求进行打标&#xff0c;并在链路中进行传递&#xff0c;那么问题来了&#xff0c;如果项目中使用了多线…

基于Springboot外卖系统07:员工分页查询+ 分页插件配置+分页代码实现

1. 员工分页查询 1.1 需求分析 在分页查询页面中, 以分页的方式来展示列表数据&#xff0c;以及查询条件 "员工姓名"。 请求参数 搜索条件&#xff1a; 员工姓名(模糊查询) 分页条件&#xff1a; 每页展示条数 &#xff0c; 页码 响应数据 总记录数 结果列表 1…

1045-Access denied for user 'root'@'localhost'(using password:YES)

解决&#xff1a; 1. 开始 --> cmd --> net stop mysql (停用MySQL服务 没启动的可以省略) 2. 找到安装路径 MySQL Server 5.1下的my.ini 3. 打开 my.ini 找到 [mysqld] 然后在下面加上 这句&#xff1a; skip_grant_tables &#xff08;意思好像是 启动MySQL服务…

arial字体可以商用吗_【工作总结】莫让字体版权引火上身

前段一条微软雅黑字体引发的巨额罚款新闻&#xff0c;引起国内多个TW大群小地震&#xff0c;人人自危。我也赶紧检查自家文档、商用出版物、网站的字体&#xff0c;以免给公司带来法务后患。把这两天收集的信息&#xff0c;采取的行动记录一下。哪些中文字体免费&#xff1f;事…

基于Springboot外卖系统08:员工账号状态管理功能+对象转换器+扩展Spring mvc的消息转换器

1. 员工账号状态管理 1.1 需求分析 在员工管理列表页面&#xff0c;可以对某个员工账号进行启用或者禁用操作。账号禁用的员工不能登录系统&#xff0c;启用后的员工可以正常登录。如果某个员工账号状态为正常&#xff0c;则按钮显示为 "禁用"&#xff0c;如果员工…

基于Springboot外卖系统09:员工信息编辑+员工信息保存

1 编辑员工信息功能 1.1 需求分析 在员工管理列表页面点击 "编辑" 按钮&#xff0c;跳转到编辑页面&#xff0c;在编辑页面回显员工信息并进行修改&#xff0c;最后点击 "保存" 按钮完成编辑操作。 那么从上述的分析中&#xff0c;当前实现的编辑功能需…

bcp 不能调用where 子句_MySQL中IS NULL、IS NOT NULL、!=不能用索引?胡扯!

不知道从什么时候开始&#xff0c;网上流传着这么一个说法&#xff1a;MySQL的WHERE子句中包含 IS NULL、IS NOT NULL、! 这些条件时便不能使用索引查询&#xff0c;只能使用全表扫描。这种说法愈演愈烈&#xff0c;甚至被很多同学奉为真理。咱啥话也不说&#xff0c;举个例子。…

基于Springboot外卖系统10:公共字段填充功能+ThreadLocal模块改进

1. 公共字段自动填充 1.1 问题分析 在新增员工时需要设置创建时间、创建人、修改时间、修改人等字段&#xff0c;在编辑员工时需要设置修改时间、修改人等字段。这些字段属于公共字段&#xff0c;也就是也就是在系统中很多表中都会有这些字段&#xff0c;如下&#xff1a; 而…

腾讯云挂在和格式化数据盘

新购买了数据盘时&#xff0c;需要格式化才可使用。未购买数据盘的用户可以跳过此步骤。也可以根据需要进行多分区操作。 这里以Windows 2012R2为例进行格式化说明。 1) 通过步骤四介绍的方法登录Windows云服务器。 2) 点击【开始】&#xff08;Start&#xff09;-【服务器管理…

基于Springboot外卖系统11:菜品新增类别+类别信息分页查询

1. 新增分类 1.1 需求分析 后台系统中可以管理分类信息&#xff0c;分类包括两种类型&#xff0c;分别是 菜品分类 和 套餐分类 。当我们在后台系统中添加菜品时需要选择一个菜品分类&#xff0c;在后台系统中添加一个套餐时需要选择一个套餐分类&#xff0c;在移动端也会按照…

基于Springboot外卖系统12:删除菜品套餐类别+修改套餐类别信息

1. 删除分类 1.1 需求分析 在分类管理列表页面&#xff0c;可以对某个分类进行删除操作。需要注意的是当分类关联了菜品或者套餐时&#xff0c;此分类不允许删除。 1.2 前端页面分析 在前端页面中&#xff0c;点击 "删除" 按钮&#xff0c;就会触发定义的方法&…

html5手机移动端三级联动城市选择器

//我的地址 var area1 new LArea(); area1.init({ trigger: #demo1, //触发选择控件的文本框&#xff0c;同时选择完毕后name属性输出到该位置 valueTo: #value1, //选择完毕后id属性输出到该位置 keys: { id: id, name: name }, //绑定数据源相关字段 id对应valueTo的value属…

我的师傅是风清扬

1 珍惜那些处处帮助你的人 国庆假期就要过去了&#xff0c;国庆这几天一直在考虑一个问题&#xff08;先保留是什么问题&#xff09;&#xff0c;也咨询了几个比较信任的朋友&#xff0c;都没有得到肯定的答案。 回家路上跟了一个大哥哥&#xff08;陈哥&#xff09;&#xf…

要多大内存才满足_佛龛的尺寸要多大?

佛龛是用于供奉佛像或者牌位的小阁子&#xff0c;大多数是木制家具。佛龛在一般是仿中国古代的房子等工程建筑制做而成&#xff0c;在其纹样层面有很高的要求&#xff0c;有关纹样今日姑且先不谈。除此之外佛龛的尺寸大小多少才算吉祥也是很有讲究的&#xff0c;那麼这个问题跟…

【YOLOV5-6.x讲解】数据配置文件 data/XXX.yaml

主干目录&#xff1a; 【YOLOV5-6.x 版本讲解】整体项目代码注释导航现在YOLOV5已经更新到6.X版本&#xff0c;现在网上很多还停留在5.X的源码注释上&#xff0c;因此特开一贴传承开源精神&#xff01;5.X版本的可以看其他大佬的帖子本文章主要从6.X版本出发&#xff0c;主要解…

python print 输出到txt_(Python基础教程之七)Python字符串操作

Python基础教程在SublimeEditor中配置Python环境Python代码中添加注释Python中的变量的使用Python中的数据类型Python中的关键字Python字符串操作Python中的list操作Python中的Tuple操作Pythonmax()和min()–在列表或数组中查找最大值和最小值Python找到最大的N个(前N个)或最小…