void Insert_Sort(int *arr, int len)
{
//for(int i=0; i
for(int i=1; i<len; i++)//控制需要跑多少趟len-1
{
int tmp = arr[i];
int j;
for(j=i-1; j>=0; j--)//控制在已排序好序列中,找到待排序值 可以插入的合适的位置
{
if(arr[j] > tmp)
{
arr[j+1] = arr[j];
}
else//arr[j] <= tmp
{
//arr[j+1] = tmp; //找到一个小于或者等于tmp的值
break;
}
}
arr[j+1] = tmp; //触底之后的处理规则
}
}
关键点就是如何让待排序序列数量降低
假设有15个数字
分割方法2:跳跃分割,分割成5组,一个组三个数,每个值之间距离三个数
希尔排序也叫最小增量排序,有一个最重要的标志——增量数组
void Shell(int *arr, int len, int gap)
{
//假设gap=5,则认为前5个值已经有序,则让i直接指向第一个组的第二个值下标
for(int i=gap; i<len; i++)//这里修改了
{
int tmp = arr[i];
int j;
for(j=i-gap; j>=0; j=j-gap)//这里修改了
{
if(arr[j] > tmp)
{
arr[j+gap] = arr[j];//这里修改了
}
else
{
break;
}
}
arr[j+gap] = tmp; //这里修改了
}
}
//希尔排序 时间复杂度可以认为O(n^1.3 ~ n^1.7) 空间复杂度O(1) 稳定性:不稳定
void Shell_Sort(int *arr, int len)
{
int gap[] = {5,3,1};
for(int i=0; i<sizeof(gap)/sizeof(gap[0]); i++)
{
Shell(arr, len, gap[i]);
}
}
int main()
{
int arr[] = { -43,57,-71,47,3,30,-85,6,60,-59,0,-46,-40,-73,53,68,-82,-54,88,73,20,-89,-22,39,55,-26,95,-87,-57,-86,28,-37,43,-27,-24,-88,-35,82,-3,39,-85,-46,37,45,-24,35,-49,-27,-96,89,87,-62,85,-44,64,78,14,59,-55,-10,0,98,50,-75,11,97,-72,85,-68,-76,44,-12,76,76,8,-75,-64,-57,29,-24,27,-3,-45,-87,48,10,-13,17,94,-85,11,-42,-98,89,97,-66,66,88,-89,90,-68,-62,-21,2,37,-15,-13,-24,-23,3,-58,-9,-71,0,37,-28,22,52,-34,24,-8,-20,29,-98,55,4,36,-3,-9,98,-26,17,82,23,56,54,53,51,-50,0,-15,-50,84,-90,90,72,-46,-96,-56,-76,-32,-8,-69,-32,-41,-56,69,-40,-25,-44,49,-62,36,-55,41,36,-60,90,37,13,87,66,-40,40,-35,-11,31,-45,-62,92,96,8,-4,-50,87,-17,-64,95,-89,68,-51,-40,-85,15,50,-15,0,-67,-55,45,11,-80,-45,-10,-8,90,-23,-41,80,19,29,7 };
Insert_sort(arr, sizeof(arr) / sizeof(int));
shell_sort(arr, sizeof(arr) / sizeof(int));
show(arr, sizeof(arr) / sizeof(int));
return 0;
}
希尔排序是直接插入排序的优化,两者关系十分密切,但是要记住希尔排序不稳定,直接插入排序是稳定的