数据结构与算法概念

数据结构小白入门

数据结构指一组相互之间存在一种或多种特定关系的数据元素的集合,
当我们需要在计算机中存储这些数据时,还涉及到数据的,组织方式,在计算机中的存储方式,以及定义在该数据上的一组操作;

  • 一组数据相互之间有某种关系
  • 组织方式
  • 存储方式
  • 以及可对其进行的一组操作
理解:

我们学习的最终目的是要在计算机中存储一组数据,但是不得不先考虑数据的组织方式,在计算机中的存储方式,以及可以对这些数据进行的一组操作,当然了既然是一组数据必然表明了这写数据之间是存在想换的关联关系的;关系可能还会有多种;

例如:

一组数据:12345

组织方式:从小到大

存储方式:可使用线性存储结构

操作:要取出最大的一个

数据结构研究方向

问题:

  • 机外处理
  • 处理要求

建模:

  • 逻辑结构
  • 基本运算

实现:

  • 存储结构
  • 算法

基本术语

数据(Data):

? 所有能被计算机处理的符号的集合

数据元素(DataElement):

? 是数据集合中的一个 个体,即数据的基本单位

数据项(DataItem):

? 数据元素常常可分为若干个数据项,数据项是数据具有意义的最小单位

组织数据的三个层次:

数据(表)->数据元素(行)->数据项(字段)

实际问题中的数据成为原始数据

逻辑结构(LogicalStructure)

? 数据元素之间的结构关系,如从小到大/一对一/一对多

物理结构(PhysicalStructure)

? 也会叫做存储结构,指数据在计算机内的表示,逻辑结构在计算机中的具体实现

逻辑结构

常见的逻辑结构如下:

集合:

数据元素属于同一个集合,表示为R{}; 数据之间不存在特定关系

组织结构松散,任意两节点之间都没有邻接关系

线性:

除了起始节点d1和终端阶段dn外,每个节点都有一个前驱和一个后继,表示为R={d1,d2...dn},数据之间存在前后顺序关系

各节点按逻辑关系排列,形成一条‘链‘

树状:

每个元素最多有一个前驱,可以有多个后继,表示为(D,{R}),就像一个树干长了多个树枝

具备分支,层次特性,上层节点可以和下层度哦哦哦个节点相邻接,但是下层节点只能和一个上层节点邻接

图状:

任何两个元素之间都可以相邻接,表示为(D,{R})

注意:

逻辑结构

  • 与元素本身的形式,内容,无关
  • 元素的相对位置,无关
  • 与包含的节点个数,无关

存储结构

存储结构由 存储节点(每个存储节点存放一个数据元素)节点之间的逻辑关系共同组成

反过来说,一个完整的存储结构必须可以存储数据元素,以及元素之间的逻辑关系

存储结构分类 (缺图)

  • 顺序存储

    使用索引(相对起始位置)来表示数据的逻辑结构,数据被存储在一组连续的存储单元中

    特点:

    • 需预先分配长度,
    • 插入和删除慢,需要移动其他元素
    • 存取数据快捷,属于随机存储结构(可通过索引直接访问任意位置数据)
  • 链式存储

    借助元素地址指针表示数据的逻辑结构,每个元素都会包含指向下一个元素的指针

    这种结构需要在节点上附加一个指针项,指出后继节点的位置,即每个节点存储单元包含两个部分:[数据项,指针项]

    特点:

    • 动态分配内容,不需要预先分配内存
    • 插入删除快捷,不需要移动其他元素
    • 非随机存取结构(获取数据必须遍历前面的所有节点)
  • 索引存储(Map是否属于索引结构 很疑惑?)

    借助索引表来指示数据元素的存储位置

    索引表中包含了所有数据元素的地址,查询索引表能够快速的定位到需要的数据

    特点:

    • 索引是一份独立于实际存放数据,的数据结构(就像书的目录都在正文前面)
    • 索引需要占用额外的存储空间
    • 当实际数据发生改变时需要重建索引
    • 查询数据快
    • 插入修改,删除慢
  • 散列存储(哈希表)

    通过散列函数计算得出元素的位置

    特点:

    • 在散列函数不变时,相同数据会得出相同的位置
    • 存入顺序和取出顺序通常不一致
    • 无法完成随机存取(指定获取某个元素)

顺序和链式是最基本的也是最常用的存储结构,需要重点掌握,包括各自的优缺点,使用场景等

链式存储结构可实现树结构(逻辑结构)

运算

