冒泡排序:
数据左右比较,把较大的数据交换到右边,往后重复以上操作,直到把最大的数据交换到最后,特点是该算法对数据的有序性敏感,如果在一次的排序过程中没有发生一次交换,那么就意味着数据已经有序,可以立即停止排序
适合待排序的数据基本有序时,则冒泡的效率非常高
时间复杂度:平均:O(N^2) 最优O:(N)
稳定的
代码实现:
void bubble_sort(int* arr,size_t len)
{
bool flag = true;
for(int i=len-1; i>0 && flag; i--)
{
flag = false;
for(int j=0; j<i; j++)
{
if(arr[j] > arr[j+1])
{
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
flag = true;
}
}
}
}
选择排序:
假定最开始的位置是最小值并记录下标min,然后与后面所有的数据比较,如果有比min位置的值更小的数,那么更新min,结束后min的下标与开始时发生过改变,才进行交换到开始位置
虽然时间复杂度较高,但是数据交换次数比较少,因此实际的运行速度并不慢(数据交换比数据比较耗时)
时间复杂度:O(N^2)
不稳定的
代码实现:
void selection_sort(int* arr,size_t len)
{
for(int i=0; i<len-1; i++)
{
int min = i;
for(int j=i+1; j<len; j++)
{
if(arr[j] < arr[min]) min = j;
}
if(i != min)
{
int temp = arr[j];
arr[j] = arr[min];
arr[min] = temp;
}
}
}
插入排序:
把数据看成两个部分,前部分是有序的,把剩余部分的数据逐个往前比较,如果比前面的数小,前面的数往后移动一位,继续往前比较,直到遇到更小的数,那么该数据的后一个位置即为可以插入的位置
适合对已经排序后的数据,新增数据后再排序
时间复杂度:O(N^2)
稳定的
代码实现:
void insertion_sort(int* arr,size_t len)
{
for(int i=1,j=0; i<len; i++)
{
int val = arr[i]; // 要插入的数据
for(j=i; j>0 && arr[j-1] > val; j--)//j表示要插入的位置
{
arr[j] = arr[j-1];
}
if(j!=i) arr[j] = val;
}
}
希尔排序:
是插入排序的增强版,由于插入排序时数据移动的步长较短,都是1,所以增加了增量的概念,通过不停地缩减增量,最终步长还是变回1,可以提高排序效率
当待排序数据远离最终位置时,希尔排序的效率高于插入排序
时间复杂度:O(NlogN)~O(N^2)
不稳定
代码实现:
void shell_sort(int* arr,size_t len)
{
for(int k=len/2; k>0; k/=2) //k增量
{
for(int i=k,j=0; i<len; i++)
{
int val = arr[i];
for(j=i; j-k>=0 && arr[j-k] > val; j-=k)
{
arr[j] = arr[j-k];
}
if(j != i) arr[j] = val;
}
}
}
快速排序:
在待排序数据中先找一个标杆位置p,备份p位置的值val,记录左标杆l、右标杆r,l从p的左边找比val大的数,找到后赋值给p位置,更新p到l,然后r从p的右边找比val小的数,找到后赋值给p位置,更新p到r
循环往复,直到l和r重合,把val还原回p位置完成一次快排,然后用同样的方式对p左右两边的数据进行快排
它的综合性能最优,因此得名快速排序,笔试时考的最多
时间复杂度:O(NlogN)
不稳定
代码实现:
void _quick(int* arr,int left,int right)
{
if(left >= right) return;
int l = left, r = right, p = left;
// 备份标杆的值
int val = arr[p];
while(l < r)
{
// 在p右边找比val小的数
while(r > p && arr[r] >= val) r--;
// r在p的右边找到比val小的数
if(r > p)
{
arr[p] = arr[r];
p = r;
}
while(l < p && arr[l] <= val) l++;
if(l < p)
{
arr[p] = arr[l];
p = l;
}
}
// 还原标杆的值
arr[p] = val;
_quick(arr,left,p-1);
_quick(arr,p+1,right);
}
// 快速排序
void quick_sort(TYPE* arr,size_t len)
{
_quick(arr,0,len-1);
}