目录
一、直接插入排序
1.算法思想
将第i个记录插到前面i-1个已排好的记录中。
2.排序过程
对48 62 35 77 55 14 35 98进行排序
{}内为已排好的序列,_标志的为将要插入的值
第一步:{48} 62 35 77 55 14 35 98
第二步:{48 62} 35 77 55 14 35 98
第三步:{35 48 62} 77 55 14 35 98
第四步:{35 48 62 77} 55 14 35 98
第五步:{35 48 55 62 77} 14 35 98
第六步:{14 35 48 55 62 77} 35 98
第七步:{14 35 35 48 55 62 77} 98
第八步:{14 35 35 48 55 62 77 98}
3.算法
void InsertSort(int ar[], int left, int right)
{
for (int i = left + 1; i < right; i++)
{
for (int j = i; j > left; j--)
{
if (ar[j - 1] > ar[j])
{
int tmp = ar[j];
ar[j] = ar[j - 1];
ar[j - 1] = tmp;
}
}
}
}
二、折半插入排序
1.算法思想
在确定插入位置时,采用折半查找的方法。
2.算法
void BinInsertSort(int* ar, int left, int right)
{
for (int i = left + 1; i < right; i++)
{
int tmp = ar[i];
int low = left;
int high = i - 1;
//寻找插入位置
while (low <= high)
{
int mid = (low + high) / 2;
if (tmp >= ar[mid])
low = mid + 1;
else
high = mid - 1;
}
//将要排序的值插入
for (int j = i; j > low; j--)
ar[j] = ar[j - 1];
ar[low] = tmp;
}
}
三、希尔排序
1.算法思想
将待排序列的关键字序列分成若干个较小的子序列,对子序列进行直接插入排序。
2.排序过程
如图:
3.算法
void _ShellSort(int* ar, int left, int right, int gap)
{
for (int i = left + gap; i < right; ++i)
{
int tmp = ar[i];
int j = i;
while (j > left && tmp < ar[j - gap])
{
ar[j] = ar[j - gap];
j -= gap;
}
ar[j] = tmp;
}
}
//分组
void _ShellSort(int* ar, int left, int right)
{
int dlta[] = { 5,3,2,1 }; //素数
int n = sizeof(dlta) / sizeof(dlta[0]);
for (int i = 0; i < n; ++i)
{
_ShellSort(ar, left, right, dlta[i]);
}
}
四、总结
排序算法 | 时间复杂度 | 最好情况 | 最坏情况 | 空间复杂度 | 稳定性 |
直接插入 | 稳定 | ||||
折半插入 | 稳定 | ||||
希尔排序 | 不稳定 |