运算指的是某种逻辑结构上可以进行的操作;

运算分为两类:

  • 加工型运算

    会改变原逻辑结构的内容,顺序,个数等的操作

  • 引用型运行

    与加工型运算相反

常见运算:

建立,查找,读取,插入,删除

加工型:建立,插入,删除

引用型:读取,查找

算法

算法字面意思,计算方法;

算法规定了求解给定类型问题所需的所有处理步骤以及执行顺序,使得问题能在优先时间内机械的求解,一个算法就是对特定问题求解步骤的一种描述,再具体一点,算法是一段有穷的指令序列;算法必须能使用某种语言描述;

例如:

计算1到5的和 ,这个需求,如何来实现,第一步做什么,第二步做什么,整个计算步骤和执行顺序统称为算法,如果最终能够在有限的步骤下求出正确的和,那这就是一个合格的算法;

算法的特点:

  • 有穷性

    算法必须在执行有穷步后结束

  • 确定性

    算法的每一个步骤都必须是明确定义的,

  • 可行性

    算法中的每一步都是可以通过已实现的操作来完成的

  • 输入

    一个算法具备0或多个输入

  • 输出

    一个算法有一个或多个输出,它们与输入有着特定的关系

算法与程序的区别,算法只是一种描述,可以使用任何语言,但是通常不能直接被计算机运行,而程序则是算法的具体实现,使用某种计算机语言;

算法设计应满足的要求

  • 正确性:对于合法的输入产生符合要求的输出
  • 易读性:算法应该尽可能易读,便于交流,这也是保证正确性的前提(注释可提高易读性)
  • 健壮性:当输入非法数据时,算法可作出适当反应而不至于崩溃(例如输出错误原因);
  • 时空性:指的是算法的时间复杂度和空间复杂度,算法分析主要也是分析算法的时间复杂度和空间复杂的,其目的是提高算法的效率;

算法分析

解决同一问题的算法可能有多种,我们希望从中选出最优的算法,效率高的,占用空间小的,为此我们就需要对算法进行评估和分析;

通常评估算法根据两个度量

  • 时间复杂度:算法运行完成所需的总步数(标准操作),通常是问题规模的函数
  • 空间复杂度:算法执行时所占用的存储空间,通常是问题规模的函数

确定算法的计算量

  • 合理选择一种或几种操作作为‘标准操作‘,无特殊说明默认以赋值操作作为标准操作;
  • 确定算法共执行多少次标准操作,并将此次数规定为算法的计算量
  • 以算法在所有时输入下的计算量最大值作为算法的最坏情况时间复杂度
  • 以算法在所有时输入下的计算量最小值作为算法的最好情况时间复杂度
  • 以算法在所有时输入下的计算量平均值作为算法的平均情况时间复杂度
  • 最坏/平均情况时间复杂度都可作为时间复杂度,通常以最坏情况衡量;

注意:时间复杂度通常以量级来衡量,也就是说不需要精确的计算到底执行了几步,而是得出其计算量的数量级即可,并忽略常数,因为当数量级足够大时,常数对于计算量的影响可以忽略不计;

如: (n-1)(n-2) 数量级为 n^2

时间复杂度使用大O表示,如O(1)

案例:

1.
void aFunction(){
    int c = 10 + 20;
    int d = c * c;
        printf(d);
}

上列算法若以赋值运算作为标准操作,则该算法的计算量为2,其时间复杂度记为O(1),为什么是O(1)呢,是因为2是一个常数,常数对于函数的增长影响并不大,所以计算量为常数时表示为O(1),按照这种方式,即使计算量为2000,同样记为O(1),称为常数

2.
void bFunction(int n){
  for(int i = 0;i < n;i++){ // n
    int c = 2 * i;// 1
    int d = 3 * i;// 2
  }
}

此时函数的循环次数由未知数n来决定,循环体内计算量为2,当n是一个自然数时,函数的计算量等于(n)(2),此时时间复杂度为O(n),无论用常数2对n进行加减乘除对于n的指数都没有影响,当n足够大时,内部的2次计算量可以忽略,所以记为O(n),称为线性阶

更粗陋的度量方法是函数体包含一层循环时记为O(n)

3.
void bFunction(int n){
  for(int i = 0;i < n;i++){
      for(int j = 0;j < i;j++){
      }
  }
}

外层循环次数为n,内层循环次数随着n的增长而增长且最大值为n-1次,那么整个函数的计算量为(n)(n-1),常数可以忽略,所以时间复杂度记为O(n^2) ,称为平方阶

