进入数据结构的世界

news2024/10/7 10:48:40

数据结构和算法的概述

  • 一、什么是数据结构
  • 二、什么是算法
  • 三、如何去学习数据结构和算法
  • 四、算法的时间复杂度和空间复杂度
    • 4.1 算法效率
    • 4.2 大O的渐进表示法
    • 4.3 时间复杂度
    • 4.4 空间复杂度
    • 4.5 常见复杂度对比

一、什么是数据结构

数据结构是计算机存储、组织数据的方式。(相互之间存在一种或多种特定关系的数据元素的集合)

二、什么是算法

算法就是一系列的计算步骤,用来吧输入数据转换成输出结果。(算法就是有良好的计算过程,把一个或一组的值输入,并产出一个或一组的值输出)

三、如何去学习数据结构和算法

现在的公司对学生的代码能力越来越高,数据结构和算法的题目越来越难。算法的能力在短期内是不能够快速提升的,需要进行算法训练的积累。校招的时候,笔试很难,为了能够找到工作,还需要对数据结构和算法早早的准备,多去训练算法能力。
数据结构和算法对于初学者来说很难。但 是,古话说的好,世上无难事,只怕有心人。不管数据结构和算法有多难,我们都要硬着头皮去学。我相信,只要多学多练,学习数据结构和算法就会越来越简单。

四、算法的时间复杂度和空间复杂度

时间空间这两个维度能够衡量算法的好坏,

4.1 算法效率

算法在编写成可执行程序后,运行程序需要耗费空间资源时间资源。因此,衡量一个算法的好坏,一般是从时间和空间两个维度来衡量的,这就是时间复杂度空间复杂度

时间复杂度主要是衡量算法的运行快慢,而空间复杂度主要是衡量一个算法运行时所需要的额外空间。(计算机发展的早期,计算机存储的容量很小,我们对空间复杂度很在乎。但是经过计算机行业的快速发展,计算机存储的容量已经达到了很高的地步。所以我们今天已经不需要特别在关注算法的空间复杂度)

4.2 大O的渐进表示法

大O符号(Big O notation):用于描述函数渐进行为的数学符号
大O的渐进表示法的推导方法:

1、用常数1取代运行时间中所以的加法常数。
2、在运行次数函数中,只保留最高阶项。
3、如果最高价项存在且不是1,则去除与这个项相乘的常数,得到的结果就是大O阶。

算法的时间复杂度存在最好、平均和最坏情况:

最好情况:任意输入规模的最大运行次数(上界)
平均情况:任意输入规模的期望运行次数
最坏情况:任意输入规模的最小运行次数(下界)

例如:在一个长度为N的数组中搜索一个数据x

最好情况:1次找到
平均情况:N/2次找到
最坏情况:N次找到

实际中,我们关注的都是算法的最坏情况所以,数组中搜索数据的时间复杂度为O(N)

4.3 时间复杂度

时间复杂度的定义:
一个算法执行所消耗的时间,从理论上说,是不能够算出来得,只有把程序放在机器上跑,才能够知道消耗的时间。一个算法所花费的时间与其中语句的执行次数成正比,算法的基本操作的执行次数,就是算法的时间复杂度。
案例1:

找到基本语句与问题规模n的数学表达式,算出该算法的时间复杂度。

//计算++count语句执行的次数
#include <stdio.h>
int main()
{
    int n = 0;
    scanf("%d", &n);
  
    int count = 0;

    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
            ++count;
    }
    for (int i = 0; i < 2 * n; i++)
    {
        ++count;
    }
    int m = 10;
    while (m--)
    {
        ++count;
    }
    printf("%d\n", count);
    return 0;
}

基本操作次数:
F(n)=n^2+2*n+10

  • n=10 F(n)=130
  • n=100 F(n)=10210
  • n=1000 F(n)=1002010

用大O的渐进表示法,时间复杂度为O(N^2)

  • n=10 F(n)=100
  • n=100 F(n)=10000
  • n=1000 F(n)=1000000

