
直接插入排序是一种简单的排序算法,它将数组分为有序和无序两部分,和插入排序的思路有些类似。
时间复杂度:O( N^2)
这里我们拿升序举例,具体思路如下:
图解:



代码如下:
void SleteSort(int* a, int n)
{
for (int i = 0; i < n - 1; i++)
{
int mini = i, min = a[i];
for (int j = i; j < n; j++)
{
if (a[j] < a[mini])
{
min = a[j];
mini = j;
}
}//找最值
int tmp = a[i];
a[i] = a[mini];
a[mini] = tmp;//交换
}
}优化:
每次遍历找最大值和最小值,把最大值放后面,最小值放前面。
void Sweap(int* a, int* b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
void SelectSort(int* arr, int n)
{
int begin = 0, end = n - 1;
while (begin < end)
{
int max = arr[begin], min = arr[begin], maxi = begin, mini = begin;
for (int i = begin; i <= end; i++)
{
if (min > arr[i])
{
min = arr[i];
mini = i;
}
if (max < arr[i])
{
max = arr[i];
maxi = i;
}
}
//这里是特殊情况,避免最大值的位置和begin的位置重复
//判断max的位置是因为要先交换最小值,这块可以仔细想想
if (maxi == begin)
{
maxi = mini;
}
Sweap(&arr[begin], &arr[mini]);//交换,这里分装成一个函数了
Sweap(&arr[end], &arr[maxi]);
begin++;
end--;
}
}堆排序是直接选择排序的进阶版,他在其原本的思想上进行了优化。
下面的内容涉及一部分数据结构堆的知识,不适合新手学习。
我们依然拿升序举例子,具体步骤如下:
时间复杂度:O( N * logN)
图解如下:





具体代码如下:
void Sweap1(int* a, int* b)
{
int tem = *a;
*a = *b;
*b = tem;
}
void AdjustDown1(int* a, int size, int child)//向下调整的函数
{
int partent = child;
child = child * 2 + 1;
while (child < size)
{
if (child + 1 < size && a[child] > a[child + 1])
child++;
if (a[child] < a[partent])
{
Sweap1(&a[child], &a[partent]);
partent = child;
child = child * 2 + 1;
}
else
{
break;
}
}
}
void HeapSort(int* a, int n)
{
int end = n - 1;
for (int i = (n - 1 - 1) / 2; i >= 0; i--)//从倒数第二层的最后一个元素开始的
{
AdjustDown1(a, i, 0);
}
while (end > 0)
{
Sweap1(&a[end], &a[0]);
AdjustDown1(a, end, 0);//向下调整;
end--;
}
}