【数据结构】复杂度(长期维护)

本篇博客主要是浅谈数据结构概念及时间复杂度,并做长期的维护更新,有需要借鉴即可。

复杂度目录

  • 一、初识数据结构
    • 1.基础概念
    • 2.如何学好数据结构
  • 二、复杂度
    • 1.复杂度
    • 2.时间复杂度
      • ①有限数的时间复杂度
      • ②函数的时间复杂度
      • ③二分查找时间复杂度
      • ④递归
      • 拓展练习题1:消失的数字
    • 3.空间复杂度
      • 拓展练习题2:旋转数组
      • 拓展练习题③数组,二级指针
      • 拓展练习题④移除元素

一、初识数据结构

1.基础概念

数据结构(Data Structure) 是计算机存储、组织数据的方式,指相互之间存在一种或多种特定关系的数据元素的集合。简单来说,数据结构就是在内存中管理数据。

相关概念拓展:
算法(Algorithm) 就是定义良好的计算过程,他取一个或一组的值为输入,并产生出一个或一组值作为输出。简单来说算法就是一系列的计算步骤,用来将输入数据转化成输出结果。简单来说,算法就是在磁盘中管理数据。

在内存与磁盘中管理数据的区别:
在内存中,

  • 数据存储速度比较快(相对磁盘而言)
  • 属于带电存储类型

相对应的,在磁盘中,

  • 数据存储速度比较慢(相对内存而言)
  • 属于不带电存储类型。

思考:带电与不带电存储对存储的影响是什么?
答:存储寿命
如果是需要带电存储,那么就需要不断电,那么也就意味这文件内容不能永久性存储;相应的,如果可以脱离电量进行存储,那么就可以永久性存储在硬件中(这里不考虑硬件寿命问题)。

2.如何学好数据结构

  • 画图
    在这里插入图片描述
  • 代码练习与思考
    在这里插入图片描述

二、复杂度

1.复杂度

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

元素个数的逐渐增大,复杂度的差异逐渐明显
在这里插入图片描述
复杂度包括两个方面:

  • 时间复杂度
  • 空间复杂度

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

  1. 用常数1取代运行时间中的所有加法常数。
  2. 在修改后的运行次数函数中,只保留最高阶项。
  3. 如果最高阶项存在且不是1,则去除与这个项目相乘的常数。得到的结果就是大O阶。
  4. 在实际中一般情况关注的是算法的最坏运行情况。

复杂度的意义何在?
用来衡量/决策比较某一种/多种实现方法的优劣
复杂度是准确的吗?
复杂度是粗略估计,对算法进行大致分“阶级”

2.时间复杂度

算法中的基本操作的执行次数,为算法的时间复杂度。

举例:

①有限数的时间复杂度

在这里插入图片描述

②函数的时间复杂度

在这里插入图片描述
注strchr:LINK

③二分查找时间复杂度

在这里插入图片描述
时间复杂度:O(logN)

④递归

在这里插入图片描述



在这里插入图片描述
在这里插入图片描述

拓展练习题1:消失的数字

消失的数字:LINK
在这里插入图片描述

在这里插入图片描述

int missingNumber(int* nums, int numsSize){// //思路二:先加起来然后减去,即可得到消失的数字
// int i = 0;
// int lose = 0;
// int sum = 0;
// //加上0到numsSize全部的数字
// for(i = 0;i<numsSize+1;i++)
// {
//     sum+=i;
// }
// //减去原数组0到numsSize的数字
// for(i = 0;i<numsSize;i++)
// {
//     sum-=nums[i];
// }
// //得到消失的数字
// lose = sum;
// return lose;//思路三:异或操作
int i = 0;
int lose = 0;
//异或正常的数组
for(i = 0;i<numsSize+1;i++)
{lose^=i;
}
//异或原来的数组
for(i = 0;i<numsSize;i++)
{lose^=nums[i];
}
//返回
return lose;
}

3.空间复杂度

为了实现某个功能额外开辟的空间。

