1.冒泡排序
一趟一趟的比较待排序的数组,每趟比较中,从前往后,依次比较这个数和下一个数的大小,如果这个数比下一个数大,则交换这两个数,每趟比较后,数组的末尾总会变成目前未有序的数组中最大的数,重复每趟比较,只不过每趟的最后一个最大的数就不需要再次比较了,持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
最坏的情况是所有元素都是逆序排列的,此时的时间复杂度是O(n^2)。
最好的情况是所有元素都是顺序排列的,此时的时间复杂度是O(n)。
冒泡排序的平均时间复杂度为O(n^2)。空间复杂度为O(1),冒泡排序是稳定的排序。
#include<stdio.h>
void bubblesort(int arr[], int len) {
for (int i = 0; i < len; i++) {
for (int j = 0; j < len - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j + 1];
arr[j + 1] = arr[j];
arr[j] = temp;
}
}
}
}
int main() {
int arr[] = { 1,2,2,3,3,4,6,1 };
int sz = sizeof(arr) / sizeof(arr[0]);
bubblesort(arr, sz);
for (int i=0; i < sz; i++) {
printf("%d", arr[i]);
}
return 0;
}
2.选择排序
一趟一趟的比较待排序的数组,每趟比较中,先把第一个数当做最小的数,记录位置,从前往后,依次比较这个数和下一个数的大小,如果这个数比下一个数大,记录更小的数的位置,每趟比较后,总会找出未排序的数组的最小值的位置,把这个数和第一个数交换,重复每趟比较,只不过每趟的第一个最小的数就不需要再次比较了,持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
无论元素的排列顺序是什么样的,此时的时间复杂度都是O(n^2),使用选择排序,数组元素越少越好。
选择排序的平均时间复杂度为O(n^2)。空间复杂度为O(1),选择排序是不稳定的排序。
#include<stdio.h>
void selectsort(int arr[], int len) {
int temp;
for (int i = 0; i < len; i++) {
temp = i;
for (int j = i+1; j < len ; j++) {
if (arr[j] < arr[temp]) {
temp = j;
}
}
if (i != temp) {
int tep = arr[i];
arr[i] = arr[temp];
arr[temp] = tep;
}
}
}
int main() {
int arr[] = { 1,2,2,3,3,4,6,1 };
int sz = sizeof(arr) / sizeof(arr[0]);
selectsort(arr, sz);
for (int i = 0; i < sz; i++) {
printf("%d", arr[i]);
}
return 0;
}
3.插入排序
将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。就是选择一个元素,从后往前扫瞄,并依次交换相邻的元素,看这个元素放在哪个位置时,已排序对面加上这个元素是有序的,循环这个过程,最后得到有序的序列。
最坏的情况是所有元素都是逆序排列的,此时的时间复杂度是O(n^2)。
最好的情况是所有元素都是顺序排列的,此时的时间复杂度是O(n)。
插入排序的平均时间复杂度为O(n^2)。空间复杂度为O(1),插入排序是稳定的排序。