插入排序(insert sort)和它的升级版希尔排序(shell sort)
昨天终于把阮大佬的周刊给翻完了,可以这么说,我的书签文件夹里收藏的大部分资源都是来自左耳朵耗子和阮大佬的,周刊是翻完了,但回头来看,也没多少东西,是不是我的猎奇心理的问题,只是在发现新的东西时感到满意。现在看文件夹,每一个都想学,但是对待知识要有点滴意识,今天主要是想学排序算法的,但我又同时打开很多个网站,这样一来,效率就下降了,打开程序羊的,吴师兄的,鱼C的,还有一个是国外网站的,但我主要还是看后俩个,前两个都是把之前发在公众号上的文章聚合起来的,然后又会看到其它文章,就递归下去了......卡尔,帅地也是,都是把以前输出过的东西聚合起来,就是一本PDF或者是一个网站再升级就是合成一本书籍,这难道就是一点点的做然后经年累月,就会成为一个产品吗?想想刘同当年也是,每天写日记,然后投稿,最后合成一本书《谁的青春不迷茫》,就是不用刻意去做一件事,每天坚持做一点,然后就会享受时间带来的复利,想想看,基金也是一样,涨的日子多于跌的日子,一点点,时间长了,就会有高的点数,我中午看了一下,我当时买的军工,现在有40多个点了,市场就在哪里,如果跌的日子多,那反映出的信息就是国家的经济发展不好,但这是不可能的,国家的发展很快,这种趋势是不可逆转的。我看的那些公众号,博客,网站,我很羡慕他们能把一件事情通过动画讲解表达的很清晰,他们有这种输出,那他们的输入可能就是输出的2倍或者更多倍。
最后一句话总结上面的文字:慢慢来才会更快!
首先看的是insert sort,上代码
1 #include<stdio.h> 2 3 void insert_sort(int arr[],int size) 4 { 5 int i,j; 6 for ( i = 1; i != size; ++i)//从一开始是因为默认index = 0的元素有序 7 { 8 int temp = arr[i];//temp永远都是最右面那群未排序的元素中的第一位,这步操作可以说是从原来数组中抽出一个来,那它在数组中的位置就可以随便被用了 9 for ( j = i - 1; j >= 0 && arr[j] > temp; --j)//一开始我把更新条件写成了j -= i 10 {//如果前者比后者大,就把它往后一位覆盖,那后一位的数据不就没了吗?别怕,在temp那里有 11 arr[j + 1] = arr[j]; 12 } 13 arr[j + 1] = temp; 14 } 15 } 16 17 void printsort(int arr[],int size) 18 { 19 for (int i = 0; i != size; ++i) 20 { 21 printf("%d ",arr[i]); 22 } 23 printf("\n"); 24 } 25 26 27 int main() 28 { 29 int array[] = {0,17,9,2,7,14,8,12}; 30 int size = sizeof(array) / sizeof(array[0]); 31 insert_sort(array,size); 32 printf("Increasing sort:"); 33 printsort(array,size); 34 return 0; 35 }
插入排序就是一个元素慢慢从后往前挪,从而找到自己的定位,这种就很慢了,有没有相对较快的办法呢?这样问了,那肯定是有的,希尔排序就是插入排序的改进方法啦,它的妙处在于充分利用了我们幼儿园就学会的知识,那就是大的元素排后面,小的元素排前面,其实还是后面的元素和前面的元素比较,前面元素大就和后面的元素交换,只不过啊,它把比较两数的间距拉大了而已,例如第一位元素是9,那如果它后面的元素都比它小,如果用插入排序,那它就是踽踽独行啊,一步步接近属于它的坐标,如果用希尔排序,就省事很多了,有点二分的味道。上代码
1 #include<stdio.h> 2 3 void shell_sort(int arr[],int size) 4 { 5 int i,j,span; 6 for (span = size >> 1; span > 0; span >>= 1)//这行就是扩大两个元素的比较范围 7 { 8 for (int i = span; i != size; ++i)//和插入排序一样,默认第一位元素有序,只不过这里和第一位元素比较的不在是它后面的元素了 9 { 10 int temp = arr[i]; 11 for (j = i - span; j >= 0 && arr[j] > temp; j -= span)//其实这循环就执行一次 12 { 13 arr[j + span] = arr[j]; 14 } 15 arr[j + span] = temp; 16 } 17 } 18 } 19 20 void printsort(int arr[],int size) 21 { 22 for (int i = 0; i != size; ++i) 23 { 24 printf("%d ",arr[i]); 25 } 26 printf("\n"); 27 } 28 29 30 int main() 31 { 32 int array[] = {0,17,9,2,7,14,8,12}; 33 int size = sizeof(array) / sizeof(array[0]); 34 shell_sort(array,size); 35 printf("Increasing sort:"); 36 printsort(array,size); 37 return 0; 38 }
本质上都相同,那又有小朋友会有疑问啦,希尔排序到达比插入排序快多少?希尔排序有三个for循环,怎么还比插入排序快?这位小朋友就是只会看表象,难道在幼儿园的时候老师和你说有多少个for循环,那它的时间复杂度就是大O n的几次方?
插入排序和希尔排序的空间复杂度都是O(1)
插入排序的平均时间复杂度和最坏时间复杂度都是O(n^2)
希尔排序的平均时间复杂度是O(nlogn),最坏时间复杂度是O(n^2)
浙公网安备 33010602011771号