粗陋的方法是有两层嵌套循环,且循环次数都随着n的增长而增长,所以是O(n^2),以此类推,但是要注意下面这种情况

4.
void bFunction(int n){
  for(int i = 0;i < n;i++){
      for(int j = 0;j < 3;j++){
      }
  }
}

此时内层循环的循环次数是固定(常数)所以不会影响计算量的数量级,时间复杂度记为O(n)

5.
void bFunction(int n){
  for(int i = 3;i < n;){
      i *= 3;
  }
}

此时函循环次数会随着3循环体中的常数3的的变化而变化,我们可以用对数来表示,

假设循环次数为s,循环条件可表示为 s = 3^s < n;(即i本身为3,其次幂会不断的增长,但结果要小于n)

当然这里有个条件是i的初值必须和每次乘等的值相同,形成次幂的增长;

用对数表示为s = log3n,时间复杂度记为O(log3n),常数可以忽略,所以最后是O(logn)称之为对数阶

对数阶的数量级小于线性阶,因为若n的值相同,对数阶计算量必然小于线性阶

6.
void bFunction(int n){
 for(int i = 0;i < n;i++){
     for(int j = 0;j < n;j++){
         for(int k = 0;k < n;k++){
       }
     }
 }
}

上述算法时间复杂度为O(n^3),3为常数,对应着循环的嵌套层数;也可以用O(n^C)表示,称为多项式阶

7.
void bFunction(int n){
  int num = 2;
  for(int i = 0;i < n;){ //O(n)
        num *= 2;
  }
  for (int j = 0;j<num;j++){ //O(n)
  }
}

上述函数输入的参数n将作为循环次数的指数,假设循环次数为s, s = 2^n,那么时间复杂度为O(2^n),

称之为指数阶,可记为O(C^n)

8.
void bFunction(int n)
{
    for(int i=0;i<n;i++){
          for(int j=0;j<n;j++){
          }
    }   

      for(int i=0;i<n;i++){
      }
}

对于顺序运行的算法,总时间复杂度等于算法中最大时间复杂度,即O(n^2)

9.
void bFunction(int n)
{
  if(n % 2 ==0){
    for(int i=0;i<n;i++){
          for(int j=0;j<n;j++){
          }
    }
  }else{
      for(int i=0;i<n;i++){
      }
  }
}

对于具备分支结构的算法,总时间复杂度等于算法中时间复杂度最大路径的复杂度,即O(n^2)

时间复杂度大小顺序

常数 < 对数阶 < 线性阶 < 平方阶 < 多项式阶 < 指数阶

O(1) < O(logn) < O(n) < O(n^2) < O(n^C) < O(C^n)

个人观点,若有错误敬请指出,谢谢!

原文地址:https://www.cnblogs.com/yangyuanhu/p/12267404.html

时间: 2024-11-07 11:16:25

数据结构与算法概念的相关文章

数据结构与算法概念解析

数据之间的相互关系称为逻辑结构.通常分为四类基本结构: 集合   结构中的数据元素除了同属于一种类型外,别无其它关系. 线性结构    结构中的数据元素之间存在一对一的关系. 树型结构       结构中的数据元素之间存在一对多的关系. 图状结构或网状结构   结构中的数据元素之间存在多对多的关系. 数据结构在计算机中有两种不同的存储方法: 顺序存储结构:用数据元素在存储器中的相对位置来表示数据元素之间的逻辑关系. 链式存储结构:在每一个数据元素中增加一个存放地址的指针,用此指针来表示数据元素之

数据结构之算法概念

数据结构:就好比一个大型图书馆,如何在书架上摆放图书,要考虑两个操作: 1.新书怎么插入 2.怎么找到指定的某本书 解决问题方法的效率,跟数据结构的组织方式有关,跟空间的利用率有关,跟算法的巧妙程度有关 所以什么是数据结构: 数据对象在计算机中的组织方式 1.逻辑结构 2.物理存储结构 数据对象必定与一系列加在其上的操作相关联 完成这些操作所用的方法就是算法 一个算法的好坏,主要看两方面, 时间复杂度:根据算法写成的程序在执行时耗费时间的长度,这个长度往往和输入数据的规模有关 空间复杂度:根据算

数据结构与算法 基于c语言篇

