数据结构入门:探索数据结构第一步

news2024/11/15 11:43:41

0.引言

在我们的日常生活中,经常需要管理大量的数据,就譬如学校中有好几千个学生,中国有十三亿人口,对于那么多的数据进行查找、插入、排序等操作就会比较慢。人们为了解决这些问题,提高对数据的管理效率,提出了一门学科:数据结构与算法

1.什么是数据结构

数据结构是由“数据”和“结构”两词组合而来。

什么是数据?

常见的数值1、2、3、4......、学生管理系统中保存的学生信息(学号、年龄、年级等到)都是数据

什么是结构?

我们想要大量的使用某一个类型的数据时,需要手动定义大量的独立的变量对于程序来说,可读性非常差,因此我们会借助数组这样的数据结构将大量的数据组织在一起,结构就可以理解为组织数据的方式。

打个比喻,如果我们把叫“裤衩”的羊放生到草原上,我们自然很难找到它;但,如果我们把这只羊放到羊圈里,我们就可以很轻松的找到它。

2.什么是算法

对于我们在这个地方的学习而言,算法就是一个计算过程,它指的是一系列的计算步骤,用来将输入的数据转化成为输出的结果。

而在我们的课程内,我们需要学习的算法是:搜索、排序,递归、分治、回溯、DP、贪心。

算法是一个很让人头疼的东西,学习算法就像学习数学,而且初学时往往一道题做着做着几个小时就过去了......  但,持之以恒,每个类型的题目都积累了一定数量了之后,算法对于我们而言便小菜一碟了。

在我们数据结构这本书上,我们会学到的算法是搜索和排序以及一部分的递归算法

3.复杂度分析

3.1算法评估

我们的学习数学的过程中,经常会遇到一题多解的情况出现,而其中总有一种方法会被称为最优解。

我们对一个编程问题的解决也是如此,可能两段程序拥有相同的入口,也可以达到相同的目标。

那么,我们如何判断两段程序的优劣呢?

我们在判断程序的优劣,自然而然的就可以想到两个方面的问题:

  • 时间效率:算法运行的快慢
  • 空间效率:算法所占空间的大小

3.2评估方法

评估时间的方法:

  • 实验分析法
  • 理论分析法

3.2.1实验分析法

实验分析法简单来说就是将不同的算法输入到同一台电脑上,统计时间的快慢。但是这种方法有两个缺陷:

  1. 无法排查实验自身条件与环境的条件的影响:比如同一种算法在不同配置的电脑上的运算速度可能不同,甚至结果完全相反。我们很难排查所有的情况
  2. 成本太高:同一种算法可能在数据少时表现不明显,在数据多时速率教快(学到排序后大家就可以理解这一句话了)。而且哪来那么多电脑给你做实验......

3.2.2理论分析法        

由于实验分析法的局限性,就有人提出了一种理论测评的方法,就是渐进复杂度分析,简称复杂度分析。

这种方法体现算法运行所需的时空资源与输入数据大小之间的关系,能够有效的反应处算法的优劣。

4.时间复杂度和空间复杂度

4.1空间复杂度

一个算法所花费的时间与其中语句的执行次数成正比例,算法中的基本操作的执行次数,为算法的时间复杂度。

我们现在假设每条语句执行所用的时间为1ns

那么,以下这段代码执行所需时间:

int main()
{
	int a = 3;//1
	int b = 5;//1
	int c = a + b;//1
	int n = 0;//1
	scanf("%d ", &n);//1
	for (int i = 0; i < n; i++)
	{
		printf("%d ", i);//n
	}
	printf("%d ", c);//1
	return 0;
}

计算时间如下:

                       T\left ( n \right )=1+1+1+1+1+1+n=6+n 

如果,n趋于正无穷时,那么,式子内的常数6的影响是微乎其微的,我们就可以将其忽略掉。

现在,我们改写一下这段代码

int main()
{
	int a = 3;//1
	int b = 5;//1
	int c = a + b;//1
	int n = 0;//1
	scanf("%d ", &n);//1
	for (int i = 0; i < 3n; i++)
	{
		printf("%d ", i);//3n
	}
	printf("%d ", c);//1
	return 0;
}

此时,它的时间为:                        

                         T\left ( n \right )=1+1+1+1+1+1+3n=6+3n

