排序的分类:
按照存储位置分为:内部排序和外部排序
按照算法或者逻辑分为:插入排序、选择排序、交换排序、归并排序、基数排序
按照排序结果分为:升序排序和降序排序
时间复杂度:某个事件的执行次数
空间复杂度:临时存储的个数
稳定性:重复数据在排序前后位置不发生变化代表稳定
插入排序:包括直接插入排序和希尔排序
直接插入排序:
(1)把一个数组先划分成已排序好的部分和未排序的部分
(2)从未排序部分获取一个关键字作为待排序数
(3)从已排序部分找到合适的位置插入这个数据
代码如下:
void insertSort(int arr[], int len)
{
int i, j;
for (i = 2; i < len; ++i)
{
arr[0] = arr[i];
for (j = i - 1; arr[j] > arr[0]; --j)
{
arr[j + 1] = arr[j];
}
arr[j + 1] = arr[0];
}
}
直接插入排序的时间复杂度为O(n^2),空间复杂度为O(1),稳定
希尔排序:在直接插入排序的基础上给一个增量组合
代码如下:
void shell(int arr[], int arr_len,int dk)
{
int i, j;
int tmp;
for (i = dk; i < arr_len; ++i)
{
tmp = arr[i];
for (j = i - dk; j >= 0 && arr[j] > tmp; j = j - dk)
{
arr[j + dk] = arr[j];
}
arr[j + dk] = tmp;
}
}
void shellSort(int arr[], int arr_len, int dka[], int dka_len)
{
for (int i = 0; i < dka_len; ++i)
{
shell(arr,arr_len,dka[i]);
}
}
希尔排序的时间复杂度为O(n^1.3)~O(n^1.5),空间复杂度为O(1),不稳定
选择排序:包括简单选择排序和堆排序
简单选择排序:(以升序为例)
一趟排序中找到最小的数,二趟排序找到剩下数列中最小的数
代码如下:
void SelectSort(int arr[], int len)
{
int i, j;
int min;
int tmp;//O(n^2) O(1)
for (int i = 0; i < len-1; ++i)
{
min = i;
for (j = i + 1; j < len; ++j)
{
if (arr[j] < arr[min])
{
min = j;
}
}
tmp = arr[min];
arr[min] = arr[i];
arr[i] = tmp;
}
}
堆排序代码如下:
void HeapAdjust(int arr[], int i, int len)
{
int j;
//j <= len 有左子树
for (j = 2 * i; j <= len; j = 2 * j)
{
if (j < len && arr[j] < arr[j + 1])
{
j++;
}
if (arr[j] < arr[i])break;
arr[0] = arr[i];
arr[i] = arr[j];
arr[j] = arr[0];
i = j;
}
}
void HeapSort(int arr[], int len)
{
int tmp;
for (int i = len / 2; i > 0; --i)
{
//i 当前要调整的堆的父节点下标 len 有效长度
HeapAdjust(arr,i,len);
}
for (int j = len; j > 0; --j)
{
tmp = arr[1];
arr[1] = arr[j];
arr[j] = tmp;
HeapAdjust(arr, 1, j-1);
}
}
交换排序:冒泡排序、快速排序
冒泡排序代码如下:
void BubbleSort(int arr[], int len)
{
int tmp;
bool mark = false;
for (int i = 0; i < len-1; i++)
{
mark = false;
for (int j = 0; j < len - 1 - i; ++j)
{
if (arr[j]>arr[j + 1])
{
tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
mark = true;
}
}
printf("i = %d\n", i);
if (!mark)
{
break;
}
}
}
归并排序:
(1)分:二分法
(2)合:小组按照二分法分出的小组组合
(归并排序的所有index都是下标)
代码如下:
void Merge(int arr[], int tmp[], int startIndex, int midIndex, int endIndex)
{
int i = startIndex;
int j = midIndex + 1;
int k = startIndex;
while (i != midIndex + 1 && j != endIndex + 1)
{
if (arr[i] > arr[j])
{
tmp[k++] = arr[j++];
}
else
{
tmp[k++] = arr[i++];
}
}
while (i != midIndex + 1)
{
tmp[k++] = arr[i++];
}
while (j != endIndex + 1)
{
tmp[k++] = arr[j++];
}
for (int i = startIndex; i <= endIndex; ++i)
{
arr[i] = tmp[i];
}
}
void MergeSort(int arr[], int tmp[], int startIndex, int endIndex)
{
if (startIndex < endIndex)
{
int midIndex = (startIndex + endIndex) / 2;
MergeSort(arr, tmp, startIndex, midIndex);
MergeSort(arr, tmp, midIndex + 1, endIndex);
Merge(arr, tmp, startIndex, midIndex, endIndex);
}
}
基数排序:排序趟数为最大值的位数
代码如下:
#define N 13
//double pow(double,int);
int FindMaxFinger(int arr[], int len)//求最大数的位数
{
int max = arr[0];
for (int i = 1; i < len; ++i)
{
if (arr[i] > max)
{
max = arr[i];
}
}
int count = 0;
while (max != 0)
{
max = max / 10;
count++;
}
return count;
}
//每个数据位的数 num/pow(10.0,fin)%10
int FindFingerNumber(int num, int fin)
{
return num / (int)pow(10.0,fin) % 10;
}
//0,1,2(个,十,百) 0不能参与排序
void Radix(int arr[], int len, int fin)
{
int tmp[10][N] = {};
int num_fin;
int count;
for (int i = 0; i < len; ++i)
{
count = 0;
num_fin = FindFingerNumber(arr[i], fin);//每个数据位的数
while (tmp[num_fin][count] != 0)
{
count++;
}
tmp[num_fin][count] = arr[i];
}
count = 0;
for (int i = 0; i < 10; ++i)
{
for (int j = 0; j < len; ++j)
{
if (tmp[i][j] != 0)
{
arr[count++] = tmp[i][j];
}
else
{
break;
}
}
}
}
//0可以参与排序
void Radix1(int arr[], int len, int fin)
{
int tmp[10][N] = {};
int num_fin;
int count[10] = {};
for (int i = 0; i < len; ++i)
{
num_fin = FindFingerNumber(arr[i], fin);
tmp[num_fin][count[num_fin]] = arr[i];
count[num_fin]++;
}
int index = 0;
for (int i = 0; i < 10; ++i)
{
for (int j = 0; j < count[i]; ++j)
{
arr[index++] = tmp[i][j];
}
}
}
//每趟循环调用Radix()
void RadixSort(int arr[], int len)
{
int maxFinNum = FindMaxFinger(arr, len);
for (int i = 0; i < maxFinNum; ++i)
{
Radix1(arr, len, i);
}
}