实际中我们计算时间复杂度时,并不一定计算精准的时间复杂度,而只需要大概执行次数,这里我们使用大O的渐进表示法。

通过上面我们可以发现大O的渐进表示法去掉了那些对结果影响不大的项,简洁明了的表示出了执行次数。
案例2:

计算Fun2的时间复杂度
void Fun2()
{
    int N;
    scanf("%d", &N);
    int count = 0;
    for (int i = 0; i < 2 * N; i++)
    {
        ++count;
    }
    int M = 10;
    while (M--)
    {
        ++count;
    }
    printf("%d\n", count);
}

Fun2的时间复杂度为:
F(N)=2*N+10
大O的渐进表示法:时间复杂度为O(N)
案例3:

//计算Fun3的时间复杂度
void Fun3()
{
    int N, M;
    scanf("%d%d", &N, &M);
    int count = 0;
    for (int i = 0; i < N; i++)
    {
        ++count;
    }
    for (int j = 0; j < M; j++)
    {
        ++count;
    }
    printf("%d\n", count);
}

Fun2的时间复杂度为:
F(N)=N+M
大O的渐进表示法:时间复杂度为O(N)
案例4:

//二分查找的思想
void Fun4()
{
    int m = 0;
    int arr[10] = { 1,2,4,6,8,11,55,66,77,88};
    int n;
    printf("请输入要查找的数:\n");
    scanf("%d", &n);
    int begin = 0;
    int end = 9;
    while (begin <= end)
    {
        int mid = begin + (end - begin)/2;
        if (arr[mid] < n)
            begin = mid + 1;
        else if (arr[mid] > n)
            end = mid - 1;
        else
        {
            printf("找到了\n");
            printf("%d", arr[mid]);
            m = 1;
            break;
    }
    }
    if(m==0)
    printf("没找到\n");
}

区间数据个数:
N
N/2
N/2/2
…………
N/2/2/2……/2=1

最坏的情况,查找区间缩放只剩一个值时,就是坏得,
假设查找x次,2^x=N,所以x=logN。

大O的渐进表示法:时间复杂度为O(logN).

案例5:

//斐波那契递归的复杂度
#include <stdio.h>
int Fun5(size_t n)
{
    if (n < 3)
        return 1;
    return Fun5(n - 2) + Fun5(n - 1);

}
int main()
{
    int n = 7;
    int sum=Fun5(n);
    printf("%d\n", sum);
    return 0;
}

打印结果:
在这里插入图片描述
递归展开图:
在这里插入图片描述
1次(2^ 0)
2次(2^ 1)
4次(2^ 2)
8次(2^ 3)
……
2^(N-1)次
通过函数递归图分析基本操作递归了2 ^N-1次,
大O的渐进表示法:时间复杂度为O (2 ^N)。

4.4 空间复杂度

空间复杂度的定义:
一个算法在运行过程中临时占用存储空间大小的量度。(空间复杂度算的是变量的个数)
注意:
函数运行时所需要的栈空间(存储函数、局部变量、一些寄存器信息等)在编译期间就已经确定好了,因此,空间复杂度主要就是函数在运行的时候申请的额外空间来确定的。
案例1:

//计算BubbleSort函数的空间复杂度
void BubbleSort(int* a, int n)
{
    assert(a);
    for (int end = n; end > 0; end--)
    {
        int exchange = 0;
        for (int i = 1; i < n; i++)
        {
            if (a[i - 1] > a[i])
            {
                Swap(&a[i - 1], &a[i]);
                exchange = 1;
            }
        }
        //不需要循环了
        if (exchange == 0)
            break;
    }
}

可以看出使用了常数个额外空间,所以空间复杂度为O(1)
案例2:

//看返回斐波那契数列的前n项,计算Fibonac的空间复杂度
int* Fibonac(int n)
{
    if (n == 0)
        return NULL;
    int* fibar = (int*)malloc(sizeof(int) * (n + 1));
    fibar[0] = 0;
    fibar[1] = 1;
    for (int i = 2; i <= n; i++)
    {
        fibar[i] = fibar[i - 1] + fibar[i - 2];
   }
    return fibar[i];
}

