赞
踩
目录
(1) 直接看N的幂,越小越快(当然)
但对于O(N^2)和O(N)来说,你也不能武断的就判断说后者比前者更好,因为你在表示时间复杂度的时候忽略了常数项,你只能说,当实验进程无限长的时候,后者比前者更好。
因此这个“好”的判断,是在数据样本足够大的时候给予的判断。
(2)对于相同时间复杂度O(N) 无法用理论预估的方式来判断谁好,给予超大的样本量让两个程序去跑,直接比较时间就可以了。
例:B的复杂度没有化简之前是1000N*(a操作)+500
而C是2000N*(b操作)+300
每种操作的固定时间差别导致了无法使用理论预估。
选择排序:O(N^2) 额外空间复杂度O(1)
冒泡(Bubble 同样的)
**额外空间复杂度
要完成自己设计流程 需要多少额外的空间
如果程序运行过程中,不需要额外的数据结构,只是使用了额外的几个变量。那么额外空间复杂度为O(1);
如果要申请一个和原数组大小一样的数组,那额外空间复杂度为O(n);
如果申请一个是原数组大小一半的数组,那额外空间复杂度为O(n)(因为系数是可以忽略的)
随堂:BubbleSort Code(反正我是没搞明白为什么内嵌的循环只需要n-1,回头再看看)
- #include <iostream>
- using namespace std;
- void Bubble(int n)
- {
- int temp;
- int *arr=new int [n];
- for(int i=0;i<n;i++)
- {
- cin>>arr[i];
- }
- for(int i=0;i<n;i++)
- {
- for(int j=0;j<n-1;j++)
- {
- if(arr[j]>arr[j+1])
- {
- temp=arr[j+1];
- arr[j+1]=arr[j];
- arr[j]=temp;}
- }
- }
- for(int i=0;i<n;i++)
- {cout<<arr[i]<<" ";}
- }
- int main()
- {
- int n;
- cin>>n;
- Bubble(n);
- return 0;
- }
随堂:SelectSort Code
- #include <iostream>
- using namespace std;
- void sort(int n)
- {
- int minIndex=0;
- int min=0;
- int *arr=new int[n];
- for(int i=0;i<n;i++)
- {
- cin>>arr[i];
- }
- for(int i=0;i<n;i++)
- {
- minIndex=i;
- min=arr[i];
- for(int j=i+1;j<n;j++)
- {
- if(arr[j]<min)
- {
- minIndex=j;
- min=arr[j];
- }
- }
- int temp=arr[i];
- arr[i]=min;
- arr[minIndex]=temp;
- }
-
- for(int i=0;i<n;i++)
- {
- cout<<arr[i]<<" ";
- }
- }
-
-
- int main()
- {
- int n;
- cin>>n;
- sort(n);
- return 0;
- }
说起来比较简单的一类排序
比如 2 3 5 2 3 9 1 0,依照顺序给每个数字标号0—i
考虑顺序为:从0开始,先看0-0上是否排好了,再看0-1号是否排好,再看0-2号是否排好。
实际编写代码的时候,基于前面所有数都已经排列好的情况,只需要考虑最末位的i号数字是否比前面大(小),令j=i-1,则每次比较j和j+1即可
时间复杂度 O(N^2)
插入排序的进行弹性很大,他可能是最坏的情况,每次都要比较到底,这种情况下的计算量为等差数列,显然时间复杂度为O(N^2)。
同时他也可能是最好的情况,每次都只需要看一下就发现根本不需要交换位置,这种情况下的时间复杂度就是O(N)。
那么我们取最坏的情况所以他的时间复杂度为O(N^2),但插入排序显然仍然在常数级别的排序上,比冒泡排序和选择排序优秀的多。
随堂:InsertSort Code
两个注意的地方(我写错的地方)
1、i=1。 i=0的情况必然正确无需讨论
2、j>=0而不是j-1>=0.
- #include <iostream>
- using namespace std;
- void InsertSort(int n)
- {
- int *arr=new int [n];
- for(int i=0;i<n;i++)
- {
- cin>>arr[i];
- }
- for(int i=1;i<n;i++)
- {
- for(int j=i-1;j>=0&&arr[j]>arr[j+1];j--)
- {
- int temp=0;
- temp=arr[j];
- arr[j]=arr[j+1];
- arr[j+1]=temp;
- }
- }
- for(int i=0;i<n;i++)
- {
- cout<<arr[i]<<" ";
- }
- }
- int main()
- {
- int n;
- cin>>n;
- InsertSort(n);
- return 0;
- }
(1)原理
很简单,一串数字里找一个数字,砍一半,去剩下的一半里找,继续砍一半,直至找到。
那么最差的情况就是全砍完,砍到最后只剩下你要找的那个数,你砍的次数就是你的操作量。
(2)时间复杂度 O(logN)
所以二分法的时间复杂度是log2N(比如说,32个数,2^5你就要砍5次,所以是log2 32)
写作O(logN),默认以2为底,若不是以2为底,则写成O(log n N)(n是那个底数)
(3)适用问题
1)在一个有序数组中,找某个数是否存在
2)在一个有序数组中,找>=某个数最左的位置或找<=某个数最右的位置
3)局部最小值问题
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。