算法入门---java语言实现的选择排序小结

来源:互联网 发布:朱雀投资怎么样知乎 编辑:程序博客网 时间:2024/05/21 10:58
  1. public class SelectionSort {
  2. /**
  3. * 选择排序。 顾名思义:先选择再排序。 假如一个序列完全未排序其为A(0.....n)
  4. * 然后就从此序列中依次的选择然后排序。
  5. * 先找到最大(小)的数,放在第一个位置为已排序序列B(1)。然后从未排序的序列中
  6. * C(2....n)再找到最大的数放到已排序的序列的尾端。依次循环的进行. 算法的实现:
  7. * 双重for循环进行查找每一个i最起码比较n-i-1次,先找到最大(小)的数的索引,
  8. * 在这一波的寻找完毕后,再把最大的索引处的元素和i(外层循环)所在的位置进行交换。
  9. *
  10. * 此处以升序举例
  11. *
  12. * @param src
  13. */
  14. public static void sort(int[] src) {
  15. int len = src.length;
  16. for (int i = 0; i < len; i++) {
  17. int min = i;// 假设此时min就是最小的
  18. // 然后在第二层循环中找到未排序序列中最大(小的)
  19. for (int j = i + 1; j < len; j++) {
  20. //if (src[j] < src[i]) {必然出错,是一直拿到了最后一个比它小的
  21. // min = j;
  22. //}
  23. if (src[j] < src[min]) {//这样和min比较,比它小就,把下标拿过来,保证最后得到的最小。
  24. min = j;
  25. }
  26. }
  27. // 这一波查找完毕以后.
  28. // 不等于证明后面有比它小的找到了。
  29. if (min != i) {
  30. int temp = src[min];
  31. src[min] = src[i];
  32. src[i] = temp;
  33. }
  34. }
  35. }
  36. public static void main(String[] args) {
  37. int[] src = {55,77,33,44,22,1,9,0,3,9,-34,9999,-66};
  38. sort(src);
  39. for(int i : src){
  40. System.out.print(i);
  41. System.out.print(" ");
  42. }
  43. }
  44. }
          选择排序的交换操作介于 0 和 (n - 1) 次之间。选择排序的比较操作为 n (n - 1) / 2 次之间。选择排序的赋值操作介
于 0 和 3 (n - 1) 次之间。比较次数O(n^2),比较次数与关键字的初始状态无关,总的比较次数N=(n-1)+(n-2)+...+1=n*
(n-1)/2。交换次数O(n),最好情况是已经有序,交换0次;最坏情况交换n-1次,逆序交换n/2次。交换次数比冒泡排序
少多了,由于交换所需CPU时间比比较所需的CPU时间多n值较小时,选择排序比冒泡排序快。

时间复杂度:(就找对N影响最大的那一项表达式就行,去除系数)1/2*n^2+n/n = n^2.
      平均n^2、最差n^2. n数比较小时较好。
       n^2的时间复杂度就是一个二次函数,倒置的抛物线,找个差不多的图如下:
 
     n^2:意味着什么那?就是比如排序十个数需要时间t = a;那么排序100个数理论上需要的时间是t = a*100.排序1000个数
              需要的时间t = a*100*100; 也就是说是增加的个数的平方 ,增加个数增加10倍,时间将增加10^2倍。
     下面简单的测试了几组数据。(没有使用特别少的数据,因为特别少的数据参考性不大)
      个人在电脑上进行了测试数据:
  1. 10000
  2. name: 选择排序1 花费了 = 56ms
  3. name: 选择排序2 花费了 = 47ms
  4. name: 选择排序3 花费了 = 31ms
  5. name: 选择排序4 花费了 = 47ms
  6. name: 选择排序5 花费了 = 31ms
  7. 平均大概是36
  8. 50000
  9. name: 选择排序1 花费了 = 999ms
  10. name: 选择排序2 花费了 = 1000ms
  11. name: 选择排序3 花费了 = 861ms
  12. name: 选择排序4 花费了 = 861ms
  13. name: 选择排序5 花费了 = 891ms
  14. 平均 922
  15. 100000
  16. name: 选择排序1 花费了 = 3993ms
  17. name: 选择排序2 花费了 = 3965ms
  18. name: 选择排序3 花费了 = 3464ms
  19. name: 选择排序4 花费了 = 3527ms
  20. name: 选择排序5 花费了 = 3635ms
  21. 平均:3716

          我们可以看到10000到50000之间,个数增长了5倍,那么对应它的时间复杂度n^2,它的时间应该增加了25倍。对应到
各自的平均是还是比较可靠的,并且选择排序数较少的情况下性能还比较好,所以36*5 = 900 < 922 也比较符合预期。而
50000到100000个数增加了2倍,时间应该增加4倍。922*4 = 3688 < 3716。

稳定性:不稳定。
        当一个元素比需要换位置的元素小,而这个小的元素又在两个相同元素的后面哪一个元素的后面如:
        随便举一个例子:  7 8 9 10 11 7 6 4. 这样当7 和6换了位置以后 序列就变的不稳定了。就是说前面有两个
    


0 0
原创粉丝点击