1. 选择排序
第一次从待排序的数组中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。以此类推,直到全部待排序的数据元素的个数为零。选择排序是不稳定的排序方法。
如数组3,2,16,1的排序过程如下:
- 找到最小值1,与3交换,1,2,16,3
- 剩下未排序的找到最小值2,不必交换
- 剩下未排序的找到最小值3,与16交换,1,2,3,16
#include <stdio.h>
void MySwap(int *nums, int i, int minIdx)
{
int tmp = nums[i];
nums[i] = nums[minIdx];
nums[minIdx] = tmp;
return;
}
void SelectionSort(int *nums, int len)
{
if (nums == NULL || len <= 1) {
return;
}
for (int i = 0; i < len; i++) {
int minIndex = i;
for (int j = i + 1; j < len; j++) {
minIndex = nums[minIndex] < nums[j] ? minIndex : j;
}
MySwap(nums, i, minIndex);
}
return;
}
int main()
{
int nums[10] = {12, 34, 8, 2, 5, 14, 16, 10, 9, 1};
printf("Before sort: ");
for (int i = 0; i < 10; i++) {
printf(" %d", nums[i]);
}
printf("\n");
SelectionSort(nums, 10);
printf("After sort: ");
for (int i = 0; i < 10; i++) {
printf(" %d", nums[i]);
}
printf("\n");
return 0;
}
2. 冒泡排序
依次比较相邻的元素。如果前面的元素比后面的大,就交换他们两个。每一轮比较后都可以找到一个当前未排序的元素的最大值放在已排序的元素的前面。
如数组3,2,16,1的排序过程如下:
第一轮:
- 3 > 2,交换,2,3,16,1
- 3 < 16,不交换
- 16 > 1,交换,2,3,1,16
第二轮: - 2 < 3,不交换
- 3 > 1,交换,2,1,3,16
- 3 < 16,不交换
第三轮: - 2 > 1,交换,1,2,3,16
- 2 < 3,不交换
- 3 < 16,不交换
#include <stdio.h>
void MySwap(int *nums, int i, int j)
{
nums[i] = nums[i] ^ nums[j];
nums[j] = nums[i] ^ nums[j];
nums[i] = nums[i] ^ nums[j];
return;
}
void BubbleSort(int *nums, int len)
{
if (nums == NULL || len <= 1) {
return;
}
for (int i = len - 1; i > 0; i--) {
for (int j = 0; j < i; j++) {
if (nums[j] > nums[j+1]) {
MySwap(nums, j, j + 1);
}
}
}
return;
}
int main()
{
int nums[10] = {12, 34, 15, 2, 5, 14, 16, 10, 9, 1};
printf("Before sort: ");
for (int i = 0; i < 10; i++) {
printf(" %d", nums[i]);
}
printf("\n");
BubbleSort(nums, 10);
printf("After sort: ");
for (int i = 0; i < 10; i++) {
printf(" %d", nums[i]);
}
printf("\n");
return 0;
}
3. 插入排序
类似打扑克时起牌。将待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列,从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。
如数组3,2,16,1的排序过程如下:
- 3 本身是有序的
- 3,2对比,3比2大,交换变为2,3,16,1
- 16,3对比,16比3大,不需交换(16比3大,自然比2大,不必比较)
- 1,16对比,16比1大,交换,2,3,1,16
- 1,3对比,3比1大,交换,2,1,3,16
- 1,2对比,2比1大,交换,1,2,3,16
#include <stdio.h>
void MySwap(int *nums, int i, int j)
{
nums[i] = nums[i] ^ nums[j];
nums[j] = nums[i] ^ nums[j];
nums[i] = nums[i] ^ nums[j];
return;
}
void InsertionSort(int *nums, int len)
{
if (nums == NULL || len <= 1) {
return;
}
for (int i = 1; i < len; i++) { // 0位置认为有序了,此循环做到0~i有序
for (int j = i - 1; j >= 0 & nums[j] > nums[j+1]; j--) {
MySwap(nums, j, j + 1);
}
}
return;
}
int main()
{
int nums[10] = {12, 34, 15, 2, 5, 14, 16, 10, 9, 1};
printf("Before sort: ");
for (int i = 0; i < 10; i++) {
printf(" %d", nums[i]);
}
printf("\n");
InsertionSort(nums, 10);
printf("After sort: ");
for (int i = 0; i < 10; i++) {
printf(" %d", nums[i]);
}
printf("\n");
return 0;
}