01-数据结构概念(c++版本)

274 阅读5分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第9天,点击查看活动详情

数据结构就计算机组织和存储数据的方式,更详细的描述,数据结构是一种或多种具有特定关系的数据的组织方式和它们在计算机上的存储方式以及定义在改组数据上的一组操作

计算机解决问题的步骤

(1)从具体问题(原始数据)抽象出一个适当的数学模型。

(2)设计一个求解的该数据模型的算法。

(3)从某种计算机语言编写实现该算法的程序,并且进行调试,运行程序解决问题。

算法基本概念

数据

数据:所有被计算机存储,处理的对象。

数据元素:数据的基本单位,在程序当中作为一个整体而加以考虑和处理。

数据项:数据项组成了数据元素,是数据最小的不可以分割的标识单位。

举例:

数据:人

数据元素:{"name": "老王","age": 18}

数据项:name,age

数据逻辑结构

逻辑结构是根据逻辑关系进行划分的,所谓的逻辑关系就是指数据之间的关联方式或者临近关系

集合 元素间没有任何关联方式

线性结构 元素之间存在一对一的关系

树形结构 元素之间存在一对多关系

图结构 元素之间存在多对多关系

数据的存储结构

数据的逻辑关系在计算机当中的实现称为数据的存储结构(物理结构),一般情况下存储结构包括以下两个部分:

1、数据元素

2、元素之间的关联方式

存储结构的管理方式:

1、顺序存储:存储节点存放在一个连续的存储区里。利用节点在存储器中的相对位置来表示数据元素之间的逻辑关系。

2、链式存储:存储节点除了存储数据元素外,还包含指针,每个指针指向一个与本节点具有逻辑关系的节点。

3、索引存储:

4、散列存储:

算法及描述

运算的实现指的是该运算的算法。

算法是计算机科学的一个基本概念,也是程序设计的核心概念。

一个算法规定了求解给定问题所需要的处理步骤和执行顺序,使得给定问题可以在有限的时间内被求解。

算法分析

1、正确性:能正确实现预定功能,满足具体问题的需求。

2、易读性:易于阅读,理解和交流,便于调试、修改和扩充。

3、健壮性:即使输入非法数据,算法也能适当的做出反应或者进行处理,不会产生预料之外的指向结果。

4、时空性:指的是时间性能(指向效率)和空间性能(空间效率?执行成本),时间性能指的是计算量,空间性能指的是存储量。

时间复杂度

时间复杂度是在整个算法运算过程当中合理的选择一种或者几种操作作为"基本操作",对给定的输入,确定算法执行了多少次基本操作,可以讲基本操作的次数作为这个算法的时间复杂度。

以阶乘为案例:

求1!+2!+3!+...n!

思路1

#include <iostream>
​
int face(int n){
    int i,j,temp,s;
    s = 0;
    for(i=1;i<=n;i++){
       temp=1;
       for(j = 1;j <=i;j++){
          temp = temp*j;
       }
       s = s+temp;
    }
    return s;
}
​
int main(){
    using namespace std;
    int r = face(10);
    cout << r << endl;
    return 0;
}
​

思路2

#include <iostream>
​
int face(int n){
    int i,j,temp,s;
    s = 0; temp=1;
    for(i=1;i<=n;i++){
       temp = temp * i;
       s = s+temp;
    }
    return s;
}
​
int main(){
    using namespace std;
    int r = face(10);
    cout << r << endl;
    return 0;
}

显而易见:

思路1外层循环n次,内层,每次循环n次,所以时间复杂度就是O(n*n)

思路2循环n次,所以思路2的时间复杂度O(n)

空间复杂度

空间复杂度就是一个算法耗费的存储空间,他也是问题规模n的函数,一个算法在执行期间所需要的存储空间包括三部分:

(1)程序代码占用的空间

(2)输入数据占用的空间

(3)辅助变量占用的空间

但是在算法执行的过程当中,输入数据占用的空间是固定的,程序代码占用的空间不能形成量级,辅助变量占用空间才是由算法决定的,所以,一般的空间复杂度考虑的是辅助变量占用的空间。

比如:

将一个n=100的整数数组进行倒置,设计两种方式:

(1)从数组两端依次进行数据的对调

void fi(int a[],int n){
    //a100个数据的数组
    int i,temp;
    for(i=0;i<n/2-1;i++){
       temp=a[i];
       a[i] = a[n-1-i];
       a[n-1-i] = temp;
    }
}

(2)先倒叙读到一个新的数组当中,然后再次传入原来的数组

void fi1(int a[], int n){
    int i,b[100];
    for(i = 0; i <= n-1; i++){
        b[i] = a[n-1-i];
    };
    for(i = 0; i <=n-1; i++){
        a[i] = b[i];
    };
}
​

问题开始前,其实就可以感觉到第二种会耗费空间,那么仔细分析,算法1当中需要2个整形变量,i和temp,与问题的规模无关,所以空间复杂度为O(1),但是第二种算法当中i和第一种算法的空间复杂度一样,但是b是一个随着规模变化而变化的空间,所以空间复杂度为O(n)