排序方法可以分为两种:内部排序 和 外部排序
内部排序的方法很多,常用的大致可以分为:
基本操作:
Java代码:
public class BuddleSort { public static int[] sort(int[] s){ for(int i = 0; i < s.length - 1; i++){//进行 n-1 趟排序 for (int j = 0; j < s.length - i - 1; j++) { if(s[j] > s[j + 1]){ int temp = s[j]; s[j] = s[j + 1]; s[j + 1] = temp; } } } return s; } }效率分析:
时间:按上述代码执行,即使是正序排列的数列,也要 n-1 趟排序,需要进行 n(n-1)/2 次比较,时间复杂度为O(n^2)。
然而当序列为正序时,冒泡排序如果能在内部循环第一次运行时,使用一个旗标来表示有无需要交换的可能,也可以把最好的复杂度降低到O(n)。
改进后的代码:
public class BuddleSort { public static int[] sort(int[] s){ boolean flag = true;// for(int i = 0; i < s.length - 1 && flag; i++){//判断的条件需要加上对旗标的判断 flag = false;//旗标先置为false,若下列交换不发生,证明已经排序好,则退出循环 for (int j = 0; j < s.length - i - 1; j++) { if(s[j] > s[j + 1]){ int temp = s[j]; s[j] = s[j + 1]; s[j + 1] = temp; flag= true; } } } return s; } }稳定性:true.因为每次只比较交换相邻两数据,当两数相等时不做调整,故为稳定的。
若在每次走访数列时,把走访顺序反过来,也可以稍微地改进效率。有时候称为鸡尾酒排序,因为算法会从数列的一端到另一端之间穿梭往返。
public class CocktailSort { public static int[] sort(int[] s) { int start = 0, end = s.length - 1; int i, temp; while (start < end) { flag = false; for (i = start; i < end; i++) { if (s[i] > s[i + 1]) { temp = s[i]; s[i] = s[i + 1]; s[i + 1] = temp; } } end--; for (i = end; i > start; i--) { if (s[i - 1] > s[i]) { temp = s[i]; s[i] = s[i - 1]; s[i - 1] = temp; } } start++; } return s; } }
以序列(2,3,4,5,1)为例,鸡尾酒排序只需要访问一次序列就可以完成排序,但如果使用冒泡排序则需要四次。但是在乱数序列的状态下,鸡尾酒排序与冒泡排序的效率都很差劲。
public class QuickSort { public static int[] sort(int[] s, int l, int h){ if (l < h) {//判断左右指针的关系,作为递归的出口 int low = l;//左指針 int high = h;//右指針 int pivotKey = s[l]; while(low < high){ while (low < high && s[high] > pivotKey) { high--; } if (low < high) { s[low++] = s[high]; } while (low < high && s[low] < pivotKey) { low++; } if (low < high) { s[high--] = s[low]; } } s[low] = pivotKey; sort(s, l, low - 1); sort(s, low + 1, h); } return s; } }效率分析: