算法时间复杂度(数据结构学习笔记1)

本文介绍了算法中的问题规模、语句频度和基本语句的概念,重点阐述了算法时间复杂度的定义,通过单层、双层和三层循环示例展示了不同时间复杂度的表示,并讲解了二分法查找的时间复杂度分析。最后讨论了如何判断算法的时间复杂度,包括考虑最佳、最坏和平均情况。
摘要由CSDN通过智能技术生成

基本概念:

     1.问题规模:算法求解问题输入量的多少,是问题大小的本质表示,一般用整数n表示。

     2.语句频度:一条语句的重复执行次数。

     3.基本语句:算法中重复执行次数和算法的执行时间成正比的语句。

     4.算法的渐近时间复杂度(简称时间复杂度):一般情况下,算法中基本语句重复执行的次数            是问题规模的某个函数f(n),算法的时间量度记作T(n)=O(f(n)),它表示随问题规模n的增大,            算法执行时间的增长率和f(n)的增长率相同,称作算法的渐进时间复杂度。(O表示数量级)

时间复杂度的表示方法

        经典函数举例

                1、单层循环

                   【例题1】给定 n(n≤1000)个元素 ai​,求其中 奇数 有多少个。

   int countOdd(int n, int a[]) {
    int cnt = 0;
    for(int i = 0; i < n; ++i) {
        if(a[i] & 1)
            ++cnt;
    }
    return cnt;
}

a & 1等价于a % 2,代码a模 2 的余数;(作者:英雄哪里出来)

此题用了单层循环,这里的 n 是一个变量,随着 n 的增大,执行次数增大,执行时间就会增加,所以就有了时间函数的表示法如下:
                        f(n)=n

当 f(n)=n,我们称这个算法拥有线性时间复杂度,记作 O(n);

           2、双层循环 

                             

int countOddPair(int n, int a[]) {
    int cnt = 0;
    for(i = 0; i < n; ++i) {
        for(j = i+1; j < n; ++j) {
            if( (a[i] + a[j]) & 1)
                ++cnt;
        }
    }
    return cnt;
}
  • 双层循环,它的时间函数表示法如下:

          f(n)=n(n−1)​/2
  • 当 f(n)=n(n−1)​/2  ,我们称这个算法拥有平方级时间复杂度,记作 O(n^2)

  • 3、三层循环 三层循环,它的时间函数表示法如下:

  •                   常见时间复杂度 

  • (二分法概念:二分法查找,也叫折半法,是一种在有序的数组中查找特定元素的搜索算法。注意:使用二分法的前提条件,数组内的数字必须是有序的!举例:首先有一组数字{1,2,3,4,5,6,7,8,9,10} ,分别给予每个数组内的数字一个下标,二分法就是每次取数组的中间值与我们所要查找的数字进行比较,例如:我需要查找的数字是“7”
    中间值下标=做左端的值的下标加上做右边的值的下标除以2;mid = (left+right);第一次使用二分法:mid = (0+9) / 2 = 4下标为4的值为5,5与7比较,5比7小,那么我们的 left = mid + 1 = 4 + 1 =5。第二次使用二分法:mid = (5 + 9) / 2 = 7,下标为7的值为8,8与7比较,8比7大,那么我们的rigth =  mid - 1 = 7 -1 = 6。第三次使用二分法:mid = (5 + 6) / 2 = 5,下标为5的值是6,6与7比较,6比7小,那么我们的left = mid + 1 = 5 + 1 = 6。第四次使用二分法:mid = (6 + 6 ) / 2 =6,下标为6的值是7,7与7相等,找到了!
    int main()
    {
    	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
    	int k = 0;
    	printf("请输入你需要查找的数字\n");
    	scanf("%d", &k);
    	int sz = sizeof(arr) / sizeof(arr[0]);
    	int left = 0;//左下标
    	int right = sz - 1;//右下标
     
    	while (left <= right)
    	{
    		int mid = (left + right) / 2;//中间元素下标;mid = left+(right-left)/2
    		if (arr[mid] < k)
    		{
    			left = mid + 1;
    		}
    		else if (arr[mid] > k)
    		{
    			right = mid - 1;
    		}
    		else
    		{
    			printf("找到了下标是:%d", mid);
    			break;
    		}
    		if (left > right)
    			printf("不存在该数字\n");
    	}
    	return 0;
    }
    

    如何判断时间复杂度

    (笔记来源:
    链接:https://leetcode.cn/leetbook/read/data-structure-all-in-one/w7bqd5/
    来源:力扣(LeetCode)
    作者:英雄哪里出来

  • (补充)最好最坏和平均时间复杂度

  •      (1)for(i=0;i<n;i++)

           (2)        if(a[i]==e)    return i+1

           (3)   return 0

    此算法中,语句2的频度不仅与问题规模n有关,还与a[i]的各元素值及e的取值有关。

    习题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LONG_shuishui

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值