这里我来集中分析一下七大排序算法的性能问题。如果不当之处,敬请指正。
冒泡排序(Bubble)
排序算法 | 平均情况下 | 最好情况 | 最坏情况 | 稳定性 | 空间复杂度 |
---|---|---|---|---|---|
冒泡 | O( n2 ) | O(n) | O( n2 ) | 稳定 | 1 |
冒泡排序算法里面含有2层循环,显然最坏时间复杂度为O( n2 ),这里可能很多人不懂平均情况下的复杂度是什么意思,下面引用一段话:
- 而平均运行时间也就是从概率的角度看,这个数字在每一个位置的可能性是相同的,所以平均的查找时间为n/2次后发现这个目标元素。平均情况更能反映大多数情况下算法的表现。平均情况分析就是对所有输入尺寸为n的输入,让算法运转一遍,然后取它们的平均值。当然,实际中不可能将所有可能的输入都运行一遍,因此平均情况通常指的是一种数学期望值,而计算数学期望值则需要对输入的分布情况进行假设。
- 平均运行时间是所有情况中最有意义的,因为它是期望的运行时间。也就是说,我们运行一段程序代码时,是希望看到平均运行时间的。可现实中,平均运行时间很难通过分析得到,一般都是通过运行一定数量的实验数据后估算出来的。
那么为什么冒泡排序最好情况下的复杂度为O(n)呢?其实用我们最初的冒泡排序代码,其最好情况下复杂度依然为O( n2 )。如果冒泡排序算法在原来的基础上改进如下:
public static void b_getsort(int[] a)
{
int len = a.length;
int i,j;
boolean flag = true;
for(i=0;i<len-1&&flag;i++)
{
flag = false;
for(j = 0;j<len-1-i;j++)
{
if (a[j]>a[j+1])
{
int temp = a[j];
a[j] = a[j+1];
a[j+1] = a[j];
flag = true;
}
}
}
}
设置了一个flag变量用来标示我们操作的那部分数据是否发生了数据交换。
比如说,在我们第一次‘冒’的时候,均未发生过交换(即原数组本身是有序的),那么flag就是为false,这也就意味着我们根本不必再进行第二次、第三次的‘冒泡’。其实这也就是最好的情况,即只进行了一次对数组所有元素的访问。
简单选择排序(Select Sort)
排序算法 | 平均情况下 | 最好情况 | 最坏情况 | 稳定性 | 空间复杂度 |
---|---|---|---|---|---|
简单选择 | O( n2 ) | O( n2 ) | O( n |