#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
//冒泡排序 时间复杂度 n2 空间复杂度 1 稳定
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n - 1 - i; j++)
{
if (a[j] > a[j + 1])
{
int temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
//选择排序 n2 1 不稳定
for (int i = 0; i < n - 1; i++)
{
mindex = i;
for (int j = 0; j < n; j++)
{
if (a[j] < a[mindex])
{
mindex = j;
}
}
int temp = a[i];
a[i] = a[mindex];
a[mindex] = tepmp;
}
//插入排序 n2 1 稳定
for (int i = 1; i < n; i++)
{
for (int j = i - 1; j >= 0; j--)
{
if (a[j] > a[j + 1])
{
int temp = a[j];
a[j] = a[j + 1];
a[j + 1] = a[j];
}
else
{
break;
}
}
}
//直接插入排序 最差n2 最好n 适合相对有序
for (int i = 0; i < n - 1; i++)
{
int end = i;
int temp = a[i + 1];
while (end >= 0)
{
if (temp < a[end])
{
a[end + 1] = a[end];
end--;
}
else
{
break;
}
}
a[end + 1] = temp;
}
// 希尔排序 n1.3 = nlogn
while (gap > 1)
{
int gap = gap / 2;
for (int i = 0; i < n - gap; i++)
{
int end = i;
int tmp = a[end + gap];
while (end >= 0)
{
if (tmp < a[end])
{
a[end + gap] = a[end];
end -= gap;
}
else
{
break;
}
}
a[end + gap] = tmp;
}
}
//快速排序 nlongn 1
void ks(arr, begin, end)
{
if (begin >= end)
{
return;
}
int i = begin;
int j = end;
int temp = arr[begin];
while (i != j)
{
while (arr[j] >= temp && j > i)
{
j--;
}
while (arr[i] <= temp && j > i)
{
i--;
}
if (j > i)
{
int i = arr[j];
arr[j] = arr[i];
arr[i] = i;
}
}
arr[begin] = arr[i];
arr[i] = temp;
ks(arr, begin, i - 1);
ks(arr, i + 1, end);
}
//堆排序 升序建大堆 降序建小堆
// 向下调整建堆是n 向上调整建堆是nlogn (公式证明 错位相减法)
// 堆排序是nlongn (但如果升序用小堆排序则是n2)
// 大堆和小堆 只需改变下符号
void ADjustdown(int* a, int n, int parent)
{
int child = 2 * parent + 1;
while (child < n)
{
if (child + 1 < n && a[child + 1] > a[child])
{
child = child + 1;
}
if (a[child] > a[parent])
{
swap(&a[child], &a[parent]);
parent = child;
child = parent * 2 + 1;
}
else
{
break;
}
}
}
void Heapsort(int* a, int n)
{
int i = 0;
for (i = (n - 1 - 1) / 2; i >= 0; i--) //n
{
ADjustdown(a, n, i);
}
int end = n - 1;
while (end > 0)
{
swap(&a[end], &a[0]);
ADjustdown(a, end, 0); //nlongn
end--;
}
}
//归并排序 nlogn 空间复杂度n
void _ms(int* a, int left, int right, int* tmp)
{
if (left >= right)
{
return;
}
int mid = left + (right - left) / 2;
_ms(a, left, mid, tmp);
_ms(a, mid + 1, right, tmp);
int begin1 = left;
int end1 = mid;
int begin2 = mid + 1;
int end2 = right;
int i = left;
while (begin1 <= end1 && begin2 <= end2)
{
if (a[begin1] > a[begin2])
{
tmp[i++] = a[begin2++];
}
else
{
tmp[i++] = a[begin1++];
}
}
while(begin1 <= end1)
{
tmp[i++] = a[begin1++];
}
while (begin2 < end2)
{
tmp[i++] = a[begin2++]
}
for (int j = left; j <= right; j++)
{
a[j] = tmp[j];
}
}
// 内排序:数据量相对少一些,可以放到内存中进行排序。
//外排序:数据量较大,内存中放不下,数据只能放到磁盘文件中,需要排序。
//
//上面介绍的排序算法均是在内存中进行的,对于数据量庞大的序列,上面介绍的排序算法都束手无策,而归并排序却能胜任这种海量数据的排序。
//
//假设现在有10亿个整数(4GB)存放在文件A中,需要我们进行排序,而内存一次只能提供512MB空间,归并排序解决该问题的基本思路如下:
//1、每次从文件A中读取八分之一,即512MB到内存中进行排序(内排序),并将排序结果写入到一个文件中,然后再读取八分之一,重复这个过程。那么最终会生成8个各自有序的小文件(A1~A8)。
//2、对生成的8个小文件进行11合并,最终8个文件被合成为4个,然后再11合并,就变成2个文件了,最后再进行一次11合并,就变成1个有序文件了。
//计数排序 n + range 空间复杂度range
void CountSort(int* a, n)
{
int max = a[0];
int min = a[0];
for (int i = 0; i < n; i++)
{
if (a[i] < min) min = a[i];
if (a[i] > max) max = a[i];
}
int range = max - min + 1;
int* count = (int*)calloc(sizeof(int) * range, 0);
for (int i = 0; i < n; i++)
{
count[a[i] - min]++;
}
int j = 0;
for (int i = 0; i < range; i++)
{
while (count[i]--)
{
a[j++] = i + min;
}
}
free(count);
}
小丑改造计划之复习二 排序
最新推荐文章于 2024-08-16 17:15:42 发布