动态开辟了n+1个空间,大O的渐进表示法为O(N);

4.5 常见复杂度对比

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1011368.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何让电脑同时远程控制5台手机?

AirDroid Cast是一款强大的投屏&控制工具&#xff0c;不仅支持将安卓、iOS、Windows、macOS系统相互投屏&#xff08;可远程&#xff09;&#xff0c;而且能让Windows系统及macOS系统的电脑远程控制安卓设备。 通过本文您将了解到如何使用AirDroid Cast&#xff0c;用Windo…

Spring底层的核心原理解析

这篇文章大致讲解一下spring的整个执行流程&#xff0c;也就是在我们脑子里面建立一个笼统的概念 spring如何创建一个容器呢 容器里面是对象 上面就是利用AnnotationConfigApplicationContext这个对象&#xff0c;然后传入了一个配置类的字节码对象给我们创建一个Spring容器&am…

【力扣每日一题】2023.9.13 检查骑士巡视方案

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 题目给我们一个n*n大小的矩阵&#xff0c;矩阵的元素表示骑士已经行动的次数&#xff0c;问我们骑士能不能按照矩阵里元素顺序来巡视整个…

(python语言程序设计教程)自学一

&#xff08;python语言程序设计教程&#xff09;自学一 文章目录 前言一、计算机基础概述1. 计算机硬件组成2. 计算机软件与程序设计语言 二、python语言简介三、turtle库3.1. 画布设置&#xff1a;3.2. 基本方法3.3. 基本图形绘制 四、课后习题4.1. 求圆柱体体积4.2. 绘制一个…

redis 多租户隔离 ACL 权限控制(redis-cli / nodejs的ioredis )

Redis 6版本之后&#xff1a;提供ACL的功能对用户进行更细粒度的权限控制 &#xff1a;&#xff08;1&#xff09;接入权限:用户名和密码&#xff08;2&#xff09;可以执行的命令&#xff08;3&#xff09;可以操作的 KEY ACL常用规则介绍&#xff1a; 指令列表 //增加可操…

学Python的漫画漫步进阶 -- 第六步

学Python的漫画漫步进阶 -- 第六步 六、容器类型的数据6.1 序列6.1.1 序列的索引操作6.1.2 加和乘操作6.1.3 切片操作6.1.4 成员测试 6.2 列表6.2.1 创建列表6.2.2 追加元素6.2.3 插入元素6.2.4 替换元素6.2.5 删除元素 6.3 元组6.3.1 创建元组6.3.2 元组拆包 6.4 集合6.4.1 创…

【Java 基础篇】Java类型通配符:解密泛型的神秘面纱

在Java中&#xff0c;类型通配符&#xff08;Type Wildcard&#xff09;是泛型的重要概念之一。它使得我们能够更加灵活地处理泛型类型&#xff0c;使代码更通用且可复用。本文将深入探讨Java类型通配符的用法、语法和最佳实践。 什么是类型通配符&#xff1f; 类型通配符是一…

ArcGIS 10.4安装教程!

软件介绍&#xff1a;ArcGIS是一款专业的电子地图信息编辑和开发软件&#xff0c;提供一种快速并且使用简单的方式浏览地理信息&#xff0c;无论是2D还是3D的信息。软件内置多种编辑工具&#xff0c;可以轻松的完成地图生产全过程&#xff0c;为地图分析和处理提供了新的解决方…

计算机毕设 大数据上海租房数据爬取与分析可视化 -python 数据分析 可视化

# 1 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&#xff0c;往往达不到毕业答辩的要求&#xff0c;这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通…

算法与设计分析--分治算法的设计与分析

某不知名学校的第二次算法实验报告&#xff0c;一共四道题 全部来自力扣 第一题 ​​​​​​169. 多数元素 题目描述&#xff1a; 给定一个大小为 n 的数组&#xff0c;找到其中的多数元素。多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的&am…

Docker概念通讲

