作者介绍:一名正在学习编程技术的萌新,希望和大家一起进步。上传的内容,都是我学习过程中的笔记。
个人主页:个人主页
数据结构专栏:数据结构
深入浅出从插入排序到希尔排序
什么是插入排序
插入排序可以理解为打扑克摸牌的过程,从3到大小王,当你摸了一张梅花10,就从大小王开始比直到遇到九就插入在9的后面,这就是插入排序!
插入排序的实现
单躺的插入排序过程(均以升序为例)
一直比较tmp和a[end]直到找到第一个比tmp小的为止,或者end走到-1了也就是tmp是最小的
while (end >= 0)//一直比较tmp和a[end]直到找到第一个比tmp小的为止,或者end走到-1了也就是tmp是最小的
{
int tmp=[end+1];
if (a[end] > tmp)
{
a[end+1] = a[end];
end--;
}
else
{
break;
}
}
a[end + 1] = tmp;//这种写法非常巧妙把end=-1和正常情况合二为一了
完整的插入排序
也就多了一个end和tmp的赋值,相当于最开始排两个然后,后面依次加一个
void InsertSort(int *a,int se)
{
int tmp, end;
for (int i = 1; i < se; i++)
{
end = i - 1;
tmp = a[i];
while (end >= 0)
{
if (a[end] > tmp)
{
a[end+1] = a[end];
end--;
}
else
{
break;
}
}
a[end + 1] = tmp;
}
}
插入排序的时间效率
最坏的情况下是每次都要挪动也就是逆排序,1+2+3+…n
为(n*n)级,但是它比冒泡排序好,因为冒泡每次都是无脑比较,固定1+2+3…n;
插入排序到希尔排序
希尔排序是插入排序的升级
1.先预排序
2.再插入排序
预排序的实现
单躺的一组gap的预排序
和插入排序很像,当gap=1时就是单躺的插入排序了
while (end >= 0)
{
int tmp=a[end+gap];
if (tmp < a[end])
{
a[end+gap] = a[end];
end -= gap;
}
else
{
break;
}
}
a[end + gap] = tmp;
所有组gap的预排序法一(一组一组的排)
一组一组的排,排完红色排蓝色排完蓝色排绿色
for (int j = 0; j < gap; j++)
{
for (int i = j; i < n - gap; i += gap)
{//一组一组的排
end = i;
tmp = a[end + gap];
while (end >= 0)
{
if (tmp < a[end])
{
a[end+gap] = a[end];
end -= gap;
}
else
{
break;
}
}
a[end + gap] = tmp;
}
所有组的预排序法二(多组并排)
for (int i = 0; i < n - gap; i++)
{
end = i;
tmp = a[end + gap];
while (end >= 0)
{
if (a[end] > tmp)
{
a[end + gap] = a[end];//往前挪动
end -= gap;
}
else
{
break;
}
}
a[end + gap] = tmp;
}
}
}
希尔排序的完整过程
就是多了个gap 当gap==1时就是插入排序了
gap=gap/3+1 gap永远都可以为一!
void ShellSort2(int *a,int n)
{
int end, tmp;
int gap = n;
while (gap > 1){
gap = gap / 3 + 1;
for (int i = 0; i < n - gap; i++){
end = i;
tmp = a[end + gap];
while (end >= 0){
if (a[end] > tmp){
a[end + gap] = a[end];//往前挪动
end -= gap;
}
else{
break;
}
}
a[end + gap] = tmp;
}
}
}
希尔排序的时间效率
while循环了logN次因为gap = gap / 3 + 1;每次都除以3;所以log级,预排序的每次的次数*是n级,总的时间效率简单的分析为nlogn!
可以看出希尔排序还是比较优秀的排序
谢谢观看
如果对你有帮助,那就真的太荣幸了!