需要注意的是:时间一去不复返,但是空间可以重复利用滴。

拓展练习题2:旋转数组

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>//旋转数组
void printArray(int arr[],int length)
{for (int i = 0; i < length; i++){printf("%d ", arr[i]);}printf("\n");
}//1.暴力求解
void test1(int arr[],int length,int k)
{while (k--){int temp = arr[length - 1];for (int i = length -1-1; i >= 0; i--){arr[i+1] = arr[i];}arr[0] = temp;}printArray(arr, length);
}void Swap(int arr[],int start,int end)
{while (start < end){int temp = arr[start];arr[start] = arr[end];arr[end] = temp;start++;end--;}}
//2.逆置法
void test2(int arr[], int length, int k)
{//1.首先逆置后半部分Swap(arr,length-k, length-1);printArray(arr, length);//2.其次逆置前半部分Swap(arr, 0, length - k - 1);printArray(arr, length);//3.整个数组进行逆置Swap(arr, 0, length - 1);printArray(arr, length);
}//3.空间换时间方法
void test3(int arr[], int length, int k)
{//开辟空间int* temp = (int*)malloc(sizeof(int) * length);if (temp == NULL){perror("malloc fail");exit(-1);}//拷贝值到新数组中去for (int i = 0,j = k; i <= length - k - 1; i++,j++){temp[j] = arr[i];}for (int i = length - k, j = 0; i <= length - 1; i++, j++){temp[j] = arr[i];}//拷贝回去for (int i = 0; i < length; i++){arr[i] = temp[i];}printArray(arr, length);
}int main()
{int k = 3;int arr[] = { 1,2,3,4,5,6,7 };//test1(arr, sizeof(arr) / sizeof(int), k);//test2(arr, sizeof(arr) / sizeof(int), k);test3(arr, sizeof(arr) / sizeof(int), k);return 0;
}

拓展练习题③数组,二级指针

在这里插入图片描述

拓展练习题④移除元素

原题链接:LINK
在这里插入图片描述

//三条思路
//1.传统的覆盖
//2.开新数组
//3.双指针
int removeElement(int* nums, int numsSize, int val) {int i = 0;int p1 = 0;//探路者int p2 = 0;//守家者for(i = 0;i<numsSize;i++){if(nums[p1]==val){p1++;}else{nums[p2++] = nums[p1++];}}return p2;
}
#if 1
/*解题思路:1. 设置一个变量count,用来记录nums中值等于val的元素的个数2. 遍历nums数组,对于每个元素进行如下操作:a. 如果num[i]等于val,说明值为val的元素出现了一次,count++b. 如果nums[i]不等于元素,将nums[i]往前搬移count个位置因为nums[i]元素之前出现过count个值等于val的元素,已经被删除了因此次数需要将nums[i]往前搬移3. 返回删除之后新数组中有效元素个数时间复杂度:O(N)   空间复杂度:O(1)*/
int removeElement(int* nums, int numsSize, int val){int count = 0;for(int i = 0; i < numsSize; ++i){if(nums[i] == val){count++;}else{nums[i-count] = nums[i];}}return numsSize - count;
}
#endif

EOF

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用MQTT.fx接入新版ONENet(24.4.8)

新版ONENet使用MQTT.fx 模拟接入 目录 新版ONENet使用MQTT.fx 模拟接入开始前的准备创建产品设备获取关键参数 计算签名使用MQTT.fx连接服务器数据流准备与上传数据流准备数据发送与接收 开始前的准备 创建产品 设备下载Token签名工具生成签名 创建产品设备 根据以下内容填写…

git生成ssh key并推送到远端仓库

ssh-keygen -t rsa -C "anarckkgmail.com"在用户文件夹中找到id_rsa.pub&#xff0c;把内容复制到gitea的配置里&#xff0c;然后直接用git推送就可以了

