常见排序算法
2015-11-14 21:59
204 查看
1.qsort 快速排序算法
采用递归的方法。对于一个给定的数组,任取一个元素为界将其余元素划分为两个子集,一个子集中所有元素都小于该元素,另一个子集中的所有元素都大于或等于该元素。对这样两个子集递归执行这一过程,当某个子集中的元素个数小于或等于2时,这个子集就不需要再次排序,终止递归。
虽然书上说这是最简单的算法之一,但我理解起来并不顺畅,所以把它的思路写下来。
为使分界元素在对应的位置,排序的时候先把这个值放在最左边,然后从左往右第2个元素开始,遍历数组元素,小于分界元素的值依次交换到第2、3、4….的位置。设小于分界元素的子集中最右边的位置是n,最后将分界元素与n位置的元素交换。这样就完成了一次对子集的排序。
可以看出这个方法需要的栈空间相对较大,且递归的执行速度不快。但代码紧凑。
2.Shell排序算法
这个算法是D.L.Shell于1959年发明。其基本思想是:先比较距离较远的元素。减少大量的无需情况,从而减轻后续的工作。被比较的元素之间的距离逐渐减少,直到减少为1.
这个方法正面比较难以理解,它想出这个算法的思路是怎样的?但可以证明得出来的元素排列是有序的。
注意第三个for循环,它保证了{ v[0],v[gap],v[2*gap]…,v[j] }这个序列是递增的。想了半天,当间隔为1时,不就可以排序完成了吗?那还要前面第一个for循环干嘛?后来查了一下,间隔为1进行排序就是插入排序法,此方法的时间复杂度为O(n^2),和冒泡排序时间复杂度一样。shell排序的时间复杂度区间是[n*log2n, n^2]. 不稳定。shell排序的优点在于,远距离的元素之间的交换提高了效率。因为排序算法的步骤可分为两部分,判断的次数、交换元素位置的次数。显然shell排序的判断次数增加了,但交换元素位置的次数少了,而交换元素位置有三个步骤。
用shell排序、插入排序、快速排序对10W个随机数排序。结果分别为5.749s, 31.355s,6.729s
采用递归的方法。对于一个给定的数组,任取一个元素为界将其余元素划分为两个子集,一个子集中所有元素都小于该元素,另一个子集中的所有元素都大于或等于该元素。对这样两个子集递归执行这一过程,当某个子集中的元素个数小于或等于2时,这个子集就不需要再次排序,终止递归。
虽然书上说这是最简单的算法之一,但我理解起来并不顺畅,所以把它的思路写下来。
为使分界元素在对应的位置,排序的时候先把这个值放在最左边,然后从左往右第2个元素开始,遍历数组元素,小于分界元素的值依次交换到第2、3、4….的位置。设小于分界元素的子集中最右边的位置是n,最后将分界元素与n位置的元素交换。这样就完成了一次对子集的排序。
void qsort(int *v, int left, int right) { int last, i; void swap(int *v, int left, int right); if(left >= right) return; swap(v, left, (left+right)/2 ); last = left; for(i = left+1 ; i <= right; ++i) if( v[i]<v[left] ) swap(v, i, ++last); swap(v, left, last); qsort(v, left, last-1); qsort(v,last+1,right); } void swap(int *v, int left, int right) { int temp; temp = v[left]; v[left] = v[right]; v[right] = temp; }
可以看出这个方法需要的栈空间相对较大,且递归的执行速度不快。但代码紧凑。
2.Shell排序算法
这个算法是D.L.Shell于1959年发明。其基本思想是:先比较距离较远的元素。减少大量的无需情况,从而减轻后续的工作。被比较的元素之间的距离逐渐减少,直到减少为1.
这个方法正面比较难以理解,它想出这个算法的思路是怎样的?但可以证明得出来的元素排列是有序的。
void shell(int* v, int n) { int gap,i,j,temp; for(gap = n/2; gap>0; gap/=2) for(i = gap; i<n; ++i) for(j = i-gap; j>=0&&v[j]>v[j+gap]; j-=gap) { temp = v[j]; v[j] = v[j+gap]; v[j+gap] = temp; } }
注意第三个for循环,它保证了{ v[0],v[gap],v[2*gap]…,v[j] }这个序列是递增的。想了半天,当间隔为1时,不就可以排序完成了吗?那还要前面第一个for循环干嘛?后来查了一下,间隔为1进行排序就是插入排序法,此方法的时间复杂度为O(n^2),和冒泡排序时间复杂度一样。shell排序的时间复杂度区间是[n*log2n, n^2]. 不稳定。shell排序的优点在于,远距离的元素之间的交换提高了效率。因为排序算法的步骤可分为两部分,判断的次数、交换元素位置的次数。显然shell排序的判断次数增加了,但交换元素位置的次数少了,而交换元素位置有三个步骤。
用shell排序、插入排序、快速排序对10W个随机数排序。结果分别为5.749s, 31.355s,6.729s
相关文章推荐
- 动易2006序列号破解算法公布
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#实现的算24点游戏算法实例分析
- c语言实现的带通配符匹配算法
- 浅析STL中的常用算法
- 算法之排列算法与组合算法详解
- C++实现一维向量旋转算法
- Ruby实现的合并排序算法
- C#折半插入排序算法实现方法
- 基于C++实现的各种内部排序算法汇总
- C++线性时间的排序算法分析
- C++实现汉诺塔算法经典实例
- PHP实现克鲁斯卡尔算法实例解析
- C#获取关键字附近文字算法实例