首页 > 编程语言 >数据结构与算法

数据结构与算法

时间:2024-04-03 23:32:30浏览次数:11  
标签:复杂度 元素 算法 操作 数据结构 数据

1.1数据结构的研究内容

程序=数据结构+算法   ———程序的本质

 

例1:图书管理系统

操作对象:若干行数据记录

操作算法:查询、插入、删除、修改等

操作对象之间的关系:线性关系

数据结构:线性数据结构、线性表

例2:文件系统的结构图

如图可以看到,这是一个典型的树型结构问题,数据与数据成一对多的关系,是一种典型的非线性关系——树型结构

例3:地图导航寻找最短路径

 

操作对象:各地点及路的信息

算法:设置信号灯,求各可通行的路的集合

关系:非线性关系、网状结构

综上:

数据结构是一门研究非数值计算的程序设计中计算机的操作对象以及它们之间的关系和操作的学科。

1.2.1数据、数据元素、数据项和数据对象

1.数据(Data)

是输入计算机且能被计算机处理的各种符号的集合,这个集合包括数值型的数据(整数、实数等)和非数值型的数据(文字、图像等)

        信号的载体

        是对客观事实符号化的表示

        能够被计算机识别、存储和加工

2.数据元素(Data element)

数据的基本单位,在计算机程序中通常作为一个整体进行考虑和处理。

也可以被称为元素、记录、结点(树)、顶点(图)。

一个数据元素可由若干数据项组成。

3.数据项(Data Item)

构成数据元素的最小单位。

数据、数据元素、数据项之间的关系:

数据 > 数据元素 > 数据项

4.数据对象(Data Object)

是性质相同的数据元素的集合,是数据的一个子集。

例:整数的数据对象是集合N={0,+1,-1,+2,-2......}

数据元素与数据对象

数据元素——组成数据的基本单位

        与数据的关系:是集合的个体

数据对象——性质相同的数据元素的集合

        与数据的关系:集合的子集

1.2.2数据结构(Data Structure)

(1)数据元素不是孤立存在的,它们之间存在着某种关系,数据元素相互之间的关系称为结构

(2)是指相互之间存在一种或多种特定关系的数据元素集合

(3)也可以理解为数据结构是带结构的数据元素的集合

1.内容

(1)数据元素之间的逻辑关系,也称为逻辑结构。

(2)数据元素及其关系在计算机内存中的表示(映像),称为数据的物理结构或存储结构。

(3)数据的运算和实现,即对数据元素可以施加的操作以及这些操作在相应的存储结构上的实现。

2.两个层次

(1)逻辑结构

描述数据元素之间的逻辑关系

与数据存储无关,独立于计算机

是从具体问题抽象出来的数学模型

种类

(2)存储结构

数据元素及其关系在计算机存储器的结构

是数据结构在计算机中的表示

四种基本存储结构

①顺序存储

用一组连续的存储单元依次存储数据元素,数据元素之间的逻辑关系由元素的存储位置来表示。

例:C语言中通常用数组来实现顺序存储。

②链式存储结构

用一组任意的存储单元存储数据元素,数据元素之间的逻辑关系用指针来表示。

例:C语言中通常用指针来实现。

③索引存储结构

在存储结点信息的同时,还建立附加的索引表。

索引表中每一项称为一个索引项。

索引项的一般形式(关键字、地址)

关键字是能唯一标识一个结点的那些数据项。

稠密索引:每个结点在索引表中都有一个索引项。

稀疏索引:一组结点在索引表中只对应一个索引项。

④散列存储结构

根据结点关键字直接计算出该结点的存储地址。

关系

存储结构是逻辑关系的映像与元素本身的映像。

逻辑结构是数据结构的抽象,存储结构是数据结构的实现。

逻辑结构与存储结构共同建立了数据元素之间的结构关系。

1.2.3数据类型和抽象数据类型

程序中出现的变量、常量、表达式,我们都需要明确说明它们所属的数据类型。

例:int、char等基本数据类型

        数组、结构、共用体、枚举等构造数据类型

        typedef,自己定义数据类型

数据类型作用:(1)约束变量或常量的取值范围;(2)约束变量或常量操作。

数据类型(Data Type)

