交换排序的核心思想是:根据序列中两条记录键值的比较结果,判断是否需要交换记录在排序中的位置。其特点是将键值较大(或较小)的记录向序列的前端移动,将键值较小(或较大)的记录向序列的后端移动。
基本排序算法实现:
void Sort (int arr[],int n) { int i,j; int k; for(i=0;i<n-1;i++) //n-1轮循环 { for(j=i+1;j<n;j++) { if(arr[i]<arr[j]) //比较判断 { swap(&arr[i],&arr[j]); //位置交换 } } } }
冒泡排序
冒泡排序的基本原则是:比较两两相邻的记录的关键字,使不满足序列要求的记录交换位置,直到n-1轮循环结束。冒泡排序算法是稳定的。
冒泡排序动图演示:
第一轮排序,注意观察,可以看到两两比较,小的往右移动,大的往左移动,第一轮排序结束可以看到“0”已排好序,已经排在了最右边的对应位置,后面几轮排序“0”也不再移动了。
第二轮可以看到又一次确定了“1”的位置,后面几轮排序,“1”也不会再移动了。
依此类推,第三轮把“2”放在对应的位置,“2”后面排序也不会再移动了。后面还有第四轮、第五轮直到第n-1轮就能排序结束。
排序完成效果:
快速排序
快速排序是对冒泡排序的改进,快速排序的基本思想是:通过一趟排序,将序列中的数据分割为两个部分,其中一部分的所有数值都比另一个部分的小;然后按照此种方法,对两部分数据分别进行快速排序,直到参与排序的两个部分都有序为止。
一开始需要设置一个参考值,(通常选用序列中第一个记录的键值作为参数),通过与参考值的比较来划分数据,把序列划分成上述的两个部分。快速排序是不稳定的排序算法。
举个升序的例子
第一层排序关键字(参考值)key=5,第一层快速排序过程如下:
首先把序列的头和尾位置看作“i”和“j”双方,双方好像下跳棋一样,“i”移动的依据i++直到所在位置的值大于key值就停止++,“j”移动的依据j--是所在位置的值小于key值就停止“j”--,当一方停止就更换对方来进行移动的操作,直到双方往中间位置移动到“i”=“j”就代表以本层key值划分的排序结束。
第一轮,“i”先操作,“i”位置的值5为参考值,所以先让参考值的位置视为空值,“i”结束操作,换“j”操作。
第二轮,“j”操作,“j”位置的值5去和key值5比较,相等无法移动;所以“j”往前移动一格,到值为7的位置(如下图),用值7去和key值5比较,发现7大于5,也无法移动;所以“j”往前再移动一格,到值为3的位置(如下图),用值3和key值5比较,发现3小于5,所以把值3移动到“i”空值的位置去(如下图),“j”成功移动就结束操作,换“i”操作。
第三轮,“i”操作,“i”前进一格到值为0的位置(如下图),用0和key值5去比较发现,0小于5,不移动;所以“i”前进一格,到值为9的位置(如下图),9和key值5比较,9大于5,所以把9移动到“j”空值的位置去(如下图),“i”成功移动结束操作,换“j”进行操作。
第四轮,“j”操作,“j”前进一格到值为6的位置(如下图),用6和key值去比较,6大于5,不移动;继续前进一格,到值为 4的位置(如下图),用4和key值去比较,4小于5,把4移动到“i”空值的位置去(如下图);“j”成功移动,换“i”操作。
第五轮,“i”操作,“i”前进一格,到值为8的位置(如下图),用8和key值5比较,8大于5,所以把8移动到“j”空值的位置(如下图),“i”结束操作,换“j”操作。
第六轮,“j”操作,“j”前进一格,到值为1的位置(如下图),用1和key值5去比较,1小于5,所以把1移动到“i”空值的位置去(如下图),“j”操作结束,换“i”操作。
第七轮,“i”操作,前进一格,发现“i”和“j”重合了(如下图),开始下跳棋之前,我们就规定了当i=j的时候代表本层排序结束。接下来把key值放到重合的位置,本层结束排序结果为(如下图)3041586975。
从上图可以很直观的看出来key值5的左边都是不大于5的数值,右边都是不小于5的值。成功的划分出来两个部分。
接下来两个部分内部通过递归调用进行排序,排序也是和上面的跳棋举例一样的方式,第一个位置的值设置为key值,“i”位置为空,“j”先操作,“i”依次交替操作,直到二者重合。每一层递归操作之后位置变动如下图。
二层排序如下图:
三层排序如下图,直接把三层排序过后产生的单个数字为一部分的4和9排除在外,不需要排序了:
四层排序如下图:
最终排序结果为:
如果对您有帮助的话,请留下小脚印再离开吧!