1.选择排序法A
private static void sortNum(int[] s) { for (int i=0; i<s.length; i++) { for (int j=i+1; j<s.length; j++) { int temp; if (s[i]<s[j]) { temp = s[i]; s[i] = s[j]; s[j] = temp; } } } }
分析:上面的代码实现一个数组中的各个元素从大到小排列,简单的来讲它的原理是这样的,先拿数组中的第一个元素s[0]与后面的每个元素作比较,如果s[0]的值小于它后面的元素那么则s[0]则与这个值交换值,否则不做交换,s[0]的值将会保持不变。例如数组中的元素s[0] ,s[1],s[2],s[3],s[4],s[5]的值依次为5 2 1 7 96 ,首先用s[0]的值5与后面的值相比,当遇到比5大的值时,s[0]的值就变为这个比较大的值。s[0]与s[1]比较,显然5 >2,则不做交换,s[0]仍然为5,再用s[0]与s[2]做比较,5 >1仍然不做交换,s[0]还是等于5。s[0]与s[3]做比较,5 <7 所以s[0] 和s[3]做交换,此时s[0] =7,s[3] = 5。仍然继续用s[0]与s[4]作比较,7 < 9 所以s[0]与s[4]做交换,此时s[0]=9,s[4]= 7,最后用s[0]与s[5]作比较,9 > 6,不做交换,所以最终s[0]为第一轮比较之后的最大值为9,经过第一轮比较厚的结果为 9 2 1 5 7 6。然后开始第二轮比较,用s[1]与他后面的值做相同方式的比较,最终s[1]将得到第二轮比较后的最大值为7,第二轮比较后的结果为9 7 1 2 5 6,依次类推,将会最终得到s[0],s[1],s[2],s[3],s[4],s[5]的值按降序排列。
但是当我仔细观察循环过程,可以发现,每循环依次就要为临时变量temp分配一块内存空间,这样的比较方式无疑是一种浪费内存效率极低的方式,那么我们就来改造一下这个算法。
2.排序算法B
private static void sortNum(int[] s) { int k; int temp; for (int i=0; i<s.length; i++) { k = i; for (int j=k+1; j<s.length; j++) { if (s[k]<s[j]) { k = j; } } if (k != i) { temp = s[k]; s[k] = s [i]; s[i] = temp; } } }
经过改造,上面的代码好在哪里呢?仔细观察一下,两个变量的作用域扩大了放在了for循环的外面,作用域的扩大带来的好处是我们不必再每次循环的时候都新开辟一块内存空间存放temp变量和k变量,只需在循环的时候改变这块空间里的值就可以了。其原理跟上面的类似,不同之处在于它打了一个标记,起初让k=i,然后经过I循环来决定是否对K赋新值,经过一次循环后来判断k是否等于眼来的i的值,如果等于说明s[k]与他后面的值比较时未遇到比s[k]大的值,所以s[k]本来就是本次循环中的最大值。反之说明s[k]遇到了比s[k]大的值,然后让s[k]和这个值交换,最终s[k]仍然为本次循环中的最大值。
3.冒泡排序法
private static void sortNum(int[] s) { for (int i=s.length-1; i>=1; i--) { for (int j=0; j<=i-1; j++) { if (s[j]>s[j+1]) { int temp; temp = s[j]; s[j] = s[j+1]; s[j+1] = temp; } } } }
冒泡排序法的原理也比较简单,仍然用上面中的s数组来说明5 2 1 7 9 6。它是这样子的,首先s[0]与s[1]比较,显然5 > 2那么两者交换,s[0]=2,s[1]=5。然后s[1]与s[2]比较,5 > 1,所以s[1]=1,s[2]=5。然后s[2]和s[3]比较 5< 7,二者不交换。s[3]和s[4]比较,7<9,二者不交换。最后s[4]和s[5]比较,9>6,二者交换后s[4]=6,s[5]=9。所以经过第一轮循环后的顺序为2 5 1 7 6 9。然后开始第二轮比较,从s[0]与s[1]开始最后一次比较为s[3]与s[4]比较,直到把每次循环中的最大数取出并按升序排列。
排序算法多种多样,但效率各有不同,更多排序算法请点击我。