C++||排序
1.插入排序
1.1直接插入排序
思路:直接插入排序是一种简单的插入排序法,其基本思想是:把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列 。当插入第i(i>=1)个元素时,前面的array[0],array[1],…,array[i-1]已经排好序,此时用array[i]的排序码与array[i-1],array[i-2],…的排序码顺序进行比较,找到插入位置即将array[i]插入,原来位置上的元素顺序后移.
代码实现
void InsertSort(int array[],int size)
{
for (int i = 1; i < size; i++)
{
int key = array[i];//为什么i要从1开始,因为第一个数字自己本身就是有序的,所以从第二个数字开始进行排序
int end = i- 1;
while (end >= 0 && key < array[end])
{
array[end + 1] = array[end];//
end--;
}
array[end + 1] = key;
}
}
直接插入排序的特性总结:
元素集合越接近有序,直接插入排序算法的时间效率越高
时间复杂度:O(N^2) (降序)
空间复杂度:O(1),它是一种稳定的排序算法
稳定性:稳定
1.2希尔排序
希尔排序法又称缩小增量法。希尔排序法的基本思想是:先选定一个整数,把待排序文件中所有记录分成个组,所有距离为的记录分在同一组内,并对每一组内的记录进行插入排序。然后,取,重复上述分组和排序的工作。当到达=1时,所有记录在统一组内排好序。(划分区间进行排序)
代码实现
void ShellSort(int array[],int size)
{
int gap = 3;
while (gap > 0)
{
for (int i = gap; i < size; i+=gap)
{
int key = array[i];
int end = i - gap;
while (end >= 0 && key < array[end])
{
array[end + gap] = array[end];
end -= gap;
}
array[end + gap] = key;
}
gap--;
}
}
希尔排序的特性总结:
希尔排序是对直接插入排序的优化。
当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了,这样就
会很快。这样整体而言,可以达到优化的效果。我们实现后可以进行性能测试的对比。
希尔排序的时间复杂度不好计算,需要进行推导,推导出来平均时间复杂度: O(N1.3—N2)
稳定性:不稳定
2.选择排序
2.1选择排序
选择排序
选择排序基本介绍
- 选择式排序也属于内部排序法, 是从欲排序的数据中, 按指定的规则选出某一元素, 再依规定交换位置后达到排序的目的。
选择排序思想
选择排序(select sorting) 也是一种简单的排序方法。 它的基本思想是(n 是数组大小):
- 第一次从 arr[0]~arr[n-1]中选取最小值,与 arr[0] 交换
- 第二次从 arr[1]~arr[n-1]中选取最小值, 与 arr[1] 交换
- 第三次从 arr[2]~arr[n-1]中选取最小值, 与 arr[2] 交换, …,
- 第 i 次从 arr[i-1]~arr[n-1]中选取最小值, 与 arr[i-1] 交换, …,
- 第 n-1 次从 arr[n-2]~arr[n-1]中选取最小值,与 arr[n-2] 交换,
- 总共通过 n-1 次, 得到一个按排序码从小到大排列的有序序列。
- 可以选择最大的和最后一个元素交换,也可以选择最小的和第一个元素交换
代码实现(选择最大和最后一个元素交换)
void SelectSort(int array[], int size)
{
for (int i = 0; i < size - 1; i++)
{
int maxpos = 0;
for (int j = 1; j < size - i; j++)
{
if (array[maxpos] < array[j])
{
maxpos = j;
}
}
if (maxpos != size - i-1)
{
/*int tmp = array[maxpos];
array[maxpos] = array[size - i - 1];
array[size - i - 1] = tmp;*/
swap(array[maxpos], array[size - i - 1]);
}
}
}
直接选择排序的特性总结:
直接选择排序思考非常好理解,但是效率不是很好。实际中很少使用
时间复杂度:O(N^2)
空间复杂度:O(1)
稳定性:不稳定
2.2堆排序
堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。它是通过堆来进行选择数据。需要注意的是排升序要建大堆,排降序建小堆。
堆排序思路很简答
1.先创建堆
2.然后进行堆的尾删进行排序
代码实现(升序)
void HeapAdjust(int array[], int size, int parent)
{
int child = parent * 2 + 1;//左孩子
while (child < size)
{
if (child + 1 < size && array[child] < array[child + 1])
{
child += 1;
}
if (array[child] > array[parent])
{
swap(array[child], array[parent]);
parent = child;//更新双亲位置 继续向下调整
child = parent * 2 + 1;
}
else
{
return;//如果是大堆则返回空,继续循环调整.
}
}
}
void HeapSort(int array[],int size)
{
//1.建堆
int root = (size - 2) / 2;//找到最后一个非叶子节点的位置
for(root;root>=0;root--)
HeapAdjust(array, size, root);
//2.排序
int end = size - 1;
while (end)
{
swap(array[0], array[end]);//第一个个最后一个位置元素
HeapAdjust(array, end, 0);//调整那个位置传那个位置的元素下标
end--;//缩小数组范围
}
}
堆排序特性总结
堆排序使用堆来选数,效率就高了很多。
时间复杂度:O(N*logN)
空间复杂度:O(1)
稳定性:不稳定