本文已参与[新人创作礼]活动,一起开启掘金创作之路
选择排序
*****
*****
**(从小到大)的基本思想是,首先,选出最小的数,放在第一个位置;然后,选出第二小的数,放在第二个位置;以此类推,直到所有的数从小到大排序。
在实现上,我们通常是先确定第i小的数所在的位置,然后,将其与第i个数进行交换。 **
*****
** *******
下面,以对 3 2 4 1 进行选择排序说明排序过程,使用min_index 记录当前最小的数所在的位置。 第1轮 排序过程 (寻找第1小的数所在的位置)
3 2 4 1(最初, min_index=1)
3 2 4 1(3 > 2, 所以min_index=2)
3 2 4 1(2 < 4, 所以 min_index=2)
3 2 4 1(2 > 1, 所以 min_index=4, 这时候确定了第1小的数在位置4)
1 2 4 3 (第1轮结果,将3和1交换,也就是位置1和位置4交换)
第2轮 排序过程 (寻找第2小的数所在的位置)
1 2 4 3(第1轮结果, min_index=2,只需要从位置2开始寻找)
1 2 4 3(4 > 2, 所以min_index=2)
1 2 4 3(3 > 2, 所以 min_index=2)
1 2 4 3(第2轮结果,因为min_index位置刚好在第2个位置,无需交换)
第3轮 排序过程 (寻找第3小的数所在的位置)
1 2 4 3(第2轮结果, min_index=3,只需要从位置2开始寻找)
1 2 4 3(4 > 3, 所以min_index=4)
1 2 3 4(第3轮结果,将3和4交换,也就是位置4和位置3交换)
至此,排序完毕。
代码如下
#include<stdio.h>
#define n 4
main()
{
int a[] = { 3,2,4,1 };
for (int i = 0; i < n - 1; i++) //进行n-1次循环
{
int min = i; //找min所对应的下标
for (int j = i + 1; j < n; j++) //注意j=i+1
{
if (a[min] > a[j])
min = j; //找最小的并且其下标给min
}
if (i !=min ) //
{
int t = a[min]; //互相交换
a[min] = a[i];
a[i] = t;
}
}
for (int k = 0; k < n; k++) //遍历并且输出
{
printf("%d", a[k]);
}
}
缺点:选择排序是一种不稳定的排序算法,可能会打乱两个相同数字的原有顺序。
例如,序列 6 8 6 2 9, 按照从小到大排序,第一轮会将第1个数字6会和2交换,那么原序列中2个6的相对前后顺序就被破坏了,所以选择排序是一种不稳定的排序算法。
冒泡排序
*****
*****
以从小到大排序为例,冒泡排序的整体思想是这样的:
- 从数组头部开始,不断比较相邻的两个元素的大小,让较大的元素逐渐往后移动(交换两个元素的值),直到数组的末尾。经过第一轮的比较,就可以找到最大的元素,并将它移动到最后一个位置。
- 第一轮结束后,继续第二轮。仍然从数组头部开始比较,让较大的元素逐渐往后移动,直到数组的倒数第二个元素为止。经过第二轮的比较,就可以找到次大的元素,并将它放到倒数第二个位置。
- 以此类推,进行 n-1(n 为数组长度)轮“冒泡”后,就可以将所有的元素都排列好。
整个排序过程就好像气泡不断从水里冒出来,最大的先出来,次大的第二出来,最小的最后出来,所以将这种排序方式称为冒泡排序(Bubble Sort)。
*****
*****
下面我们以“3 2 4 1”为例对冒泡排序进行说明。 第一轮 排序过程
3 2 4 1 (最初)
2 3 4 2 (比较3和2,交换)
2 3 4 1 (比较3和4,不交换)
2 3 1 4 (比较4和1,交换)
第一轮结束,最大的数字 4 已经在最后面,因此第二轮排序只需要对前面三个数进行比较。
第二轮 排序过程
2 3 1 4 (第一轮排序结果)
2 3 1 4 (比较2和3,不交换)
2 1 3 4 (比较3和1,交换)
第二轮结束,次大的数字 3 已经排在倒数第二个位置,所以第三轮只需要比较前两个元素。
第三轮 排序过程
2 1 3 4 (第二轮排序结果)
1 2 3 4 (比较2和1,交换)
至此,排序结束
#include<stdio.h>
#define n 4
main()
{
int a[] = { 3,2,4,1 };
for (int i = 0; i < n ; i++) //循环n次
{
for (int k = 0; k < n-1; k++) //因为下面是a[k+1]所以k<n-1
{
if (a[k] > a[k+1])
{
int t = a[k]; //交换
a[k ] = a[k+1];
a[k+1] = t;
}
}
}
for (int k = 0; k < n; k++) //遍历并且输出
{
printf("%d", a[k]);
}
}