定义:是一组性质相同的值的集合,以及定义于这个值集合上的一组操作的总称。

        数据类型=值的集合+值集合上的一组操作

抽象数据类型(Abstract Data Type,ADT)

是指一个数学模型以及定义在此数学模型上的一组操作。

·由用户定义,从问题抽象出数据模型(逻辑结构)

·定义在数据模型上的一组抽象运算(相关操作)

·不考虑计算机内的具体存储结构与运算的具体实现算法

形式定义

可用(D、S、P)三元组表示

        D——数据对象

        S——D上的关系集

        P——对D的操作

定义格式

ADT 抽象数据类型名{

        数据对象:<数据对象的定义>

        数据关系:<数据关系的定义>

        基本操作:<基本操作的定义>

} ADT 抽象数据类型名

基本操作的定义格式:

基本操作名 (参数表)

初始条件:(初始条件描述)

操作结果:(操作结果描述)

说明:

参数表:赋值参数,只为操作提供输入值。

               引用参数 以&开头,可以提供输入值和返回操作结果。

初始条件:描述操作之前数据结构和参数应满足的条件,若不满足,操作失败,返回相应出错信息。当初始条件为空,省略。

操作结果:说明操作正常之后,数据结构的变化状况和应返回的结果。

例:Circle的定义

ADT 抽象数据类型名{                                        ADT Circle{

        Data                                                                数据对象:D={r,x,y|r,x,y均为实数}

          数据对象的定义                                            数据关系:R={<r,x,y>|r是半径,<x,y>圆心坐标}

          数据元素之间逻辑关系定义                          基本操作:

        Operation                                                       Circle(&C,r,x,y)

          操作1                                                                        操作结果:构造一个圆

                初始条件                                                double Area(C)

                操作结果描述                                                      初始条件:圆已存在。

          操作 2                                                                       操作结果:计算面积。

                ......                                                        double Circumference(C)

          操作n                                                                        初始条件:圆已存在。

                ......                                                                     操作结果:计算周长。

} ADT 抽象数据类型名                                       }

C语言描述,用已有的数据类型定义描述存储结构,用函数描述操作。

例:用C实现抽象数据类型

typedef struct
{
    float realpart;                    /*实部*/
    float imagpart;                    /*虚部*/
}Complex;

void assign (Complex * A, float real , float imag);    /*赋值*/
void add (Complex * A, float real , float imag);    /*A+B*/
void minus (Complex * A, float real , float imag);    /*A-B*/
void multiply (Complex * A, float real , float imag);    /*A*B*/
void divide (Complex * A, float real , float imag);    /*A/B*/

void assign (Complex * A, float real , float imag)
{
    A->realpart = real;                /*实部赋值*/
    A->imagpart = image;                /*虚部赋值*/
}

void add (Complex *c, Complex A, Complex B)    /* c = A + B */
{
    c->realpart = A.realpart + B.realpart;        /*实部相加*/
    c->imagpart = A.imagpart + B.imagpart;        /*虚部相加*/
}

注:Complex是自己定义的结构体类型

        带*:指针变量,指向Complex类型的指针

        不带*:普通变量。

1.3算法和算法分析

1.3.1算法的定义

对待特定问题求解方法和步骤的一种描述,它是指令的有限序列。其中每个指令表示一个或多个操作。简而言之,算法是解决问题的方法和步骤

1.3.2算法与程序

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

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

                                        程序=数据结构+算法

                                   数据结构通过算法实现操作 

                                   算法根据数据结构设计程序

1.算法的五个特性

2.算法设计的要求

正确性、可读性、健壮性、高效性

一个算法主要考虑算法的效率

1.时间效率:指算法所耗费的时间。

2.空间效率:算法执行过程中所耗费的存储空间。

时间效率和空间效率有时候是矛盾的。

3.算法时间效率的度量

该算法编制的程序在计算机上执行所消耗的时间

方法:事后统计、事前统计(一般用它)

事前分析法

        算法运行时间=一个简单操作所需时间*简单操作次数

即:算法中每条语句的执行时间之和

        算法运行时间=\sum每条语句的执行次数(语句频度)*该语句执行一次所需的时间

由于每条语句执行一次的时间由机器本身软硬件环境决定,与算法无关,所以,假设执行每条语句所需时间均为单位时间,此时算法运行时间为语句频度之和。

