您的位置:首页 > 其它

常见排序算法

2015-11-14 21:59 204 查看
1.qsort 快速排序算法

采用递归的方法。对于一个给定的数组,任取一个元素为界将其余元素划分为两个子集,一个子集中所有元素都小于该元素,另一个子集中的所有元素都大于或等于该元素。对这样两个子集递归执行这一过程,当某个子集中的元素个数小于或等于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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法