关于冒泡排序

            闲来无事自己写的冒泡排序,感觉几分钟就可以写完的,结果不熟练Java用法花了半个多小时,最开始写的:

     package testjson;


import org.junit.Test;


public class maopao {
private int i;
private int j;
@Test
public void mp() {
int temp;
int[] score = {11,8,0,4, 2, 6, 3, 7, 1,33,22,24,14,16,15 };


for(int str1 : score){
   System.out.print(str1+",");
   }
for (i = 0; i < score.length; i++) {
for(j = 0; j < score.length-1 ; j++){   

if(score[j]<score[j+1]){   
temp = score[j];
score[j] = score[j+1];
score[j+1] = temp;
//System.out.println(j);

}
}
}
System.out.println("排序完成后的结果:");
for(i=0;i<score.length;i++){
   System.out.print(score[i]+",");
   }


}


}


结果是对的;但是感觉有点太简单了,于是改成下边的:

package testjson;


import org.junit.Test;


public class maopao {
private int i;
private int j;
@Test
public void mp() {
int temp;
int[] score = {11,8,0,4, 2, 6, 3, 7, 1,33,22,24,14,16,15 };


for(int str1 : score){
   System.out.print(str1+",");
   }
for (i = 0; i < score.length-1; i++) {
for(j = i+1; j < score.length ; j++){   //这是小梅帮忙改进之后 ,我之前写的那个是i=0;循环,j=0,再全体循环是效率最差的

if(score[j]<score[i]){   
temp = score[j];
score[j] = score[i];
score[i] = temp;
//System.out.println(j);

}
}
}
System.out.println("排序完成后的结果:");
for(i=0;i<score.length;i++){
   System.out.print(score[i]+",");
   }


}


}

立马感觉效率提高了不少,时间复杂度好像提高了,BUT,这个算法并不是冒泡排序,而是直接选择排序,它们的时间复杂度一样都是O(n^2)

以下是百度找出来的内容对理解很有帮助:

1,简单排序和直接选择排序的区别:

     冒泡是从第一个数开始,往下每两个数进行比较,如果后面闭前面小,就调换位置,这样一趟下来就将最大的放到最后,如排序:8 5 2 7 第一趟结果:5 2 7 8(注意没相邻的两个数都有进行比较,符合后面比前面小的都有交换) 选择排序是将第一个数和后面的每个数进行比较,如果后面的比前面小,就两个数调换位置,最后就将最小的数放在最前面 如排序:8 5 2 7 第一趟结果 2 5 8 7(注意,它是后面的每个数和第一个数比较

2,时间复杂度的求法:

对于这些算法
(1)   for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
s++;

(2)   for(i=1;i<=n;i++)
for(j=i;j<=n;j++)
s++;

(3)   for(i=1;i<=n;i++)
for(j=1;j<=i;j++)
s++;

(4)   i=1;k=0;
while(i<=n-1){
k+=10*i;
i++;
}

(5)   for(i=1;i<=n;i++)
for(j=1;j<=i;j++)
for(k=1;k<=j;k++)
x=x+1;

对应的时间复杂度为:

1.时间复杂度O(n^2)
2.时间复杂度O(n^2)
3.时间复杂度O(n^2)
4.时间复杂度O(n)
5.时间复杂度O(n^3)

一般来说,时间复杂度是总运算次数表达式中受n的变化影响最大的那一项(不含系数)
比如:一般总运算次数表达式类似于这样:
a*2^n+b*n^3+c*n^2+d*n*lg(n)+e*n+f
a<>0时,时间复杂度就是O(2^n);
a=0,b<>0 =>O(n^3);
a,b=0,c<>0 =>O(n^2)依此类推

那么,总运算次数又是如何计算出的呢?
一般来说,我们经常使用for循环,就像刚才五个题,我们就以它们为例
1.循环了n*n次,当然是O(n^2)
2.循环了(n+n-1+n-2+...+1)≈(n^2)/2,因为时间复杂度是不考虑系数的,所以也是O(n^2)
3.循环了(1+2+3+...+n)≈(n^2)/2,当然也是O(n^2)
4.循环了n-1≈n次,所以是O(n)
5.循环了(1^2+2^2+3^2+...+n^2)=n(n+1)(2n+1)/6(这个公式要记住哦)≈(n^3)/3,不考虑系数,自然是O(n^3)
另外,在时间复杂度中,log(2,n)(以2为底)与lg(n)(以10为底)是等价的,因为对数换底公式:
log(a,b)=log(c,b)/log(c,a)
所以,log(2,n)=log(2,10)*lg(n),忽略掉系数,二者当然是等价的

看到这应该就彻底明白了

下边来个辅助资料,也是百度来的

时间复杂度
时间频度
一个算法执行所耗费的时间,从理论上是不能算出来的,必须上机运行测试才能知道。但我们不可能也没有必要对每个算法都上机测试,只需知道哪个算法花费的时间多,哪个算法花费的时间少就可以了。并且一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法中语句执行次数多,它花费时间就多。一个算法中的语句执行次数称为语句频度或时间频度。记为T(n)。

计算方法
1. 一般情况下,算法的基本操作重复执行的次数是模块n的某一个函数f(n),因此,算法的时间复杂度记做:T(n)=O(f(n))
分析:随着模块n的增大,算法执行的时间的增长率和f(n)的增长率成正比,所以f(n)越小,算法的时间复杂度越低,算法的效率越高。
2. 在计算时间复杂度的时候,先找出算法的基本操作,然后根据相应的各语句确定它的执行次数,再找出T(n)的同数量级(它的同数量级有以下:1,Log2n ,n ,nLog2n ,n的平方,n的三次方,2的n次方,n!),找出后,f(n)=该数量级,若T(n)/f(n)求极限可得到一常数c,则时间复杂度T(n)=O(f(n))

例:算法:
for(i=1;i<=n;++i)
{
for(j=1;j<=n;++j)
{
c[ i ][ j ]=0; //该步骤属于基本操作 ,执行次数:n的平方 次
for(k=1;k<=n;++k)
c[ i ][ j ]+=a[ i ][ k ]*b[ k ][ j ]; //该步骤属于基本操作 ,执行次数:n的三次方 次
}
}
则有 T(n)= n的平方+n的三次方,根据上面括号里的同数量级,我们可以确定 n的三次方 为T(n)的同数量级
则有f(n)= n的三次方,然后根据T(n)/f(n)求极限可得到常数c
则该算法的 时间复杂度:T(n)=O(n^3) 注:n^3即是n的3次方。
3.在pascal中比较容易理解,容易计算的方法是:看看有几重for循环,只有一重则时间复杂度为O(n),二重则为O(n^2),依此类推,如果有二分则为O(logn),二分例如快速幂、二分查找,如果一个for循环套一个二分,那么时间复杂度则为O(nlogn)。

分类
按数量级递增排列,常见的时间复杂度有:
常数阶O(1),对数阶O(log2n),线性阶O(n),
线性对数阶O(nlog2n),平方阶O(n^2),立方阶O(n^3),...,
k次方阶O(n^k), 指数阶O(2^n) 。随着问题规模n的不断增大,上述时间复杂度不断增大,算法的执行效率越低
 
 



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值