例:连个n*n矩阵相乘的算法可描述为

for(i=1;i<n;i++)                                    //n+1次
    for(j=1;j<n;j++)                                //n(n+1)次
    {
        c[i][j]=0;                                  //n*n次
        for(k=0;k<n;k++)                            //n*n*(n+1)次
            c[i][j]=c[i][j]+a[i][k]*b[k][j];        //n*n*n次
    }

时间消耗T(n)=2n^{3}+3n^{2}+2n+1 

4.时间复杂度

有某个辅助函数f(n),n\rightarrow \infty,T(n),f(n)极限值为不等于零的常数,f(n)是T(n)的同数量级函数。记作T(n)=O(f(n)),O(f(n))称为算法渐进时间复杂度,简称时间复杂度。

        定义:算法中基本语句重复执行的次数是问题规模n的某个函数f(n),记作 T(n)=O(f(n)),表示随着n增大,算法执行时间增长率和f(n)的增长率相同,称渐进时间复杂度。

5.分析算法时间复杂度的基本方法

1.找出语句频度最大的那条语句作为基本语句

2.计算基本语句的频度得到问题规模n的某个函数f(n)

3.取其数量级用符号“O”表示

例1

for(i=1;i<=n;i++)
    for(j=1;j<=i;j++)
        for(k=1;k<=j;k++)
            x=x+1;

解:(1)语句频度最大的语句:x=x+1;

       (2)语句频度=\sum_{i=1}^{n}\sum_{j=1}^{i}\sum_{k=1}^{j}1=\sum_{i=1}^{n}\sum_{j=1}^{i}j=\sum_{i=1}^{n}\frac{i(i+1)}{2} =\frac{n(n+1)(n+2)}{6}

       (3)时间复杂度O(n^3)

例2

i=1;
while(i<=n)
    i=i*2;

 解:先找出语句频度最大的语句:i=i*2;

        关键找出执行次数x与n的关系,并表示成n的函数

        若循环1次:i=1*2=2;

        若循环2次:i=2*2=2^2;

        若循环3次:i=2*2*2=2^3;

        若循环x次:i=2^x.

        i<=n,

        \therefore2^x=n,

        \thereforex<=\log_{2}n

        即:f(n)\leq \log_{2}n,取最大值f(n)\leq \log_{2}n

        \therefore该程序的时间复杂度T(n)=O(\log_{2}n)

注:有些情况下,算法中基本操作重复执行的次数还随问题的输入数据集不同而不同

例:顺序查找

for(i=0;i<n;i++)
    if(a[i]==e)
        return i+1;    //找到,返回是第几个元素
return 0;

最好情况:1次;最坏情况:n次。平均时间复杂度O(n)。

一般情况下考虑最坏情况下的时间复杂度,以保证算法的运行时间不会比它更长。

对于复杂的算法,利用加法法则和乘法法则,计算时间复杂度 :

a)加法规则

T(n)=T1(n)+T2(n)=O(f(n))+O(g(n))=O(max(f(n),g(n)))

b)乘法规则

T(n)=T1(n)*T2(n)=O(f(n))*O(g(n))=O(f(n)*g(n))

6.算法时间效率的比较

时间复杂度按数量级递增顺序:

复杂度低——————————————————————————————————>复杂度高

7.渐进空间复杂度

空间复杂度:算法所需存储空间的度量,

                记作:S(n)=O(f(n)), n为问题的规模

算法要占据的空间:

(1)算法本身要占据的空间,输入/输出,指令,常数,变量等。

(2)算法要使用的辅助空间

例:将一维数组a中的n个数逆序存放到原数组中。

算法1:S(n)=O(1)

for(i=0;i<n/2;i++)
{
    t=a[i];
    a[i]=a[n-i-1];
    a[n-i-1]=t;
}

算法2:S(n)=O(n) 

for(i=0;i<n;i++)
    b[i]=a[n-i-1];
for(i=0;i<n;i++)
    a[i]=b[i];

1.4设计好算法的过程

 

标签:复杂度,元素,算法,操作,数据结构,数据
From: https://blog.csdn.net/m0_74794884/article/details/137300328

