交换排序又分为冒泡排序和快速排序,首先我们来了解一下冒泡排序。
1.1 冒泡排序
冒泡排序我们在c语言里已经学过一遍了,我们在回顾一下,无非就是依次把最大的数冒到最后边
我们先来看一下单趟排序的代码
for(i=1;i<n;i++)
{
if(a[i-1] > a[i])
Swap(&a[i-1],&a[i]);
}
这样就完成了第一趟排序,把最大的数冒到了最后面
for(j=0;j<n;j++)
{
int flag = 0;
for(i=1;i<n-j;i++)
{
if(a[i-1] > a[i])
{
Swap(&a[i-1],a[i]);
flag = 1;
}
}
if(flag == 0)
break;
}
ok,这就是完整的冒泡排序算法,第一趟排序先把最大的数冒到数组n-1的位置,第二趟排序冒到n-2的位置,一直到最后一趟只剩一个元素的时候不再进行下次循环,这里我们对冒泡排序进行了优化,如果某趟排序里没有发生交换,就说明这段数据已经有序了,就直接退出循环不再进行下次排序
冒泡排序的算法是比较劣质的,我们在实践中一般用不上,但是它的算法是很具有教学意义的,值得我们学习一下。
1.2 快速排序
给这么一组数据,我们快速排序的思路是令第一个数据为关键数key,根据这个数在右边找到比key小的数,在左边找到比key大的数进行交换,直到找数的指针相遇
由于相遇的位置一定比key小(这里后面会讲为什么),所以这时候我们把相遇的数与key所在的位置再交换一下,我们令keyi为相遇的数的位置,这样keyi左边的数都比key小,右边的数都比右边大了。接下来我们继续递归操作继续排[left,keyi-1]和[keyi+1,right],就和二叉树的递归一样,很相似。
直到递归结束,最后排序完成。
void QuickSort(int*a, int left,int right)
{
if(left>=right)
return;
int begin = left;
int end = right;
int keyi = left;
while(begin > end)
{
//右边找小
while(begin < end && a[end] >= a[keyi])
{
end--;
}
while(begin < end && a[begin] <= a[keyi])
{
begin++;
}
Swap(&a[begin],&a[end]);
}
Swap(&a[keyi],&a[begin]);
kei = begin;
QuickSort(a,left,keyi-1);
QuickSort(a,keyi+1,right);+
}
}