希尔排序
2016-03-06 14:52
288 查看
基本思想:希尔排序可以说实际上是直接插入排序的一种改进,具体思想是将N个元素的无序数列进行分组,分割成若干个子序列,然后在这每个子序列中进行直接插入排序,(直接插入排序对已经基本有序或是待排序数列元素个数很少时是非常高效的,这也正是希尔排序的精妙之处),当整个序列基本有序时,在对整个序列进行一次直接插入排序。
时间复杂度:n*log(n) 这个和增量gap的取值有关
空间复杂度:O(1)
是否是稳定排序:不是稳定排序
代码示例:
#include <stdio.h>
int println(int array[], int len)
{
int i = 0;
int ret = (array != NULL) && (len >= 0);
if(ret)
{
printf("array[]: ");
for(i=0; i<len; i++)
{
printf("%d ", array[i]);
}
printf("\n");
}
return ret;
}
int ShellSort(int array[], int len) // O(n*n)
{
int i = 0, j = 0;
int gap = len;
int temp = 0;//定义一个变量保存缓存值
int k = 0;
int ret = (array != NULL) && (len >= 0);
if(ret)
{
//这里用do-while循环,代码更简洁
do{
//这里取间距为3,gap == 1是就相当于对整个序列进行一次插入排序
gap = gap/3 + 1;//据说gap为3效率比较高,有待论证
for(i = gap; i < len; i += gap)//先以gap间距分组
{
k = i;//待比较数据下标,分组内每完成一趟直接插入排序 更新K值
temp = array[k];//先将array[i]的值保存起来
//temp = array[i];//直接这样会出错???
//原因很简单,就是第一次直接插入排序要记录待插入的位置
//如果不记录,k的初值被初始化为0而一开始key值是gap位置
//然后在每个分组内进行直接插入排序,原来的配方,原来的味道
for(j = i - gap; (j >= 0) && (array[j] > temp); j -= gap)
{
//1. 挪数据
array[j+gap] = array[j];
//2. 记录待插入位置
k = j;
}
//将待插入位置插入合适的位置
array[k] = temp;
}
}while(gap > 1);
}
return ret;
}
int main()
{
int array[] = {3, 8, 7, 1, 9, 2, 17, 4, 2, 13, 6};
int len = sizeof(array) / sizeof(*array);
println(array, len);
ShellSort(array, len);
println(array, len);
printf("Press enter to continue ...");
getchar();
return 0;
}
运行效果截图:
![](https://img-blog.csdn.net/20160306144957017?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
总结:发现把算法思路反复的琢磨,把代码撸出来也没那么难!而且通过总结还能更加深刻的理解算法的精妙之处。
时间复杂度:n*log(n) 这个和增量gap的取值有关
空间复杂度:O(1)
是否是稳定排序:不是稳定排序
代码示例:
#include <stdio.h>
int println(int array[], int len)
{
int i = 0;
int ret = (array != NULL) && (len >= 0);
if(ret)
{
printf("array[]: ");
for(i=0; i<len; i++)
{
printf("%d ", array[i]);
}
printf("\n");
}
return ret;
}
int ShellSort(int array[], int len) // O(n*n)
{
int i = 0, j = 0;
int gap = len;
int temp = 0;//定义一个变量保存缓存值
int k = 0;
int ret = (array != NULL) && (len >= 0);
if(ret)
{
//这里用do-while循环,代码更简洁
do{
//这里取间距为3,gap == 1是就相当于对整个序列进行一次插入排序
gap = gap/3 + 1;//据说gap为3效率比较高,有待论证
for(i = gap; i < len; i += gap)//先以gap间距分组
{
k = i;//待比较数据下标,分组内每完成一趟直接插入排序 更新K值
temp = array[k];//先将array[i]的值保存起来
//temp = array[i];//直接这样会出错???
//原因很简单,就是第一次直接插入排序要记录待插入的位置
//如果不记录,k的初值被初始化为0而一开始key值是gap位置
//然后在每个分组内进行直接插入排序,原来的配方,原来的味道
for(j = i - gap; (j >= 0) && (array[j] > temp); j -= gap)
{
//1. 挪数据
array[j+gap] = array[j];
//2. 记录待插入位置
k = j;
}
//将待插入位置插入合适的位置
array[k] = temp;
}
}while(gap > 1);
}
return ret;
}
int main()
{
int array[] = {3, 8, 7, 1, 9, 2, 17, 4, 2, 13, 6};
int len = sizeof(array) / sizeof(*array);
println(array, len);
ShellSort(array, len);
println(array, len);
printf("Press enter to continue ...");
getchar();
return 0;
}
运行效果截图:
总结:发现把算法思路反复的琢磨,把代码撸出来也没那么难!而且通过总结还能更加深刻的理解算法的精妙之处。
相关文章推荐
- 如何组织构建多文件 C 语言程序(二)
- 如何写好 C main 函数
- 肯特·贝克:改变人生的代码整理魔法
- 你应该学习哪种编程语言?
- [转]我们需要一种其他人能使用的编程语言
- 书评:《算法之美( Algorithms to Live By )》
- DB2编程序技巧(1)
- DB2编程序技巧 (四)
- 女人VS编程_国庆快乐
- DB2编程序技巧 (六)
- DB2编程序技巧 (三)
- DB2编程序技巧 (九)
- DB2编程序技巧 (七)
- DB2编程序小小技巧
- DB2编程序技巧 (五)
- 动易2006序列号破解算法公布
- DB2编程序技巧 (一)
- DB2编程序技巧 (八)
- DB2编程序技巧 (十)
- VBS基础编程教程 (第1篇)