相关文章

  • 稀碎从零算法笔记Day37-LeetCode:所有可能的真二叉树
    今天的每日一题,感觉理解的还不够深,有待加深理解题型:树、分治、递归链接:894.所有可能的真二叉树-力扣(LeetCode)来源:LeetCode题目描述给你一个整数 n ,请你找出所有可能含 n 个节点的 真二叉树 ,并以列表形式返回。答案中每棵树的每个节点都必须符合 Node.val==0 ......
  • 稀碎从零算法笔记Day36-LeetCode:H指数
    有点绕的一个题,题目描述的有点奇怪(可以看下英文?)题型:数组、模拟链接:274.H指数-力扣(LeetCode)来源:LeetCode题目描述给你一个整数数组 citations ,其中 citations[i] 表示研究者的第 i 篇论文被引用的次数。计算并返回该研究者的 h 指数。根据维基百科上 h指数......
  • 编写一个算法来计算 n 阶乘中尾随零的数量
    算法:编写一个算法来计算n阶乘中尾随零的数量解题思路:当n过大时,从1遍历至n,那么会超时,发现以下规律:n!=1*2*3*4*(1*5)*...*(2*5)*...*(3*5)...每隔5个数就会出现一个5,因此我们只需要通过n/5来计算存在存在多少个5个数,那么就对应的存在多少个......
  • 树模型系列——1、决策树算法简介
    1.决策树简介决策树(decisiontree)是机器学习中一种非参数的监督学习算法,可用于分类与回归。其中分类决策树是基于变量特征对离散变量目标值进行分类的,可用于二分类或多分类;回归决策树是基于变量特征对连续变量目标值进行分类的,可用于连续变量的回归拟合。从上图看,可知树形结构......
  • 数据结构——从入门到入土
    链表的建立及遍历:分为如下几步:声明链表这种结构,比如:点击查看代码typedefstructnode*listlink;//定义一个指针类型名称,使指针变量能像其他变量那样声明,而不需要在每个指针变量前加*typedefstructnude(){intdata;structlistlinknext;}LNode;//声明......
  • Java最短路径算法知识点(含面试大厂题和源码)
    最短路径算法是计算机科学和图论中的核心问题之一,它旨在找到从一个顶点到另一个顶点或在所有顶点之间的最短路径。这个问题在多种实际应用中都非常重要,如网络路由、交通规划、社交网络分析等。以下是一些与最短路径算法相关的知识点:Dijkstra算法:由荷兰计算机科学家艾兹......
  • 数据结构与算法分析实验3 [进阶]通过链表实现多项式加法和乘法
    文章目录大致内容介绍多项式加法代码一览头文件Poly.h内容如下:实现文件Poly.cpp内容如下:初始化增加元素删除元素功能函数遍历函数清除销毁打印多项式向多项式内插入一个元素源文件main.cpp内容如下:实现效果:多项式乘法实现方法:在Poly.h中添加声明:在Poly.cpp中添加实现:在......
  • 代码随想录算法训练营三刷day44 | 动态规划之 完全背包 518. 零钱兑换 II 377. 组合总
    三刷day44完全背包基础知识问题描述举个栗子518.零钱兑换II1.确定dp数组以及下标的含义2.确定递推公式3.dp数组如何初始化4.确定遍历顺序5.举例推导dp数组377.组合总和Ⅳ1.确定dp数组以及下标的含义2.确定递推公式3.dp数组如何初始化4.确定遍历顺序5.举例来推导dp......
  • 算法之查找
    1、顺序查找:packagecom.arithmetic.search;//顺序查找//sequentialSearch方法接收一个整数数组和一个目标元素作为参数,并使用顺序查找的方式在数组中查找目标元素。//它通过循环遍历数组元素,逐个与目标元素比较,如果找到了目标元素,则返回其索引位置。//如果遍历完整个数......
  • 数据结构——队列(包括循环队列)——Java版
    目录队列介绍:基本概念:应用:Java实现示例:循环队列的Java实现:队列介绍:队列(Queue)是一种常见的数据结构,它按照先进先出(FIFO,First-In-First-Out)的原则管理数据。在现实生活中,队列的概念很容易理解,就像是排队等待服务的人群一样。在计算机科学领域,队列同样扮演着重要的角色,在......