1.插入排序:以第二个数据开始,插入到数据前已排序好的数据序列中,并使其依旧有序。
实现过程:
算法的代码实现:
//函数功能:直接插入排序,把数据从小到大排序
//arr 表示数组 len 表示长度
时间复杂度O(n^2) 空间复杂度O(1) 稳定 如果待排序列本就有序,时间复杂度为O(n)
#include<stdio.h>
int insertsort(int *arr, int len)
{
int i = 0; int j = 0;
int tmp;
for (i = 0; i < len -1; i++)
{
for (j = i+1; j > 0; j--)
{
if (arr[j]>arr[j-1])
{
break;
}
else
{
tmp = arr[j-1];
arr[j-1] = arr[j];
arr[j] = tmp;
}
}
}
return 0;
}
int main()
{
int arr[] = { 2, 5, 6, 8, 12, 7, 16, 11 };
int len = sizeof(arr) / sizeof(int);
insertsort(arr, len);
for (int i = 0; i < len; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
2.希尔排序(一个改进的插入排序):先把大数据集合划分成若干个小组,然后对每一个小组分别进行插入排序。此时,插入排序所作用的数据量比较小(每一个小组)插入的效率比较高。
第一趟:增量为4 第二趟:增量为2
第三趟:增量为1
复杂度分析:
排序方法 | 时间复杂度 | 空间复杂度 | 稳定性 | 复杂性 | ||
平均情况 | 最坏情况 | 最好情况 | ||||
希尔排序 | O(n^1.3~n^1.5) | O(n^2) |
O(n) |
O(1) | 不稳定 |
较复杂 |
算法代码实现:
//希尔排序
//时间复杂度O(n^1.3 - n^1.5) 空间复杂度O(1) 不稳定
#include<stdio.h>
void shellsort(int a[], int n)
{
int i, j, d;
for (d = n / 2; d>0; d /= 2)
{
for (i = d; i<n; ++i)
{
int tmp = a[i];
for (j = i; j >= d&&a[j - d]>tmp; j -= d)
a[j] = a[j - d];
a[j] = tmp;
}
}
}
int main()
{
int arr[] = { 2, 5, 6, 8, 12, 7, 16, 11 };
int len = sizeof(arr) / sizeof(int);
shellsort(arr, len);
for (int i = 0; i < len; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
3.选择排序:从头至尾扫描序列,找出最小的一个元素,和第一个元素进行交换,接着从剩下的元素中继续这种选择和交换的方式,最终得到一个有序序列。
原始序列:{2,5,6,8,12,7,16,11}
1)进行选择排序时分成有序和无序两个序列,最开始都是无序序列 {2,5,6,8,12,7,16,11}
2)从无序序列中找出最小的元素2,将2同无序序列第一个元素交换,此时产生仅含一个元素的有序序列,无序序列减一(此时可以看到,无序序列中2本来就在第一个元素中,所以无需进行交换)
{2} {5,6,8,12,7,16,11}
3)从无序序列中取出最小的元素5,将5同无序序列第一个元素交换,此时产生仅两个元素的有序序列,无序序列减一(同上)
{2,5} {6,8,12,7,16,11}
4)从无序序列中取出最小的元素6,将6同无序序列第一个元素交换,此时产生含三个元素的有序序列,无序序列减一
{2,5,6} {8,12,7,16,11}
5)同上 {2,5,6,7} {12,8,16,11}
6)从无序序列中取出最小的元素6,将6同无序序列第一个元素交换,此时产生含三个元素的有序序列,无序序列减一
{2,5,6,7,8} {12,11,16}
{2,5,6,7,8,11} {12,16}
7)最后一个元素肯定是最大元素,无序排序直接生产一个有序的序列
结果:{2,5,6,7,8,11,12,16}
算法代码实现:
//时间复杂度O(n^2) 空间复杂度O(1) 不稳定
#include<stdio.h>
void selectsort(int *arr, int len)
{
int tmp, index;
for (int i = 0; i < len-1; i++)//每次循环数组,找出最小的元素,放在前面,前面的即为排序好的
{
index = i;//假设最小元素的下标
for (int j = i + 1; j < len; j++)
{
if (arr[j] < arr[index])//将上面假设的最小元素与数组比较,交换出最小的元素的下标
{
//index = j;//进行交换
tmp = arr[index];
arr[index] = arr[j];
arr[j] = tmp;
}
if (i != index)////若数组中真的有比假设的元素还小,就交换
{
tmp = arr[i];
arr[i] = arr[index];
arr[index] = tmp;
}
}
}
}
int main()
{
int arr[] = { 2, 5, 6, 8, 12, 7, 16, 11 };
int len = sizeof(arr) / sizeof(int);
selectsort(arr, len);
for (int i = 0; i < len; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
4.冒泡排序:
算法实现:第一次首先将第0和第1位进行比较,并且将结果大的数字向后移动,也就是进行交换,然后将第二位和第三位进行比较,依次两两进行往后推移,最后得到排序,最后一位就是最大的数字。如下图:
算法代码实现:
//时间复杂度 O(n^2) 空间复杂度O(1) 稳定
#include<stdio.h>
void bubblesort(int *arr, int len)
{
int tmp;
for (int i = 0; i < len-1; i++)
{
for (int j = i+1; j < len; j++)
{
if (arr[i] > arr[j])
{
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
}
}
int main()
{
int arr[] = { 2, 5, 6, 8, 12, 7, 16, 11 };
int len = sizeof(arr) / sizeof(int);
bubblesort(arr, len);
for (int i = 0; i < len; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}