归并排序:
基本思想
分解+合并(将已有的子序列合并,得到完全有序的序列。)
最重要的观点
1.将两段有序的子区间,可以合成一段有序的序列,时间复杂度为O(n)。
2.认为单个元素是有序的
图解:
代码实现
:
void _MergrSort(int* a, int begin, int end, int* tmp)
{
if (begin >= end)//每段只有一个元素的返回
return;
int mid = (begin + end) / 2;
//递归分段
_MergrSort(a, begin, mid, tmp);
_MergrSort(a, mid + 1, end, tmp);
int begin1 = begin;
int begin2 = mid + 1;
int end1 = mid;
int end2 = end;
int index = begin;
//将两段合成一段有序序列
while (begin1 <= end1&&begin2 <= end2)
{
if (a[begin1] < a[begin2])
{
tmp[index++] = a[begin1++];
}
else
{
tmp[index++] = a[begin2++];
}
}
//将剩余部分添加到有序序列
while (begin1 <= end1)
{
tmp[index++] = a[begin1++];
}
while (begin2 <= end2)
{
tmp[index++] = a[begin2++];
}
memcpy(a + begin, tmp + begin, sizeof(int)*(end - begin+1));
}
//归并序列的接口
void MergeSort(int* a, int length)
{
int* tmp = (int*)malloc(sizeof(int)*length);
_MergrSort(a, 0, length - 1, tmp);
free(tmp);
}
非比较排序:
思想
又称鸽巢原理。是对哈希定址法的变形应用。
具体操作步骤
1.统计相同元素的出现次数。
2.根据统计结果写回到原来的序列。
图解
代码实现
void CountSort(int* a, int n)
{
int max = a[0];
int min = a[0];
for (int i = 0; i < n; ++i)
{
if (a[i]>max)
{
max = a[i];
}
if (a[i] < min)
{
min = a[i];
}
}
int range = max - min + 1;
int* arr = (int*)malloc(sizeof(int)*range);
memset(arr, 0, sizeof(int)*range);
//统计数据出现的次数
for (int k = 0; k < n; ++k)
{
arr[a[k] - min]++;
}
int x = 0;
//,根据统计的次数,将数据在原数组中排序
for (int j = 0; j < range; ++j)
{
while (arr[j]--)
{
a[x++] = min + j;
}
}
}