• 数据结构和算法简介


    1.基本概念

    —数据:数据是描述客观事物的数值、字符以及能输入机器且能被处理的各种符号集合
    例如除了表示人的姓名、身高、体重的字符、数字是数据,人的照片、指纹、三维模型、语言指令等也都是数据。数据项、数据元素、数据对象都是数据
    (1)数据项具有原子性,是不可分割的最小数据单位
    (2)数据元素:是数据的基本单位,是数据集合的个体,通常由若干数据项组成,在计算机程序中通常作为一个整体来进行处理。
    (3)数据对象是性质相同的的数据元素的集合,是数据的子集
    在这里插入图片描述

    2.数据结构

    2.1基本概念

    (1)数据结构是指相互之间存在的一种或多种特定关系的数据元素的集合,是组织并存储数据以便能够有效使用的一种专门格式,它用来反映一个数据的内部构成,即一个数据由哪些成分数据构成,以什么方式构成,是什么结构。
    (2)表示一组数据元素及其相互关系的数据结构具有两种不同的表现形式:
    ①一种是数据结构的逻辑层面,即数据的逻辑结构
    ②另一种是存在于计算机世界的物理层面,即数据的存储结构
    数据结构=逻辑结构+存储结构
    数据结构=逻辑结构+存储猎狗+(在存储结构上的)运算/操作
    在这里插入图片描述

    2.2 逻辑结构

    逻辑结构分类1

    (1)线性结构:有且只有一个开始节点和一个终端节点,并且所有节点都最多只有一个直接前驱和一个直接后继。线性表就是一个典型的线性结构,它有四个基本特征:
    ①集合中必存在唯一的一个“第一个元素”;
    ②集合中必存在唯一的一个“最后的元素”
    ③除第一元素之外,其他元素均为唯一的“前驱”;
    ④除最后元素之外,其他数据元素均有唯一的“后继”;
    (4)非线性结构的逻辑特征是一个结点元素可能对应多个直接前驱和多个直接后继
    常见的非线性结构有:树、图等

    2.逻辑结构分类2:

    (1)集合结构:就是集合中所学的集合。集合有三个特征:
    ①确定性(集合中的元素必须是确定的)
    ②唯一性(集合中的元素互不相同)
    ③无序性(集合中的元素没有先后之分)
    (2)线性结构:数据元素之间存在着“一对一”的线性关系的数据结构
    (3)树状结构:除了第一个数据元素以外每个元素有且仅有一个直接前驱元素,但是可以有多个直接后继元素
    (4)网络结构:每个数据元素可以有多个直接前驱元素,也可以有多个直接后继元素。特点是元素之间是多对多的联系

    2.3 存储结构

    数据的存储结构主要包括数据元素本身的存储以及数据元素之间关系表示,是数据的逻辑结构在计算机中的表示。常见的存储结构有顺序存储,链式存储,索引存储,以及散列存储。
    (1)顺序存储结构:把逻辑上相邻的节点存储在物理位置上相邻的存储单元中,结点之间的逻辑关系由存储单元的邻接关系来体现。由此得到的存储结构为顺序存储结构。(数据元素的存储对应于一块连续的存储空间,数据元素之间的前驱和后继关系通过数据元素在存储器中的相对位置来反映),
    ①优点
    节省存储空间,因为分配给数据的存储单元全用存放结点的数据,结点之间的逻辑关系没有占用额外的存储空间。采用这种方法时,可实现对结点的随机存取,即每一个结点对应一个序号,由该序号可以计算出来结点的存储地址。
    ②缺点
    插入和删除操作需要移动元素,效率较低
    在这里插入图片描述

    (2)链式存储结构:数据元素的存储对应的是不连续的存储空间,每个存储节点对应一个需要存储的数据元素。每个结点是由数据域和指针域组成。元素之间的逻辑关系通过存储节点之间的链接关系反映出来
    特点:
    ①比顺序存储结构的存储密度小( 每个节点都由数据域和指针域组成,所以相同空间内假设全存满的话顺序比链式存储的更多)
    ②逻辑上相邻的节点物理上不必相邻
    ③插入、删除灵活(不必移动节点,只需改变节点中的指针)
    在这里插入图片描述
    (3)索引存储结构:除建立结点信息外,还建立附加的索引表来标识结点的地址。比如图书、字典的目录
    (4)散列存储结构:根据结点的关键字直接计算出该结点的存储地址
    一种神奇的结构,添加、查询速度块。
    注意:
    (1)同一逻辑结构可以对应多种存储结构
    (2)同样的运算,在不同的存储结构中,其实现过程是不同的
    在这里插入图片描述

    3.算法

    1.什么是算法?

    算法就是计算机解题的过程

    2.算法的5个特性:

    (1)输入:一个算法应以待解决的问题的信息作为输入
    (2)输出:输入对应指令集处理后得到的信息
    (3)可行性:算法是可行的,即算法中的每一条指令都是可以实现的,均能在有限的时间内完成
    (4)有穷性:算法执行的指令的个数是有限的,每个指令又是在有限时间内完成的,因此整个算法也是在有限时间内可以结束的
    (5)确定性:算法对于特定的合法输入,其对应的输出是唯一的。即当算法从一个特定输入开始,多次执行同一指令集结果总是相同的

    3.什么是复杂度?

    (1)时间复杂度是指执行算法所需要的计算工作量。
    ①一个算法中的语句执行次数称为语句频度或时间频度,表示为T(n),n表示问题的规模。
    时间复杂度就是时间频度去掉低阶项和首项常数。
    ②最坏情况下的时间复杂度称为最坏时间复杂度。一般不特别说明,讨论的时间复杂度均是最坏情况下的时间复杂度。
    ③在最坏情况下的时间复杂度为T(n)=O(n),它表示对于任何输入实例,该算法的运行时间不可能大于O(n)
    (2)空间复杂度是指执行这个算法所需要的内存空间

    3.1 时间复杂度的计算

    (1)找出算法中的基本语句;
    算法中执行次数最多的那条语句就是基本语句,通常是最内层循环的循环体
    (2)计算基本语句的执行次数的数量级;
    ①只需计算基本语句执行次数的数量级,这就意味着只要保证基本语句执行次数的函数中的最高次幂正确即可
    ②可以忽略所有最低次幂和最高次幂的系数。这样能够简化算法分析,并且使注意力集中在最重要的一点上:即增长率
    (3)用大O记号表示算法的时间性能
    将基本语句执行次数的数量级放入大O记号中

    3.2时间复杂度举例

    1)①一个简单语句的时间复杂度为O(1)
    int count = 0;100个简单语句的时间复杂度也为O(1)
       因为100是常数,不是趋向无穷大的n
    (3)一个循环的时间复杂度为O(n)
    int n=8;count=0;
    for(int i=1;i<=n;i++)
    	count++;
    (4)时间复杂度为O(log2n)的循环语句
    int n=8,count=0
    for(int i=1;i<=n;i*=2)
    	count++;
    (5)时间复杂度为O()的二重循环体
    int n=8;count=0;
    for(int i=1;i<=n;i++)
    	for(int j=1;j<=n;j++)
    		count++;	
    (6)时间复杂度为O(nlog2n)的二重循环体
    int n=8;count =0;
    for(int i=1;i<=n;i*=2)
    	for(int j=1;j<=n;j++)
    	 count++;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    在这里插入图片描述

    3.3空间复杂度

    (1)算法的存储量包括:
    ①程序本身所占空间
    ②输入数据所占空间
    ③辅助变量所占空间
    (2)输入数据所占空间只取绝于问题本身,和算法无关,则只需要分析除输入和程序之外的辅助变量所占额外空间
    (3)空间复杂度是对一个算法在运行过程中临时占用的存储空间大小的量度,一般也作为问题规模n的函数,以数量级形式给出,记作:S(n)=O(g(n))
    (4)例子
    ①例子①

    int fun(int n){
    	int i,j,k,s;
    	s=0;
    	for(i=0;i<=n;i++)
    		for(j=0;j<=i;j++)
    			for(k=0;k<=j;k++)
    			s++;
    	return(s);		
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    分析:i,j,k,s各占一个空间,总共4个空间,即S(n)=O(1)
    例子②(递归)
    void fun(int a[],int n;int k)
    // 数组a共有n个元素
    { int i;
    if(k == n-1)
    for(i=0;i printf(“%d\n”,a[i]);//执行n次
    else
    {for(i=k;i a[i]=a[i]+i*i;//执行n-k次
    fun(a,n,k+1);
    }
    }
    此属于递归算法,每次调用本身都要分配空间,fun(a,n,0)的空间复杂度为O(n)

  • 相关阅读:
    1310. 数三角形
    MySQL笔记:MySQL求最近一段时间
    为什么 Lettuce 会带来更长的故障时间?
    jarsigner和apksigner对apk/aab签名
    制作路由器openwrt安装及配置
    六种最常见的软件供应链攻击
    聚观早报 | 慧聪网经营困难宣布停工;推特工程副总投奔 Meta
    力扣第51题 N 皇后 c++ 难~ 回溯题
    【自然语言处理(NLP)】基于BiLSTM+CRF的事件抽取
    算法--贪心算法的应用
  • 原文地址:https://blog.csdn.net/y516369/article/details/126205752