关于排序的算法,大约分为两大类:顺序排序与对数排序。
         顺序排序一般使用一对嵌套的循环结构(多为两个for循环),因此排序n个元素需要大约n的2次方的比较。比较常用的顺序排序有(1)选择排序法 (2)插入排序法 (3)冒泡排序法
         对数排序一般需要大约n*log2n(2为底数)次比较。这两种排序,当n越大的时候,他们性能上的差别就越大。快速排序与归并排序都属于对数排序,同样是使用递归。



1)选择排序法

1. public class
2.   
3. // 选择排序
4. public static void
5. int
6.         Comparable temp;  
7. // 从第一个元素开始比较,找出最小那个,放在第一位
8. // 从第二个元素开始比较,找出最小那个,放在第二位
9. // 总共需要放N-1次
10. for (int index = 0; index < data.length - 1; index++) {  
11.             min = index;  
12. for (int scan = index + 1; scan < data.length; scan++) {  
13. if (data[scan].compareTo(data[min]) < 0) {  
14.                     min = scan;  
15.                 }  
16.             }  
17. //跳回到第一层循环的时候,才进行交换,把最小的数放在第一位...如此类推
18.             temp = data[min];  
19.             data[min] = data[index];  
20.             data[index] = temp;  
21.   
22.         }  
23.     }  
24. }


策略是:搜索整个数组,找到最小值。然后将这个值与第一个位置上的值交换。然后搜索除第一个值钱外的次小值,然后与第二个位置上的值进行交换。如此类推。这种算法最简单易明


2)插入排序

    1. // 插入排序
    2. public static void
    3. // 插入一个数,与前面的数比较,放到适当的位置,如此类推
    4. for (int index = 1; index < data.length; index++) {  
    5.         Comparable temp = data[index];  
    6.   
    7. int
    8.   
    9. while (position > 0 && data[position - 1].compareTo(temp) > 0) {  
    10.   
    11. 1];  
    12.             position--;  
    13.         }  
    14.         data[position] = temp;  
    15.     }  
    16. }

    插入排序相对于选择排序要复杂一些,策略是:每插入一个数,与前面的所有数进行比较, 然后把这个数放到适当的位置。比如:数组里只有3,插入6,3与6排序后,插入4,然后4就放到第2位,之后插入5,3与4位置不变,5放在第3位,6换 到第4位...插入的过程需要移动数组的其他值,为插入的元素腾出存储空间。


    3)冒泡算法


    1. public static void
    2.   
    3.     Comparable temp;  
    4.   
    5. for (int i = 0; i < data.length; i++) {  
    6. for (int j = 0; j < data.length - 1
    7. if (data[j].compareTo(data[j + 1]) > 0) {  
    8. 1];  
    9. 1] = data[j];  
    10.                 data[j] = temp;  
    11.             }  
    12.         }  
    13.     }  
    14. }



    冒泡算法大家应该最熟悉了...它的策略是:第一次对数组所有值进行比较,重复地比较相邻两个元素,比较后进行交换,把最大值移动到最后一个位置,然后再扫描除最后一位外的数组其他值,不断进行交换,把次大值移到倒数第2位,如此类推。每次比较都找出该次所有数中的最大值


    上面3种顺序排序实现都很相似,效率也接近
    现在看看如何使用递归实现排序
    4)快速排序

      1. public static void quickSort(Comparable[] data, int min, int
      2. int
      3.   
      4. if
      5.         mid = findPartition(data, min, max);  
      6. 1);  
      7. 1, max);  
      8.     }  
      9. }  
      10.   
      11. // quickSort的支撑方法
      12. private static int findPartition(Comparable[] data, int min, int
      13. int
      14. int
      15.     Comparable temp;  
      16.     Comparable partitionelement;  
      17.   
      18. // 以第一个元素为分割元素(不一定是data[min])
      19.     partitionelement = data[min];  
      20.   
      21.     left = min;  
      22.     right = max;  
      23.   
      24. while
      25.   
      26. // 从左边找到比partitionelement大的数就跳出循环
      27. while (data[left].compareTo(partitionelement) <= 0
      28.             left++;  
      29.         }  
      30.   
      31. // 从右边找到比partitionelement小的数就跳出循环
      32. while (data[right].compareTo(partitionelement) > 0) {  
      33.             right--;  
      34.         }  
      35.   
      36. // 交换左边比partitionelement大的与右边比partitionelement小的元素
      37. if
      38.             temp = data[left];  
      39.             data[left] = data[right];  
      40.             data[right] = temp;  
      41.         }  
      42.     }  
      43.   
      44. // 当left>=right的时候,交换分割元素与data[right]的位置(把分割元素放到去一个比较中间的位置)
      45.     temp = data[min];  
      46.     data[min] = data[right];  
      47.     data[right] = temp;  
      48.   
      49. return
      50. }



      策略:首先在数组中任意选择一个元素作为分割元素,上面的例子是选择第一个数。然后开 始分割数组,把比这个分割元素小的值都移到它的左边,比他大的都移到它的右边。然后递归调用这个方法,对左右两部分排序,类似地从左边选择一个分割元素, 把左边比它小的排在它的左边,比它大的排在它的有...然后到右边。直到只剩下一个元素时(即不能再分割时)完成排序。
      这种排序需要3个参数,第一个为对象数组,第2个是数组索引的起始位置,第3个是数组索引的结束位置。


      下面对这几种排序的实现和性能进行测试

        1. public static void
        2. long
        3.   
        4. new
        5.        
        6. new Integer[40000];  
        7.           
        8. for(int i=0;i<40000;i++){  
        9. 10);  
        10.         }  
        11.   
        12. // 插入排序
        13. // insertionSort(array);
        14.   
        15. // 选择排序
        16. // selectionSort(array);
        17.   
        18. // 冒泡排序
        19. // bubbleSort(array);
        20.   
        21. // 快速排序
        22. 0, 39999);  
        23.              
        24.            
        25.         System.out.println(Arrays.toString(array));  
        26.   
        27. long
        28.   
        29. "时间差:" + (end - start) + "毫秒");  
        30. }

        结论:
        对有4万个(1~9)随机数的数组进行排序,在我的机器上运行,使用递归的快速查询约1秒,插入查询用5秒左右,选择查询11秒+,冒泡算法要几乎14秒。当然要查询的对象越少,他们之间效率的差别就越小。在排序对象的数量不多时,用顺序查询会比较方便与直观。