当前位置:   article > 正文

复杂度与冒泡排序、二分查找_二分排序和冒泡排序 时间副再度

二分排序和冒泡排序 时间副再度
  1. 总结:
  2. 时间复杂度:衡量算法快慢的标准刻度
  3. 在CPU单位时间运行指令数恒定的情况下,求算法运行指令数和数据规模n的关系 F(n)
  4. 不求甚解
  5. 大O渐进法:
  6. 1)只保留最高次项
  7. 2)最高次项的系数化为1
  8. 时间复杂度不是绝对意义上的快慢,运行时间的变化趋势。
  9. 常见的时间复杂度:
  10. O(1) O(log(n)) O(n) O(n*log(n)) O(n^2)
  11. 特殊的时间复杂度:
  12. 二分查找
  13. 递归函数--画框框、数框框 了解
  14. 空间复杂度
  15. 大O渐进表示法
  16. 数据规模是n的情况下,
  17. 1)额外使用的空间大小(不考虑输入/输出中用到的空间)
  18. 2)常见形式
  19. i. int[] array=new int[和n的关系];
  20. int[] array=new int[255]; S(n)=O(n)
  21. ii.递归函数 调用栈

一、数据结构与算法

数据结构:存储、组织数据的形式。
算法:一系列步骤。

二、复杂度

1.含义

是衡量算法好坏的刻度尺(标杆)
2.衡量的角度:

          快/慢--时间复杂度    ****
          使用空间的角度(内存)--空间复杂度
如:快慢:冒泡排序  其它排序  
3.拿运行时间衡量怎么样?

不好  原因:1)事后衡量  2)影响因素太多(如当时系统上打开程序的多少)

4.衡量算法快慢的标准

是算法运行的指令个数(基本指令)。这里有个前提,即:CPU每秒运行的指令数是恒定的。

5.大O渐进法

数据规模  n
for(int i=0;i<n;i++){}
运行指令个数F(n) 和数据规模n有关。n越大,F(n)越大。

衡量算法好坏,不需要精确衡量。-->大O渐进表示法
O(F(n))=
1)只保留最高次项
2)最高次项的系数变为1

  1. //在array数组中查找value
  2. int search(int[] array,int value){
  3. for(int i=0;i<array.length;i++){
  4. if(array[i]==value){
  5. return i;
  6. }
  7. }
  8. return -1;//没有找到
  9. }
  10. 3 5 2 7 9 6 4
  11. 最好 平均 最坏
  12. 用平均/最坏来衡量

6.两个例子

  1. 1
  2. void count(int m,int n){
  3. int count=0;
  4. for(int i=0;i<m;i++){
  5. count++;
  6. }
  7. for(int i=0;i<n;i++){
  8. count++;
  9. }
  10. System.out.println(count);
  11. }
  12. O(n)=O(m+n)
  13. 2
  14. int String.indexOf(int ch);
  15. 数据规模:String的长度 O(n)

7.常见的时间复杂度
O(1)
O(log(n))
O(n)
O(n*log(n))
O(n^2)

8.递归函数的时间复杂度

做法:画框框,找框框的个数

  1. 1:n的阶乘
  2. long Factorial(int n){
  3. return n>2?Factorial(n-1)*n:n;
  4. }
  5. 这个递归函数有两个出口:
  6. 1)n=1或n=2-->返回12
  7. 2)n>2-->求(n-1)! 递归n次。
  8. 因此,T(n)=O(n)
  1. 2 斐波那契数列
  2. long Fabonacci(int N){
  3. return N<2?N:Fabonacci(N-1)+Fabonacci(N-2);
  4. }
  5. 两个出口:
  6. 1)N=1-->返回1
  7. 2)N>=2-->求Fabonacci(N-1)+Fabonacci(N-2)

举例说明:

三、冒泡排序和二分查找的时间复杂度

1.冒泡排序(升序)

冒泡过程:两个相邻的数依次比较,保证大的数在后面。
减治算法:每次处理都减少一个数,剩下的数用同样的方式处理。冒泡的过程就相当于减治算法。

外部循环表示比较的轮数,共比较array.length次。更优化的方式是array.length-1。

  1. //冒泡排序
  2. public static void bubbleSort(int[] array) {
  3. for (int i = 0; i < array.length; i++) {
  4. for (int j = 0; j < array.length - 1 - i; j++) {
  5. //保证相邻的两个数,最大的在后面。
  6. if (array[j] > array[j + 1]) {
  7. int temp = array[j];
  8. array[j + 1] = array[j];
  9. array[j] = temp;
  10. }
  11. }
  12. }
  13. }

时间复杂度:F(n)=(n-1)+(n-2)+....+1=(n-1+1)(n-1)/2=(n^2-n)/2,因此冒泡排序的时间复杂度为O(n)=n^2。

冒泡排序的优化

每次冒泡之前,假设数组已经有序。如:2 3 4 5 6 7 9。可以在每轮排序前设置标志位假设已经是有序的,经过一轮排序后,如果标志位未发生变化,则说明整个数组是有序的,就不必进行后面的排序了。

  1. for(int i=0;i<array.length;i++){
  2. //每次冒泡之前,假设数组已经有序。
  3. int sorted=true;
  4. //一次冒泡的过程,保证最大的数被推到最后。
  5. for(int j=0;j<array.length-1-i;j++){
  6. //保证相邻的两个数,最大的在后面。
  7. if(arr[j]>arr[j+1]){
  8. int temp=arr[j];
  9. arr[j+1]=arr[j];
  10. arr[j]=temp;
  11. sorted=false;
  12. }
  13. }
  14. //如果过程一次交换都没有发生过,假设有序成立。
  15. if(sorted==true){
  16. break;
  17. }
  18. }

2、二分查找

前提:数组有序     

查找方式:两种方式:[left,right)  [left,right](其中, left=区间的左边界   right=区间的右边界)

中间位置的下标:int m=(left+right)/2
[left,right)  区间内只有一个数:right=left+1  没有数 left==right

  1. //二分查找
  2. [left,right]
  3. public static int binarySearch1(int[] array, int value) {
  4. int left = 0;
  5. int right = array.length - 1;//5 []
  6. while (left <= right) {
  7. int mid = left + (right - left) / 2;
  8. if (array[mid] == value) {
  9. return mid;
  10. }
  11. //说明value在(mid,right],那么left=mid+1
  12. if (array[mid] < value) {
  13. left = mid + 1;
  14. }
  15. //说明value在[left,mid),那么right=mid-1
  16. if (array[mid] > value) {
  17. right = mid-1;
  18. }
  19. }
  20. return -1;
  21. }
  22. //[left,right)
  23. public static int binarySearch2(int[] array,int value){
  24. int left=0;
  25. int right=array.length;
  26. //区间内还有一个数,就继续找,没有数就可以停下。
  27. while(left<right){
  28. int m=left+(right-left)/2;
  29. if(value==array[m]){
  30. return m;
  31. }
  32. if(value>array[m]){
  33. left=m+1;
  34. }
  35. if(value<array[m]){
  36. right=m;
  37. }
  38. }
  39. return -1;
  40. }

二分查找的时间复杂度:
长度变化:n  n/2  n/4  ..... 1
1*2*2*2*...*2=n  ->2^a=n-->a=log(n)
二分查找的时间复杂度T(n)=O(log(n))

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/632296
推荐阅读
相关标签
  

闽ICP备14008679号