时间复杂度
复杂度:时间复杂度、空间复杂度
时间复杂度:算法运行的快慢(执行次数(可有多条语句))
空间复杂度:算法运行所需要的额外空间
计算数据结构的时间复杂度需要考虑两个方面:基本操作的执行次数和输入规模的增长。
下面是计算数据结构时间复杂度的一般步骤:
-
确定基本操作:首先要确定数据结构中的基本操作,例如插入、删除、查找等。这些操作通常是数据结构的核心操作。
-
分析基本操作的执行次数:对于每个基本操作,分析其在最坏情况下的执行次数。这可以通过分析代码或者估算操作的执行次数来确定。
-
表达时间复杂度:将基本操作的执行次数表示为输入规模的函数。常用的时间复杂度表示方法包括大O记法、Ω记法和Θ记法。大O记法用于表示最坏情况下的时间复杂度,Ω记法用于表示最好情况下的时间复杂度,Θ记法用于表示平均情况下的时间复杂度。
-
简化时间复杂度:根据算法的特点和规模,简化时间复杂度的表示。常见的时间复杂度有常数时间O(1)、线性时间O(n)、对数时间O(log n)、平方时间O(n^2)等。
需要注意的是,计算时间复杂度是一种近似估计的方法,它用于衡量算法的运行效率。在实际应用中,还需要考虑其他因素,如硬件环境、编译器优化等。
另外,不同的数据结构可能有不同的时间复杂度计算方法。例如,对于链表,插入和删除操作的时间复杂度通常是O(1),而查找操作的时间复杂度是O(n);对于二叉搜索树,插入、删除和查找操作的时间复杂度都是O(log n)。因此,在计算时间复杂度时,需要根据具体的数据结构和操作进行分析。
计算
1、用常数1取代运行时间中的所有加法常数。
2、在修改后的运行次数函数中,只保留最高阶项。
3、如果最高阶项存在且不是1,则去除与这个项目相乘的常数。得到的结果就是大O阶。
void Fun(int N,int M)
{
int count=0;
for(int k=0;k<M ; ++k)
{
++count;
}
for(int k=0;k<N ; ++k)
{
++count;
}
printf("%d\n",count);
}
上述代码的时间复杂度要分情况讨论:
1.不知道M和N的大小 O(N+M)
2.N远大于M O(N)
3.M远大于N O(M)
4.M和N一样大 O(N)或者O(M)
#include<stdio.h>
void Bubble_sort(int arr[], int size)
{
int j,i,tem;
for (i = 0; i < size-1;i ++)//size-1是因为不用与自己比较,所以比的数就少一个
{
int count = 0;
for (j = 0; j < size-1 - i; j++) //size-1-i是因为每一趟就会少一个数比较
{
if (arr[j] > arr[j+1])//这是升序排法,前一个数和后一个数比较,如果前数大则与后一个数换位置
{
tem = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tem;
count = 1;
}
}
if (count == 0) //如果某一趟没有交换位置,则说明已经排好序,直接退出循环
break;
}
}
F(N)=N-1+N-2+N-3+…+2+1=(N-1+1)(N-1)/2 即为O(N^2)
//二分查找
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };//已知的整形有序数组
int x = 0;//x是要寻找的数
int left = 0;//左下标
int right = sizeof(arr) / sizeof(arr[0]) - 1;//数组右下标
scanf("%d", &x);
while (left <= right)
{
int mid = left+(right-left)/2;//找到最中间的数
if (x < arr[mid])
{
right = mid-1;
}
else if (x > arr[mid])
{
left = mid+1;
}
else
{
printf("找到了,下标是%d\n", mid);
break;
}
}
if (right < left)
{
printf("没找到");
}
return 0;
}
N/2/2/2/2…/2=1
2^x=N 则x=log2 N 即O(log2 N)