冒泡、选择排序

冒泡排序:

public static int[] testBubble(int[] arr) {
  int temp = 0;
  boolean flag = true;// 优化,如果数组本身是有序的,如{1,2,3....},可以省略后面不需要的比较
  for (int i = 0; i < arr.length && flag; i++) {
    flag = false;
    for (int j = arr.length - 1; j > i; j--) {
      if (arr[j - 1] > arr[j]) {
        temp = arr[j - 1];
        arr[j - 1] = arr[j];
        arr[j] = temp;
        flag = true;//出现数据移动,设为true,保证下一次循环的执行
      }
    }
  }
  return arr;
}

时间复杂度:

如果待排序的表本身就是有序的,那么整个程序只有刚开始的n-1次的比较,没有数据的交换,时间复杂度为O(n)

如果是逆序,比较次数为1+2+3+....+n-1= n*(n-1)/2次,并且做等量级的数据交换,时间复杂度为O(n2)

 

简单选择排序:

public static int[] testSelect(int[] arr) {
  int min = 0;
  int temp = 0;

  for (int i =0; i < arr.length; i ++) {
    min = i;//假定此时的i下标对应值为最小值
    for (int j = i +1; j < arr.length; j ++) {
      if (arr[min] > arr[j]) {
        min = j;//更新最小值下标,不交换数据,j继续循环
      }
    }

    //j循环一遍完成后再判断是否交换数据
    if (min != i) {
      temp = arr[min];
      arr[min] = arr[i];
      arr[i] = temp;
    }
  }
  return arr;
}

简单选择排序 并不是像冒泡那样,遇到小的就交换
而是遇到小的就记录其下标,这样循环比较一遍,记录的下标就是此循环范围内最小值的下标
再执行交换操作,这样可减少数据的交换次数

时间复杂度:

无论原始数组是最好的有序还是逆序,这种排序方式的比较次数都是1+2+3+.....+n-1 = n*(n-1)/2次

有序时数据交换0次,逆序时交换n-1次

所以选择排序时间复杂度也是O(n2), 但一般来说,性能上还是要优于冒泡排序

 

直接插入排序:

public static int[] testInsert(int[] arr) {
  int temp = 0;
  int i, j;
  for (i = 1; i < arr.length; i++) {
    if (arr[i - 1] > arr[i]) {
      temp = arr[i];
      //把当前索引i前所有大于当前值的数据,依次后移
      for (j = i - 1; j >= 0 && arr[j] > temp; j--) {
        arr[j + 1] = arr[j];
      }
      arr[j + 1] = temp;//for循环结束时j--,故+1
    }
  }
  
  return arr;
}

 时间复杂度:

待排序数组有序,执行n-1次比较,0次数据交换,时间复杂度为O(n)

逆序,执行2+3+....+n=(n+2)*(n-1)/2次比较,数据移动次数:2+3+...+n=(n+2)*(n-1)/2次

根据概率相等的原则,待排序数组是随机的,所以平均的移动和比较次数均为n2/4

因此时间复杂度为O(n2),一般来说,其性能要比简单选择排序和冒泡要好一些

 

关于执行的性能,不同算法自己的适用场景,如直接插入排序更适合在记录数较少,且记录基本有序的情况下使用,具体使用还是要看具体场景!

posted @ 2012-01-12 11:18  当年明月  阅读(278)  评论(0编辑  收藏  举报