一、冒泡排序
时间复杂度:平均情况:O(n^2) 最好情况:O(n)
空间复杂度:O(1)
稳定性:稳定
主要思路:
1.比较相邻的元素。如果第一个比第二个大,就交换它们两个。
2.对每一个相邻元素做同样的工作,从开始第一对到结尾的每一对。在这一 点,最后的元素应该会是最大的数。
3.针对多有的元素重复以上的步骤,除了最后一个。
持续每次对越来越少的元素重复上面的步骤,知道没有任何一对数字需要比较。
图解:
代码:
void Bubble_sort(int *arr, int len)
{
assert(arr != NULL);
int tmp = 0;
bool swap = false;//加判断条件 减少比较次数
for (int i = 0; i < len -1; i++)
{
for (int j = 0; j < len - 1 - i; j++)
{
if (arr[j] > arr[j + 1])
{
tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;//交换
swap = true;
}
}
if (!swap)
{
return;
}
}
}
void Show(int *arr, int len)
{
for (int i = 0; i < len; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
int main()
{
int drr[] = {
1,8,7,5,0};
int num = sizeof(drr) / sizeof(drr[0]);
Bubble_sort(drr, num);
Show(drr, num);
return 0;
}
二、选择排序
时间复杂度:O(n^2)
空间复杂度:O(1)
稳定性:不稳定(相同的数值都交换了)
主要思路:
每一次从无序组的数据元素中选出最小的一个元素,存放在无序组的起始位置,无需组的元素减少,有序组的元素增加,直到全部待排序的数据元素排完。
图解:
代码:
void select_sort(int *arr, int len)
{
assert(arr != NULL);
int i, j;
int tmp;
int min = 0;
for (i = 0; i < len; i++)
{
int min = i;
for (j = i + 1; j < len; j++)
{
if (arr[j] < arr[min])
{
tmp = arr[min];
arr[min] = arr[j];
arr[j] = tmp;
}
}
}
}
void Show(int *arr, int len)
{
for (int i = 0; i < len; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
int main()
{
int drr[] = { 1,8,7,5,0 };
int num = sizeof(drr) / sizeof(drr[0]);
select_sort(drr, num);
Show(drr, num);
return 0;
}
三、插入排序
直接插入排序:
时间复杂度:无序 O(n^2) 有序O(n)
空间复杂度:O(1)
稳定性:稳定
主要思路:
插入排序是最简单常用的方法,将数组分为两部分,排好序的数列,以及未排序的数列,将未排序的数列中的元素 与排好序的数列进行比较,然后将该元素插入到已排序列的合适位置中。
图解:
代码:
void Insert_sort(int *arr, int len)
{
assert(arr != NULL);
int i, j;
int tmp = 0;
for (i = 1; i < len; i++)
{
tmp = arr[i];
for (j = i - 1; j >= 0; j--)
{
if (arr[j] > tmp)
{
arr[j + 1] = arr[j];
}