C语言第四十一弹---猜数字游戏

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 猜数字游戏 1、随机数生成 1.1、rand 1.2、srand 1.3、time 1.4、设置随机数的范围 2、猜数字游戏的分析和设计 2.1、猜数字游戏功能说明 2.2、猜数字游戏…

为什么大型语言模型都在使用 SwiGLU 作为激活函数?

如果你一直在关注大型语言模型的架构&#xff0c;你可能会在最新的模型和研究论文中看到“SwiGLU”这个词。SwiGLU可以说是在大语言模型中最常用到的激活函数&#xff0c;我们本篇文章就来对他进行详细的介绍。SwiGLU其实是2020年谷歌提出的激活函数&#xff0c;它结合了SWISH和…

【蓝桥杯嵌入式】第十三届省赛(第二场)

目录 0 前言 1 展示 1.1 源码 1.2 演示视频 1.3 题目展示 2 CubeMX配置(第十三届省赛第二场真题) 2.1 设置下载线 2.2 HSE时钟设置 2.3 时钟树配置 2.4 生成代码设置 2.5 USART1 2.5.1 基本配置 2.5.2 NVIC 2.5.3 DMA 2.6 TIM 2.6.1 TIM2 2.6.2 TIM4 2.6.3 …

百度富文本编辑器配置(vue3)

今天分享一下我做的项目里面的一个百度富文本的配置问题&#xff0c;安装配置流程以及如何解决的 1.首先是安装组件 # vue-ueditor-wrap v3 仅支持 Vue 3 npm i vue-ueditor-wrap3.x -S # or yarn add vue-ueditor-wrap3.x 2. 下载 UEditor UEditor 并不支持通过 npm 的方式…

FreeRTOS移植到标准库

源码下载 1&#xff1a;从官网获取freeRTOS源码 freeRTOS官网 2&#xff1a;FreeRtos源码文件阐述 3&#xff1a;移植FreeRtos源码 FreeRTOS移植步骤1&#xff1a;添加FreeRTOS源码&#xff0c;将FreeRTOS源码添加到基础工程&#xff0c;头文件等路径2&#xff1a;添加FreeR…

Taro打包生成不同目录

使用taro init创建taro项目时&#xff0c;taro默认打包目录是&#xff1a; /config/index.js outputRoot:dist默认的目录&#xff0c;编译不同平台代码时就会覆盖掉&#xff0c;为了达到多端同步调试的目的&#xff0c;这时需要修改默认生成目录了&#xff0c;通过查看官方文…

蓝桥杯练习系统(算法训练)ALGO-958 P0704回文数和质数

资源限制 内存限制&#xff1a;256.0MB C/C时间限制&#xff1a;1.0s Java时间限制&#xff1a;3.0s Python时间限制&#xff1a;5.0s 一个数如果从左往右读和从右往左读数字是完全相同的&#xff0c;则称这个数为回文数&#xff0c;比如898,1221,15651都是回文数。编写…

打包与发布iOS应用的完整指南

摘要 本文旨在指导开发者如何准备工作、打包和发布iOS应用。详细介绍了生成请求证书文件、生成APP开发证书及发布证书、生成APP ID、添加调试设备、生成描述文件等步骤。同时&#xff0c;结合案例演示和实际操作&#xff0c;帮助读者更好地理解和应用这些步骤。通过本文&#…

数据结构初阶:栈和队列

栈 栈的概念及结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。 进行数据插入和删除操作的一端 称为栈顶&#xff0c;另一端称为栈底。 栈中的数据元素遵守后进先出 LIFO &#xff08; Last In First Out &#xff09;的原则。…

JMeter+Ant+Jenkins构建接口报告(无人驾驶版)

展示结果&#xff1a; uc浏览器打开测试报告&#xff0c;绿色显示脚本结果 搭建操作步骤如下 1.jemter写好脚本 2.下载并配置ant环境变量&#xff1a;加上activation.jar、commons-lang3-3.8.1.jar、mail.jar 这3个包 mail.jar需要引用到jmeter 3.下载安装Jenkins 并进行构建…