目录 什么是Docker&#xff1f; Docker的应用场景有哪些&#xff1f; Docker的优点有哪些&#xff1f; Docker与虚拟机的区别是什么&#xff1f; Docker的三大核心是什么&#xff1f; 如何快速安装Docker&#xff1f; 如何修改Docker的存储位置&#xff1f; Docker镜像常…

敏捷管理的4价值观12准则

一、敏捷管理的的4个价值观 个体和交互胜过流程和工具可工作的软件胜过面面俱到的文档客户合作胜过合同谈判响应变化胜过遵循计划 二、敏捷管理的12条准则 上篇解读了对于敏捷价值观的理解&#xff0c;这篇来聊一聊敏捷的12指导准则。关于敏捷宣言的12条准则的原始描述&…

Dokcer搭建Apache Guacamole堡垒机

一、什么是堡垒机 “堡垒机” 这个词通常指的是 “堡垒机器”&#xff08;Bastion Host&#xff09;的简称。堡垒机是一种计算机系统或网络设备&#xff0c;用于增强计算机网络的安全性。它在网络中充当一个重要的安全关口&#xff0c;通过限制对内部网络的访问&#xff0c;帮…

LeetCode(力扣)860. 柠檬水找零Python

LeetCode860. 柠檬水找零 题目链接代码 题目链接 https://leetcode.cn/problems/lemonade-change/ 代码 class Solution:def lemonadeChange(self, bills: List[int]) -> bool:five 0ten 0twenty 0for i in range(len(bills)):if bills[i] 5:five 1if bills[i] 10…

pdf怎么压缩的小一点?pdf文件压缩方法汇总

在日常生活中&#xff0c;我们常常需要处理大量的PDF文件。有时候&#xff0c;这些PDF文件可能因为内容丰富、结构复杂而体积庞大&#xff0c;给我们的存储和传输带来了不便。那么&#xff0c;如何将这些PDF文件压缩得小一点&#xff0c;以便更方便地使用呢&#xff1f; 一、嗨…

Git(6)——GitHub

目录 一、简介 二、概要 三、注册 ​四、创建仓库 五、推送本地代码 六、拉取远端代码 一、简介 在Git&#xff08;5&#xff09;中&#xff0c;我们已经对Git分支的概念和用法有了一定了解&#xff0c;对于在本地进行代码版本管理&#xff0c;其实当前所学的东西基本已经…

【个人博客系统 × Redis】“最后的升级” · 连接Redis · Redis的基本使用

【JavaEE】进阶 个人博客系统&#xff08;7&#xff09; 文章目录 【JavaEE】进阶 个人博客系统&#xff08;7&#xff09;1. linux安装Redis1.1 通过yum商店下载Redis1.2 启动Redis1.3 操作Redis 2. Redis的基本使用&#xff08;关键字大小写不区分&#xff09;2.1 set2.2 g…

Lombok中的@Builder注解的使用

Lombok中的Builder注解的使用 作用 Builder注解的作用主要是用来生成对象&#xff0c;并且可以为对象链式赋值。 引入依赖 因为Builder注解是lombok中的东西&#xff0c;所以第一步我们需要引入lombok的依赖&#xff0c;如下图&#xff1a; 第二步给实体类加上Builder注解…

每日一博 - Token Based Authentication VS HMAC Authentication 实现web安全

文章目录 概念HMAC工作原理 概念 Token Based Authentication和HMAC&#xff08;Hash-based Message Authentication Code&#xff09;Authentication都是用于身份验证和数据完整性验证的安全机制&#xff0c;但它们有不同的工作方式和适用场景。以下是它们的主要区别和比较&a…

idea把项目打成jar包步骤详解

最近产品需要预研一个小功能&#xff0c;开始后在本地开发测试好之后&#xff0c;需要打成jar提供出去&#xff0c;今天弄完了&#xff0c;决定把这个步骤记录下来&#xff0c;便于以后轻车熟路。 打成jar要有mian方法的入口&#xff0c;所以我们在代码中需要定义一个main方法&…