void bubble_sort(int *arr, int n) {
int time = 1;//用来标记这次循环是否发生了冒泡交换
for (int i = 1; i < n && time; i++) {//如果没有发生交换说明数组已经排好了序
time = 0;
for (int j = 0; j < n - i; j++) {
if (arr[j] >= arr[j + 1]) {
swap(arr[j], arr[j + 1]);
time++;
}
}
}
return ;
}
void number_sort(int *arr, int n, int exp) {
int count[10] = {0};
for (int i = 0; i < n; i++) {
count[arr[i] / exp % 10] += 1;//对每位数的数的个数统计
}
for (int i = 1; i < 10; i++) {
count[i] += count[i - 1];//位数排序,从小到大,现在的操作就是使count变为下标
}
int *sum = (int *)malloc(sizeof(int) * n);
for (int i = n - 1; i >= 0; i--) {//假如个位已近排序后,那么个位大的在后,而根据十位排序也是从高位排到低位,所以需要倒过来存
sum[count[arr[i] / exp % 10] - 1] = arr[i];//下标从0开始,所以需要-1;
count[arr[i] / exp % 10]--;//对应的位数已经排序一个,所以数量-1;
}
memcpy(arr, sum, sizeof(int) * n);
free(sum);
return ;
}
void radix_sort(int *arr, int n) {
int max = INT_MIN;
for (int i = 0; i < n; i++) {//获取最大数的数
max = max > arr[i] ? max : arr[i];
}
for (int i = 1; max / i > 0; i *= 10) {//从个位一直到大于最大数的位数
number_sort(arr, n, i);
}
return ;
}
非稳定排序:
1.选择排序:
将数组分为两个区域一个已排序区和一个未排序区,每次将未排序区中的最值放在已排序区中;
如图将54放放到最后,也就是已排序区中;
这样一直在未排序区中选择,直到排序完成:
时间复杂度:
代码实现:
cpp复制代码
void select_sort(int *arr, int n) {//这里实现的是将最小的元素放在最前面,现在前面就是已排序区
for (int i = 0; i < n - 1; i++) {
int ind = i;//ind先记录当前准备排序的位置
for (int j = i + 1; j < n; j++) {
if (arr[ind] > arr[j]) ind = j;//ind记录未排序区中最小值的值的位置
}
swap(arr[ind], arr[i]);//将未排序的区的最小值放在准备排序的位置
}
return ;
}
//l最初为0,r最初为n-1
void quick_sort(int *arr, int l, int r) {
if (r < l) return ;
int x = l, y = r, num = arr[l];
while (x < y) {
while (x < y && arr[y] >= num) y--;//如果大于基数的部分,该位置数大于基数就不用交换
if (x < y) arr[x++] = arr[y];//如果x<y,说明y位置的值是小于基数的,就放到前面去,第一次的时候x的位置就是基数的位置,所以覆盖的是基数的位置
while (x < y && arr[x] <= num) x++;//如果小于基数的部分,该位置数小于等于基数就不用交换
if (x < y) arr[y--] = arr[x];//x<y,说明x位置的值是小于基数的,现在y位置是之前小于基数的位置,直接覆盖
}
arr[x] = num;//将基数放到分割位置
quick_sort(arr, l, x - 1);//小于基数的部分
quick_sort(arr, x + 1, r);//大于基数的部分
return ;
}