算法和算法分析

1.算法的定义

 2.算法和程序

算法是解决问题的一种方法或一个过程,考虑如何将输入转成输出,一个问题可以有多种算法。

程序是用某种程序设计语言对算法的具体实现。

程序=数据结构+算法

理解:对每一种菜肴,需要说明用什么原料(数据结构),再介绍操作步骤(算法)。

3.算法的特性


4.算法的效率
时间效率

 

 

 比较总和比较麻烦↓

*时间复杂度

    

 

 

 基本语句:算法中重复执行次数和算法的执行时间成正比的语句;对算法运行时间贡献最大的;执行次数最多

问题规模n:

 

 

 

 

 

平均时间复杂度:用代码在所有情况下执行的次数的加权平均值表示。

 

 时间复杂度:

O(1)常数型:

O(n)线性型:

O(n的平方)平方型:

O(n的三次方)立方型:

O(2的n次方)指数型:

对数型:

O二维型:

*空间复杂度

O(1):常数空间复杂度。算法使用的额外空间是固定的,不随输入规模变化。例如,一个只使用几个变量的简单算法。x、y数值再大也不会影响空间分配

O(N):线性空间复杂度。算法使用的额外空间与输入规模成线性关系。例如,一个数组来存储输入数据。

O(n2):平方空间复杂度。算法使用的额外空间与输入规模的平方成正比。例如,在矩阵乘法中,如果需要创建一个新的矩阵来存储结果。

 

例题1:二分查找的复杂度分析

递归方法:

#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>
#include <stdlib.h>
int search_(int a[], int l, int r, int x)//递归方法
{
    int m = l + (r - l) / 2;
    if (l > r) {
        return -1;
    }
    if (x == a[m]){
        return m;
    }
    if (x < a[m]) {//查找的数比中间值小,在左半区继续查找
        search_(a,m-1,l,x);

    }
    else {        //查找的数比中间值大,在右半区继续查找
        search_(a, m + 1, r, x);
    }

}

int main()
{
    int n;
    scanf("%d", &n);
    int* a = (int*)malloc(n * sizeof(int));
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }
    int x;
    scanf("%d", &x);//待查找元素
    int result = search_(a, 0, n - 1, x);
    if (result == -1) {
        printf("元素未找到");
    }
    else {
        printf("元素找到,位于索引%d", result);
    }
    free(a);//记得释放内存
}

非递归方法:



int search(int arr[], int n, int x) //非递归方法
{
    int l = 0, r = n - 1;//查找范围的左边界和右边界
    while (l <= r) {
        int m = l + (r - l) / 2;
        if (arr[m] == x)
            return m;

        if (arr[m] < x)//中间位置元素小于要查找的元素x 更新左边界
            l = m + 1;
        else          //中间位置元素大于要查找的元素x 更新右边界
            r = m - 1;
    }
    return -1;
}
int main(
    {
        int n;
        scanf("%d", &n);

        int* arr = (int*)malloc(n * sizeof(int));
        for (int i = 0; i < n; i++)
        {
            scanf("%d", &arr[i]);
        }
         int x;
            scanf("%d", &x);

        int result = search(arr, n, x);

        if (result == -1) {
            printf("元素未找到\n");
        }
        else {
            printf("元素找到,位于索引 %d\n", result);
        }
        
        free(a);

        return 0;
    }




第一次:在n个元素中找到目标元素

第二次:在n/2个元素中找到目标元素

第三次:在n/22个元素中找到目标元素

...

第k次:在n/2k个元素中找到目标元素

2k<=n,k<=

最坏情况时间复杂度:  

最好情况时间复杂度:一次找到----O(1)

平均情况时间复杂(所有可能的输入实例以均等概率出现的情况下, 算法的运行运行时间)

假设要查找的元素等概率地分布在数组中的任意位置,则每次查找时,要查找的元素有 50% 的可能在左侧和 50% 的可能在右侧。因此,每次循环迭代最多将查找范围缩小一半。

空间复杂度一个算法在运行过程中临时占用储存空间大小的量度,额外占取的空间的大小):

函数中没有使用额外的数据结构来存储中间结果或辅助信息,其空间复杂度主要取决于局部变量l,r,m的使用情况,这几个变量均只占用了固定的空间,是常数级别的,与输入的个数n无关。

O(1)

 

例题2:冒泡排序的复杂度分析

本段冒泡排序函数中,外部循环执行次数为n-1次。

内部循环的执行次数为n-1-i次,总执行次数为:T(n)=(n-1)*(n-1-i)次

最坏情况时间复杂度:  O(n2)

最好情况时间复杂度O(n2)

平均情况时间复杂O(n2)

空间复杂度一个算法在运行过程中临时占用储存空间大小的量度,额外占取的空间的大小):

     冒泡排序是一种原地排序算法,不需要开辟额外的数组或数据结构空间来储存数据

O(1)

优化写法:

最坏情况时间复杂度:  O(n2)

最好情况时间复杂度O(n)

在优化写法中,最好情况是输入的数据元素已经是有序的,这时只需要在i=0时,进行内部循环,执行n-1次

平均情况时间复杂O(n2)

空间复杂度:O(1)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值