学习数据结构与算法走向深蓝之路 第一章:数据结构与算法概念型 数据结构:数据之间的相互关系,即是数据的组织形式. 基本组成:{ 数据:信息的载体 数据元素:数据基本单位: } 其结构形式有四种: 1,集合结构  2,线性结构.   3,树形结构  4,图形结构 在计算机中的存储有量中形式: 顺序存储(数组形式)和非顺序存储(链式存储结构) 1.1抽象数据类型:指的是数据模型或者定义在数据模型上的一组操作 (D,R,P){ D是数据对象, R是D上的关系集 P是对D进行的操作} ListInser

java数据结构和算法

目录 (1)数据结构与算法概念解析 (2)数据结构之数组 (3)数据结构之栈 (4)数据结构之队列 (5)数据结构之链表 (6)数据结构之二叉树 (7)数据结构之霍夫曼树 (8)数据结构之红黑树(一)--基础分析 (9)数据结构之红黑树(二)--插入操作 (10)数据结构之红黑树(三)--删除操作 (11)排序算法(一)--冒泡排序及改进 (12)排序算法(二)--选择排序及改进 (13)排序算法(三)--插入排序及改进 (14)排序算法(四)--归并排序与递归 (15)排序算法(五)--快速排

python数据结构与算法 36 树的基本概念

树 学习目标 理解什么是树及使用方法 学会使用树实现映射 用列表实现树 用类和引用实现树 用递归实现树 用堆实现优先队列 树的例子 前面我们学习过栈和队列这类线性数据结构,并且体验过递归,现在我们学习另一种通用数据结构,叫做树.树在计算机科学中应用广泛,象操作系统.图形学.数据库系统.网络等都要用到树.树和他们在自然界中的表哥--植物树--非常相似,树也有根,有分枝,有叶子.不同之处是,数据结构的树,根在顶上,而叶子在底部. 在开始学习之前,我们来研究几个普通的例子.第一个是生物学上的分级树.图

数据结构与算法 1 :基本概念,线性表顺序结构,线性表链式结构,单向循环链表

[本文谢绝转载] <大纲> 数据结构: 起源: 基本概念 数据结构指数据对象中数据元素之间的关系  逻辑结构 物理结构 数据的运算 算法概念: 概念 算法和数据结构区别 算法特性 算法效率的度量 大O表示法 时间复杂度案例 空间复杂度 时间换空间案例 1)线性表: 线性表初步认识: 线性表顺序结构案例 线性表顺序结构案例,单文件版 线性表的优缺点 企业级线性表链式存储案例:C语言实现 企业级线性表链式存储案例:C语言实现 单文件版 企业级线性表链式存储案例,我的练习  线性表链式存储优点缺点

[数据结构和算法]算法基本概念

算法基本概念: 算法:用来对数据的操作作描述,是对问题求解的步骤的描述.是一系列将输入转为输出的计算步骤 算法复杂度:分为时间复杂度和空间复杂度时间复杂度:算法中所有语句的频度之和用T(n)表示,记为T(n) = O(n) 常见时间复杂度递增次序:常数 O(1) , 对数阶O(log2^n) , 线性阶O(n) , 线形对数阶O(nlog2^n),平方阶O(n^2),立方阶O(n^3),指数阶O(2^n),O(n!),O(n^n)当n值增大,算法时间复杂度即变大,执行效率变低 最坏时间复杂度:最

java数据结构与算法之树基本概念及二叉树(BinaryTree)的设计与实现

[版权申明]未经博主同意,不允许转载!(请尊重原创,博主保留追究权) http://blog.csdn.net/javazejian/article/details/53727333 出自[zejian的博客] 关联文章: java数据结构与算法之顺序表与链表设计与实现分析 java数据结构与算法之双链表设计与实现 java数据结构与算法之改良顺序表与双链表类似ArrayList和LinkedList(带Iterator迭代器与fast-fail机制) java数据结构与算法之栈(Stack)设

数据结构与算法的基本概念

整理一下数据结构和算法的基本概念: 有序数组是按关键字升序或降序排列的,可以使用二分法查找 有序数组的查找速度比无序数组快 有序数组在插入操作中由于所有靠后的数据都需要移动以腾开空间,使用速度较慢 有序数组和无序数组的删除操作都很慢,因为数据项必须向前移动来填补已删除的数据项的洞 有序数组使用于查找频繁的数据库,插入和删除较为频繁的时候,无法高效工作 无序数组插入块,查找慢 有序数组插入慢,查找快 数组创建之后大小就固定了. 数组中每一项占用一个特定的位置,这个位置可以用一个下标号直接访问 数组