排序
1.1排序的概念
排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。
稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排 序算法是稳定的;否则称为不稳定的。
内部排序:排序算法要求一次性将所有的数据加载到内存中才可以进行排序。
外部排序:排序算法没有要求一次性将所有的数据加载到内存中才可以进行排序。
1.2排序的运用
1.3 常见的排序算法
排序相关:排序算法原理 + 代码实现 + 时间和空间复杂度 + 稳定性 + 应用场景
2.常见排序算法的实现
2.1 插入排序
2.1.1基本思想:
直接插入排序其基本思想是:把待排序的记录按其关键值的大小逐个插入到一 个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列 。 实际中我们玩扑克牌时,就用了插入排序的思想。(每起一张牌,将其往手中插入,:依次从右往左来进行比较)
2.1.2直接插入排序:
将一个数插入到一组已经排好序的有序序列中
延伸到将一组无序序列插入到有序序列中(1个元素便可以看做一个有序序列)
算法描述
- 从第一个元素开始,该元素可以认为已经被排序(如图的8);
- 取出待插入区的下一个元素,在已经排序的元素序列中从后向前扫描;
- 如果该元素(已排序)大于新元素,将该元素移到下一位置;
- 重复步骤 3,直到找到已排序的元素小于或者等于新元素的位置;
- 将新元素插入到该位置后;
- 重复步骤 2~5
Sort.h
#pragma once
// 插入排序
void InsertSort(int array[], int size);
void PrintArray(int array[], int size);
void TestSort();
Sort.cpp
void InsertSort(int array[] , int size)
{
// 下标0位置的元素,可以自己成序,所以只需要从1的位置开始往里插
for (int i = 1; i < size; i++ )
{
//模拟单个元素插入过程
int key = array[i];
int end = i-1;
// 找待插入元素在区间中的位置,end≥0不然end--数组会越界
while (end>=0 && key < array[end])
{
// 大元素后移
array[end+1] = array[end];
// end前移
end--;
}
// 若key > array[end],将key直接插入到end+1的位置
array[end+1] = key;
}
}
void PrintArray(int array[], int size)
{
for (int i = 0; i < size; ++i)
cout << array[i] << " ";
cout << endl;
}
void TestSort()
{
int array[] = { 4, 1, 7, 6, 3, 9, 5, 8, 0, 2 };
cout << "排序前:";
PrintArray(array, sizeof(array) / sizeof(array[0]));
InsertSort(array, sizeof(array) / sizeof(array[0]));
cout << "插入排序后:";
PrintArray(array, sizeof(array) / sizeof(array[0]));
}
main()
#include"Sort.h"
int main()
{
TestSort();
return 0;
}
直接插入排序的特性总结:
1. 元素集合越接近有序,直接插入排序算法的时间效率越高
2. 时间复杂度:O(N^2)
3. 空间复杂度:O(1),它是一种稳定的排序算法
4. 稳定性:稳定
最优的场景:如果数据的序列与用户所需要序列是接近相同,比如:用户要升序,序列就是一个升序---->O(N)
最差场景:逆序 O(N²)
应用场景:数据有序或者接近有序&数据量比较少
=========================================================================
问题:现实数据凌而且数据量往往比较大,但是要求使用插入排序来进行排序,解决方法:将用户所给的场景向插入排序的场景进行转变
数据凌乱---->想办法让该数据逐渐接近有序(比较难:小的数据尽量靠前,大的数据尽量靠后)
数据量比较大---->想办法让数据量逐渐变小(相对简单:将数据进行分组)
对数据进行平均分组:每组数据个数较少,用插入排序对每个分组进行排序
4, 1, 7, 6, 3, 9, 5, 8, 0, 2
1, 4, 7, 3, 6, 9, 0, 5, 8, 2 并不是接近有序
以gap间隔的方式进行分组然后调用插入排序,再缩小gap再进行分组排序.....反复——希尔排序