直接插入排序&希尔排序
直接插入排序
时间复杂度:无序O(n^2) 有序O(n)
空间复杂度:O(1)
算法稳定性:稳定
原理:
把一个元素按升序或(降序)插入已经有序的一个序列里面,插入后保持序列的有序。
假设有序列arr[1…n],则将arr[2]插入arr[1…1]中,将arr[3]插入arr[1…2]中,
将arr[4]插入arr[1…3]中。如此经过n-1次的插入,便可以使arr[1…n]有序。
把待插入数与已有序的数列依次比较,找到合适位置,进行数据挪动,插入到合适位置。
(一直分为排序好的和无序的两个部分,从待排序的数值里找一个插入到排序好的数值里)
例:4 1 5 12 0
第一趟:tmp=1 1<4 1 4
第二趟:tmp=5 1 4 5
第三趟:tmp=12 1 4 5 12
第四趟:tmp=0 0<12,0<5,0<4,0<1 0 1 4 5 12
void Insert_Sort(int *arr, int len)
{
int i,j;
int tmp=0;
for (i = 1; i < len; i++)
{
tmp = arr[i];//把将要比较的值放入tmp里
for (j = i - 1; j >= 0; j--)//j在i的前一位
{
if (tmp < arr[j])//如果tmp里的值比j的值小就互换tmp和j的值
{
arr[j + 1] = arr[j];//即把j里的值放在下一位,把tmp的值放在原来j的位置
}
else
{
break;
}
}
arr[j + 1] = tmp;//不是则就放在它原来的位置,包扩j减到-1位置 j+1位0号位置
}
}
希尔(shell)排序 :直接插入的优化
分组的直接插入排序—》先对数据进行分组,使用直接插入算法使得组内有序再分组,在直接插入使组内有序,直到分组只有一个
时间复杂度:O(n1.3)——O(n1.5)
空间复杂度:O(1)
算法稳定性:不稳定
原理:设定一个增量gap,每次插入排序使相距为d的元素排成一个有序列,
然后缩小增量,继续插入排序,最后一次gap=1,排序完成 。
在进行大量数据排序上,效率较高,因为相比于冒泡,选择排序,
其每次操作省略了三步赋值的开销,只有一步。
版本1
void Shell(int *arr, int len,int gap)
{
int i, j;
int tmp = 0;
for (i = gap; i < len; i++)
{
tmp = arr[i];
for (j = i - gap; j >= 0; j-=gap)
{
if (tmp < arr[j])
{
arr[j + gap] = arr[j];
}
else
{
break;
}
}
arr[j + gap] = tmp;
}
}
void Shell_Sort(int *arr, int len)
{
int drr[] = { 5,3,1 };//素数数组
int lend = sizeof(drr) / sizeof(drr[0]);
for (int i = 0; i < lend; i++)
{
Shell(arr, len, drr[i]);
}
}
主函数及测试:
void Show(int *arr,int len)
{
for (int i = 0; i < len; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
int main()
{
int arr[] = {12,45,68,76,24,5};
int len = sizeof(arr) / sizeof(arr[0]);
//Select_Sort(arr, len);
//Bubble_Sort(arr, len);
Bubble_Sort2(arr,len);
//Insert_Sort(arr,len);
Show(arr, len);
/*int arr[] = { 12,45,68,76,24,5,85,65,2,4,78,95 };
int len = sizeof(arr) / sizeof(arr[0]);
Shell_Sort(arr, len);
Show(arr, len);*/
}
版本2
void Shell(int *arr, int len, int t)
{
int i = t;
int j = 0;
int tmp = 0;
while (i < len)
{
tmp = arr[i];
j = i - t;
while (j >= 0 && arr[j] > tmp)
{
arr[j + t] = arr[j];
j -= t;
}
arr[j + t] = tmp;
i++;
}
}
// O(n^1.3--1.5) O(1) 不稳定
void ShellSort(int *arr, int len)
{
int d[] = { 7, 5, 3, 1 };
for (int i = 0; i < sizeof(d) / sizeof(d[0]); ++i)
{
Shell(arr, len, d[i]);
}
}