一、排序
定义
排序是数据处理中经常使用的一种重要运算,它是将一组无序的数据元素按其关键字的某种次序排列成有规律的序列,排序的目的之一就是方便数据的查找,排序分为内排序和外排序。
二、计数排序
定义
计数排序顾名思义,即统计每一个元素出现的次数,再按照顺序 依次排列。数列中的元素就是“票”,而一个与元素取值范围相 符的数组就是“票箱”。
记n为数列长度, m为取值范围。 需要
O(n)的时间统计每一数值出现次数。之后再用O(n+m)的时 间构造出结果数列,总时间O(n + m)。
另外,需要O(m)的额外空间作为票箱。
优点:当m较小时,时间复杂度近似于O(n),性能强大。
缺点:当m远大于n时,时空复杂度均取决于m,得不偿失。 取值范围为非整数时,无法实现。
三、冒泡排序(Bubble Sort)
思路:不超过n次大循环;每次大循环,按照顺序比较相邻元素并 交换,直到序列有序。
代码实现
for (int i = 0; i < n - 1; i++)
{
for (int j = 0; j < n - i - 1; j++)
{
if (a[j] > a[j + 1])
{
swap(a[j], a[j + 1]);
}
}
}
特点: 总交换次数恰为逆序对数。 每次迭代都能保证至少一个(最大)元素的位置被确定。 后i个元素有序,且为最大的i个元素。
四、选择排序
思路:n次大循环,第i次大循环中,用小循环寻找数列中第i小的 元素。如果发现更小的数字,则交换至第i个位置。
代码实现
for (int i = 0; i < n - 1; i++)
{
for (int j = i + 1; j < n; j++)
{
if (a[j] < a[i])
{
swap(a[i], a[j]);
}
}
}
特点:
思路简单,实现更简单。
每次迭代都能保证至少一个(最小)元素的位置被确定。
前i个元素有序,且为最小的i个元素。
五、插入排序
思路:n次大循环;第i次大循环将第i个元素向前交换,直至左侧 元素不大于它,或抵达数列首部。
代码实现
for (int i = 1; i < n; i++) {
{
int now = a[i], j;
for (int j = i - 1; j >= 0; j--)
{
if (a[j] > now)
{
a[j + 1] = a[j];
else break;
a[j + 1] = now;
}
}
}
特点:
前i个元素有序。但是直到排序完成,不能保证任何一个元 素的最终位置被确定(设想最小元素在数列尾部)。
可以用来动态维护前k小元素,单次插入时间复杂度O(k) 。在此场 景下,第k + 1小的元素将不会右移,而是被直接丢弃。
六、快速排序
定义
快排是一种基于分治法的排序算法。 大多数基于分治法的算法均具有O(nlogn)的时间复杂度。