在刚刚,我们已经发现常数可以忽略了,现在我们同样让n趋于正无穷,这时我们发现,3n和n的极限都是正无穷,那么,它的系数影响的也不大了。因此,我们也可以把系数忽略掉。

现在,我们再改写一下代码:

int main()
{
	int a = 3;//1
	int b = 5;//1
	int c = a + b;//1
	int n = 0;//1
	scanf("%d ", &n);//1
	for (int i = 0; i < 3n; i++)
	{
		printf("%d ", i);//n
	}
	for (int i = 0; i < n^2; i++)
	{
		printf("%d ", i);//n的平方
	}
	printf("%d ", c);//1
	return 0;
}

此时,它的时间为:

                  T\left ( n \right )=1+1+1+1+1+1+3n+n^{2}=6+3n+n^{2}

显而易见的是,随着n的扩大,n^2的变化率必然是要比n高的。

譬如,当n等于一千时,n^2就是一百万了。

假如说一个国家有一百万零一千个兵,那么,战死了一千个兵会影响到别的国家对这个国家的评估吗?

这是显然不会的。

同理,在我们对算法的评估中,我们也不会在乎这个影响,因此,我们也可以将n忽略掉。

根据刚刚所说的内容,我们继续向外推导,如果一个数是指数,那么自然也就可以忽略这个平方了。

现在给大家介绍一个概念:“阶”

在数学和计算机科学中,"阶"通常指的是函数的增长速度,特别是在描述算法的时间复杂度时。阶通常与函数的输入规模n相关,用来表示随着输入规模n的增加,函数值增长的速度。

通过上述的推导过程,我们可以得到这么一个结论:

  • 最高阶项的增长速度远超过其他低阶项,因此低阶项的影响可以忽略不计。

也就是说,阶数高的可以忽略阶数低的

现在,我们发现,时间复杂度的计算可以简化为两个步骤:

  • 忽略除最高阶以外的所有项
  • 忽略所有系数

这里需要我们大家注意的一点是:我们对时间复杂度的理论推导是基于理论的,而不是基于实例。

然后现在我们学习一下如何记录时间复杂度:

譬如上面的一段代码,时间复杂度为O(n^2),这种方法称为大O的渐进表示法。

现在给大家写一个O(1)的代码

int main()
{
	int a = 3;//1
	int b = 5;//1
	int c = a + b;//1
	return 0;
}

 时间:

                                      T\left ( n \right )=1+1+1=3X1

我们认为3是1的系数,因此这段代码的时间复杂度为O(1),表示常数阶。

最后一个需要大家注意的点是:

  • 在计算复杂度时,我们考虑最坏的情况,不是最坏的情况算出的时间复杂度都是错误的。

4.2空间复杂度

空间复杂度也是一个数学表达式,它的计算方式和空间复杂度是一样的。

在这里,它计算的是一个算法在运行过程中临时占用存储空间大小的量度。

这里,我们关心的是临时变量占用存储空间的量度,而不是具体的变量大小。

也就是说,我们关心的是创建的临时变量的个数,而不关心具体的大小。

下面给大家算几个实例:

//这段代码在有的编译器过不了,大家可能无法运行
void func()
{
	int n = 0;
	scanf("%d ", &n);
	int arr[n];//开辟了n个空间     
}

这段代码中,开辟了n个空间,空间复杂度为O(n)。

void Swap(int  a,int b)
{
	int c = a;
	a = b;
	b = c;
}

开辟了一个整型的空间,空间复杂度为O(1) 

由于1KB=1024Byte ,所以1MB=1024*1024=1048576字节,大概就是一百万字节。

一百万字节能存的变量可太多了,因此我们现在更加关注时间复杂度而不是空间复杂度。

5.常见时间复杂度

这里分析两段代码的复杂度,分别是冒泡排序和折半查找

冒泡排序:

void bubble_sort(int* arr, int sz)
{
	for (int i = 0; i < sz-1; i++)
	{
		int flag = 1;
		for (int j = 0; j < sz-1- i; j++)//每次都可以少比较一个数
		{
			if (arr[j] > arr[j + 1])
			{
				flag = 0;
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
		if (flag == 1)
			break;
	}
}
int main()
{
	int arr[] = { 8,3,2,7,10,9,1,0,7,4};
	int sz = sizeof(arr) / sizeof(arr[0]);
    bubble_sort(arr, sz);
	for (int i= 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

时间复杂度O(n^2);空间复杂度O(1)

折半查找:

int binarySearch(int arr[], int size, int key) {
    int left = 0;
    int right = size - 1;

    while (left <= right) {
        int mid = left + (right - left) / 2; // 防止溢出
        if (arr[mid] == key) {
            return mid; // 找到键值,返回下标
        } else if (arr[mid] < key) {
            left = mid + 1; // 键值在右侧子数组
        } else {
            right = mid - 1; // 键值在左侧子数组
        }
    }

    return -1; // 未找到键值,返回-1
}

 时间复杂度:O(logn)  空间复杂度:O(1)

结构体

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

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

相关文章

支持微信支付宝账单,极空间Docker部署一个开箱即用的私人账本『cashbook』

支持微信支付宝账单&#xff0c;Docker部署一个开箱即用的私人账本『cashbook』 哈喽小伙伴好&#xff0c;我是Stark-C~ 不知道屏幕前的各位富哥富姐们有没有请一个专业的私人财务助理管理自己的巨额资产&#xff0c;我不是给大家炫耀&#xff0c;我在月薪300的时候就已经有了…

WPF学习(2)--类与类的继承2-在窗口的实现

一、代码分析 1.Animal.cs 1.1 代码 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace AnimalNamespace {public class Animal{public string Name { get; set; }public int Age { get; set…

四、STP(生成树协议)

目录 一、经典生成树&#xff08;STP&#xff09; 1.1、作用 1.2、重要参数 1.3、BPDU 1.4、STP计算过程 1.5、STP接口状态 二、快速生成树&#xff08;RTSP&#xff09; 2.1、端口角色的增补 2.2、端口状态简化 2.3、配置BPDU报文修改 2.4、配置BPDU的处理 2.5、快…

从零开始手把手Vue3+TypeScript+ElementPlus管理后台项目实战十一(整体布局04之Header及用户注销)

新增Hearder 新增 src/layout/components/PageHeader.vue <template><div class"header-cont"><div><h1><router-link to"/">RealWorld</router-link></h1></div><div><template v-if"is…

ESP32-C6 闪耀 Apple WWDC24|使用 Embedded Swift 构建 Matter 设备

WWDC 是苹果公司的年度全球开发者大会&#xff0c;旨在向全球开发者展示最新技术和工具。在今年的 WWDC 2024 上&#xff0c;苹果宣布将 Swift 语言扩展至嵌入式设备领域。大会技术讲座中&#xff0c;乐鑫 ESP32-C6 也现身官方 Demo “Go Small with Embedded Swift​​​​​​…

Python-json模块

一、相关概念 # 序列号 和反序列号 # 序列号&#xff1a;把内存中的数据类型转成一种特定格式&#xff0c;这种格式&#xff08;json/pickle&#xff09;可以用于存储&#xff0c;或者传输给其他平台 import json # 内存中是数据类型 ----> 序列化 ----> 特定格式&…

今日早报 每日精选15条新闻简报 每天一分钟 知晓天下事 6月13日,星期四

每天一分钟&#xff0c;知晓天下事&#xff01; 2024年6月13日 星期四 农历五月初八 1、 财政部&#xff1a;将在19日第一次续发行2024年20年期超长期特别国债。 2、 成本低&#xff0c;商载高&#xff0c;我国自主研制HH-100商用无人运输机首飞成功。 3、 四川甘孜州石渠县1…

水利水电安全员B类精选试题(附答案)

第1题:职业病病人除依法享有工伤保险外&#xff0c;依照有关民事法律&#xff0c;尚有获得赔偿的权利&#xff0c;有权向()提出赔偿要求。 | A.当地人民政府 B.医疗机构 C.企业主管部门 D.用人单位 正确答案:D 第2题:事故预防对策中()是利用法律.规程.标准以及规章制度等必要…

ChatGPT面试指南来袭!10个提示词助你应对自如

面试时刻,你准备充分了吗?许多求职者即将面对的面试,仿佛一场无形的战斗。关键的面试问题,犹如一个个智勇双全的敌人。那么,如何才能在这场战斗中取胜?本文为你提供面试中的十大秘密武器——提示词。正确使用提示词,你可以破解面试官的难题,从容应对各种困境。别小看这十个小…

SpringBoot集成mqtt上下线提醒功能设计

目录 1.首先安装emqx&#xff0c;去官网下载emqx压缩包&#xff0c;并且解压。 2.使用emqx start 命令启动emqx后台管理 3.下载mqttx调试工具&#xff0c;使用mqttx调试mqtt连接。下载地址:MQTTX下载-MQTTX官方版下载,下载完成直接打开&#xff0c;便可进行mqtt连接调试 4.…

ping: www.baidu.com: 未知的名称或服务(IP号不匹配)

我用的是VMware上的Red Hat Enterprise Linux 9&#xff0c;出现了能联网但ping不通外网的情况。 问题描述&#xff1a;设置中显示正常连接&#xff0c;而且虚拟机右上角有联网的图标&#xff0c;但不能通外网。 按照网上教程修改了/etc/resolv.conf和/etc/sysconfig/network-…

公交车载视频监控系统解决方案

公交车载视频监控系统基于iVMS-7200移动视频监控管理平台&#xff0c;通过3G/4G网络接入车载前端&#xff0c;实现实时监控、录像回放、GIS地图定位、轨迹回放、设备状态查询、紧急报警等功能。 车载前端包含车载硬盘录像机(简称车载DVR或MDVR)、车载专用摄像机、车载LCD显示屏…

谷粒商城实战(035 k8s集群学习1-前置介绍)

Java项目《谷粒商城》架构师级Java项目实战&#xff0c;对标阿里P6-P7&#xff0c;全网最强 总时长 104:45:00 共408P 此文章包含第339p-第p342的内容 分布式高级篇总结 高可用集群 内容 k8s介绍 为什么使用k8s 组件 master组件 node&#xff08;节点&#xff09;组件 要部…

操作系统——信号

将信号分为以上四个阶段 1.信号注册&#xff1a;是针对信号处理方式的规定&#xff0c;进程收到信号时有三种处理方式&#xff1a;默认动作&#xff0c;忽略&#xff0c;自定义动作。如果不是自定义动作&#xff0c;这一步可以忽略。这个步骤要使用到signal/sigaction接口 2.…

代码随想录算法训练营第五十八天 | 392.判断子序列

392.判断子序列 题目链接&#xff1a;代码随想录 视频讲解&#xff1a;动态规划&#xff0c;用相似思路解决复杂问题 | LeetCode&#xff1a;392.判断子序列_哔哩哔哩_bilibili 解题思路 本题和求最长公共子序列是一样的&#xff0c;值就是s字符串的长度&#xff0c;如果一致…

不吃饭也要搞懂的 git 命令

昨天睿哥布置了一个任务给我&#xff0c;让我学习一下 Git 的一些命令。 我问睿哥&#xff0c;到底我们在实际开发中用哪些命令会比较多&#xff0c;睿哥是这样回答我的&#xff1a; 而且他推荐我用 IDEA 自带的那个 Git 面板来执行 git 命令&#xff0c;他说直接敲命令太麻烦…

一线大厂都在高薪抢AI产品经理?

哈喽&#xff0c;大家下午好呀&#xff5e; 当AI的风吹到产品届&#xff0c;唯叹相见恨晚&#xff01; 作为一名产品经理&#xff0c;日常写调研、需求分析、产品设计、项目管理、数据分析……每一项工作都需要投入大量的时间和精力。 但用上AI后&#xff0c;你会发现写个需…

【面经总结】Java基础 - IO

序列化 什么是序列化和反序列化&#xff1f; 序列化&#xff1a;将对象转换为二进制数据 反序列化&#xff1a;将二进制数据转换为对象 目的&#xff1a;方便网络传输、持久化保存 Java 是怎么实现序列化的&#xff1f; Java 通过对象输入输出流来实现序列化和反序列化&a…

关于docker无法正常下载镜像的问题

文章目录 之前还可以正常下载镜像&#xff0c;但是一段时间之后就无法下载了&#xff0c;猜测可能是政治原因&#xff0c;无法连接到国外服务器&#xff0c;所以我设置了阿里云的镜像加速器。 配置方法如下&#xff1a; 前往阿里云&#xff08;https://help.aliyun.com/zh/acr/…

Windows同一文件夹下支持大小写同名文件

举例&#xff1a;同一文件目录下需要存在A.java, a.java, Windows是不支持的&#xff0c;这时候需要建一个Linux子系统的文件夹 创建教程 1、在启用或关闭Windows功能下面找到 适用于Linux系统的Windows子系统 2、cmd 执行命令 fsutil file SetCaseSensitiveInfo 文件夹路径 …