1.插入排序
1.1 基本思想
直接插入排序是一种简单的插入排序法,其基本思想是:
把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为为止,得到一个心得有序序列。
1.2 直接插入排序
直接上代码!!
void InsertSort(int* nums, int n)
{
for (int i = 0; i < n - 1; i++)
{
int tmp = nums[i + 1];
int end = i;
while (end >= 0)
{
if (nums[end] > tmp)
{
nums[end + 1] = nums[end];
--end;
}
else break;
}
nums[end + 1] = tmp;
}
}
特性总结:
1.元素集合越接近有序,直接插入排序的时间效率越高
2.时间复杂度:O(n^2)
3.空间复杂度:O(1)
4.稳定性:稳定
希尔排序
void ShellSort(int* a, int n)
{
int gap = n;
while (gap > 1)
{
gap = gap / 3 + 1;
for (int i = 0; i < n - gap; i++)
{
int tmp = a[i + gap];
int end = i;
while (end >= 0)
{
if (a[end] > tmp)
{
a[end + gap] = a[end];
end -= gap;
}
else break;
}
a[end + gap] = tmp;
}
}
}
特性总结
1.希尔排序是对直接插入排序的优化。
2.当gap > 1的时候都是预排序,目的是让数组更接近有序,这样就可以加快数组排序的效率。整体而言可以达到优化的效果
3.希尔排序的时间复杂度的不好计算,因为gap的取值方法很多,导致很难计算。以这段代码gap的取值方式暂时按照O(n^1.25)到O(1.6 * n^1.25)来算
4.稳定性:不稳定
2.选择排序
2.1 直接选择排序
void SelectSort(int* a, int sz)
{
for(int i = 0;i < sz;i ++)
for (int j = i + 1; j < sz; j++)
{
if (a[i] > a[j])
{
a[i] ^= a[j];
a[j] ^= a[i];
a[i] ^= a[j];
}
}
}
特性总结:
- 直接选择排序思考非常好理解,但是效率不是很好。实际中很少使用
- 时间复杂度:O(N^2)
- 空间复杂度:O(1)
- 稳定性:不稳定
2.2 堆排序
void AdjustDown(int* a, int pos, int end)
{
if (pos * 2 + 2 > end)
return;
int t = pos * 2 + 1;
if (t + 1 < end && a[t + 1] > a[t]) t++;
if (a[pos] < a[t])
{
a[pos] ^= a[t];
a[t] ^= a[pos];
a[pos] ^= a[t];
AdjustDown(a, t, end);
}
}
void HeapSort(int* a, int n)
{
for (int i = (n - 2) / 2; i >= 0; i--)
AdjustDown(a, i, n);
while (n)
{
Swap(&a[0], &a[n - 1]);
n--;
AdjustDown(a, 0, n);
}
}
特性总结
- 堆排序使用堆来选数,效率就高了很多。
- 时间复杂度:O(N*logN)
- 空间复杂度:O(1)
- 稳定性:不稳定
3.交换排序
3.1选择排序
void BubbleSort(int* a, int n)
{
for (int j = 0; j < n; ++j)
{
bool exchange = false;
for (int i = 1; i < n-j; i++)
{
if (a[i - 1] > a[i])
{
int tmp = a[i];
a[i] = a[i - 1];
a[i - 1] = tmp;
exchange = true;
}
}
if (exchange == false)
{
break;
}
}
}
特性总结
- 冒泡排序是一种非常容易理解的排序
- 时间复杂度:O(N^2)
- 空间复杂度:O(1)
- 稳定性:稳定
3.2快速排序
void quick_sort(int q[], int l, int r)
{
if(l >= r)
return ;
int i = l - 1,j = r + 1, x = q[l + r >> 1];
while(i < j)
{
do i ++;while(q[i] < x);
do j --;while(q[j] > x);
if(i < j) swap(q[i], q[j]);
}
quick_sort(q, l, j);
quick_sort(q, j + 1, r);
}
特性总结:
- 快速排序整体的综合性能和使用场景都是比较好的,所以才敢叫快速排序
- 时间复杂度:O(N*logN)
-
- 空间复杂度:O(logN)
- 稳定性:不稳定