各种排序对比:
注:
- 时间复杂度:排序的时间复杂度,由于排序受本身数据的影响,比如说在些全部混乱,而一些数据或者数据中一部分值有序。因此可能出现最好情况和最差情况,一般来说用平均情况来衡量时间复杂度。
- 稳定性:对于出现相同值的情况下,有没有改变其顺序比如说 {3、4、1、1、8};排序后的结果可能是{1(第一个)、1(第二个)、3、4、8},{1(第二个)、1(第一个)、3、4、8};如果保存稳定的话则不变,如果不稳定的话则有可能改变。
- 空间复杂度(Space Complexity)是对一个算法在运行过程中临时占用存储空间大小的量度,记做S(n)=O(f(n))。比如直接插入排序的时间复杂度是O(n^2),空间复杂度是O(1) 。而一般的递归算法就要有O(n)的空间复杂度了,因为每次递归都要存储返回信息。一个算法的优劣主要从算法的执行时间和所需要占用的存储空间两个方面衡量。
1、冒泡排序
冒泡排序:在对数列进行排序时,比较大的值经过每轮的排序都会慢慢“浮”上来,就像冒的泡泡一样。
冒泡排序运行起来是比较慢的,但在排序算法中是比较简单的,冒泡排序遵循的规则是:比较相邻的两个数值。
对于冒泡排序的时间复杂度可以简单这样猜疑:一个循环嵌套另一个循环,对于外层循环执行了n次,内层循环也执行了n次,这就意味着大约执行n*n次的操作,也就是冒泡排序的平均时间复杂度的O(n^2);
代码如下:
public class SortDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
int a[] = { 7, 2, 300, 9, 3, 0, 6 };
// 外层循环遍历数组,为数组长度-1(相当于从数组中取出一个元素和其他)
for (int i = 1; i < a.length; i++) {
System.out.println("第" + i + "轮的排序结果:");
// 内层循环对数组中的值判读,进行交换;如果大的往后移;
for (int j = 0; j < a.length - i; j++) {
if (a[j] > a[j + 1]) {
int temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
// 对每循环一轮结果进行打印;
for (int n = 0; n < a.length; n++) {
System.out.print(a[n] + " ");
}
System.out.println();
}
}
}
运行结果:
2、选择排序
选择排序改进了冒泡排序,虽然把交换实数减小到n,但比较的次数仍然为n*n。
选择排序就是把数据中所有的元素扫描一趟,然后把这组中的最小的值放到最左边的位置上。选择排序的核心就是选出最小的值。
代码如下:
public class SelectDemo {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int a[] = { 4, 8, 90, 2, 500 };
// 在外层循环中,控制每一轮循环;
for (int i = 0; i < a.length - 1; i++) {
int min = i;
System.out.println("第" + (i+1) + "轮循环:");
// 在内层循环中比较值大小,找出最小值,并记录基数组的下标;
for (int j = i + 1; j < a.length; j++) {
if (a[min] > a[j]) {
min = j;
}
}
// 如果不是最小值,则把这个交换到这个位置上;
if (i != min) {
int temp = a[min];
a[min] = a[i];
a[i] = temp;
}
for (int n = 0; n < a.length; n++) {
System.out.print(" " + a[n]);
}
System.out.println();
}
}
}
3、插入排序
插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为O(n^2)。是稳定的排序方法。
插入排序如下图所示:
代码如下:
public static void main(String[] args) {
int j, insert;
int a[] = { 7, 4, 6, 20, 100, 1, 0 };
for (int i = 1; i < a.length; i++) {
// 记录可能要插入的值;
insert = a[i];
// j初始化的值为数组的下标;
j = i - 1;
//当j大于等于0时,并且数组元素中的值大于插入时,继续循环,直到找到比比当前值小的;
while (j >= 0 && insert < a[j]) {
a[j + 1] = a[j];
j--;
}
//找到当前数组中元素比插入值小,则把它赋值给下一个元素;
a[j + 1] = insert;
for (int n = 0; n < a.length; n++) {
System.out.print(" " + a[n]);
}
System.out.println();
}
}
}
运行:
java数据结构和算法(第二版)对几种排序之间的总结与比较:
- 一般情况下几乎用不到冒泡排序算法。它过于简单了,以至于可以毫不费力的写出来。然而当数据量很小的时候它会有些应用的价值。
- 选择排序虽然把交换次数降低,但比较的次数仍然很大,当数据量很小,并且交换数据相对于比较数据更加耗时的情况下,可以应用选择排序。
- 在大多数民情况下,假设数据量比较小或者基本有序时,插入排序算法是三种简单排序算法中最好的选择。