一、冒泡排序
1.原理
冒泡排序先会从头到尾比较相邻元素的⼤⼩,如果不满⾜升序降序的条件,则对其进⾏交换。⼀轮排序后,最⼤最⼩的元素将会移到末尾。因此进⾏ n-1 轮冒泡之后,整个序列即变为有序。
2.代码实现(降序排序)
#include <stdio.h>
void bubble_sort(int a[], int n) {
int i, j;
// 总共排序 n-1 轮
for(i = 0; i < n - 1; i++)
// j只需排到第 n-i 个元素,因为后i个元素已经有序
for(j = 1; j < n - i; j++)
// 如果不满⾜降序,则进⾏交换
if(a[j] > a[j-1])
{
int temp = a[j];
a[j] = a[j-1];
a[j-1] = temp;
}
}
void print_array(int a[], int n) {
int i;
for(i = 0; i < n; i++)
printf("%d ", a[i]);
printf("\n");
}
int main()
{
int a[] = {7, 2, 3, 1, 5, 8, 9, 0, 4, 6};
bubble_sort(a, 10);
print_array(a, 10); // 输出排序后的数组
return 0;
}
如果需要升序排列,只需要将 if(a[j] > a[j-1])
改为 if(a[j] < a[j-1])
即可。
二、选择排序
1.原理
选择排序的原理是:先找到⽆序序列中的最⼤/最⼩元素的下标,然后将其与⽆序序列的第⼀个元素进⾏交换。这样序列的第⼀个元素就变为有序,之后我们需要对第⼀个元素后⾯的⽆序序列再进⾏选择排序。这样经过 n-1 轮,我们就得到了⼀个有序的序列。
例如序列 7, 2, 3, 1, 5, 8, 9, 0, 4, 6
我们先找到最⼤元素的下标为 6 ,将其与 a[0] 进⾏交换,便得到
9, 2, 3, 1, 5, 8, 7, 0, 4, 6
这样,第⼀个元素便是有序的,我们只需要从 a[1] 开始再不断进⾏选择排序:
9, 8, 3, 1, 5, 2, 7, 0, 4, 6
9, 8, 7, 1, 5, 2, 3, 0, 4, 6
9, 8, 7, 6, 5, 2, 3, 0, 4, 1
9, 8, 7, 6, 5, 2, 3, 0, 4, 1
…
9, 8, 7, 6, 5, 4, 3, 2, 1, 0
这样最终我们就得到了有序序列。
2.代码实现(降序排序)
#include <stdio.h>
void select_sort(int a[], int n)
{
int i, j;
// 总共排序 n-1 轮
for(i = 0; i < n - 1; i++)
{
// 找到 i 之后的元素中最⼤元素的下标
int max_j = i;
for(j = i + 1; j < n; j++)
if(a[j] > a[max_j])
max_j = j;
// 如果最⼤元素不为当前元素,则进⾏交换
if(max_j != i)
{
int temp = a[i];
a[i] = a[max_j];
a[max_j] = temp;
}
}
}
void print_array(int a[], int n)
{
int i;
for(i = 0; i < n; i++)
printf("%d ", a[i]);
printf("\n");
}
int main()
{
int a[] = {7, 2, 3, 1, 5, 8, 9, 0, 4, 6};
select_sort(a, 10);
print_array(a, 10); // 输出排序后的数组
return 0;
}
如果需要改为升序排列,我们只需先找到 i 及之后的最⼩元素的下标,再和 a[i] 进⾏交换即可。
注意事项
在排序算法中,有以下⼏点需要注意:
- 注意排序的内层循环变量 j 的起始值与终⽌条件
- 选择排列中,记录不是最⼤值⽽是最⼤元素的下标
- 对于结构体的排序,可以将中间变量 temp 定义为同⼀种结构体,这样就可以实现交换
- 对于字符串的排序,可以使⽤ strcpy 函数来实现交换
- 注意升序排列与降序排列的代码差别