想吃开发程序这块蛋糕,就看谁的数据结构与算法运用的好

231 阅读8分钟

请牢记:程序=数据结构+算法

1. 数据结构发展史

  1. 起源:

1968年美国唐•欧•克努特教授开创了数据结构的最初体系;

他所著的《计算机程序设计技巧》第一卷《基本算法》是第一本较系统地阐述数据的逻辑结构和存储结构与其操作的著作。

数据结构的发展经历三个阶段:无结构阶段,结构化阶段和面向对象阶段。

  1. 无结构阶段

40~60年代间,程序设计技术以机器语言和汇编语言为主,程序处理的是存粹的数值,数据之间的关系主要是以来数学公式或者数学模型,此时数据结构概念并没有明确形成。

3)结构化阶段

60~80年代,计算机开始广泛应用于非数值处理领域,数据表示成为程序设计的重要问题,人们认识到程序设计规范化的重要性,提出了程序结构模块化,并开始注意数据表示与操作的结构化。

数据结构及抽象数据类型就是在这种情况下形成的,随着数据规模的加大,程序的设计越来越依附于数据结构的设计,此时数据结构开始广泛普及。

此间也有非常多的数据结构相关的文献产出,最为著名的是图灵奖获得者沃斯的一个著名公式:程序=数据结构+算法。

4)面向对象阶段

80年代初期到现在,随着计算机不断普及,计算机性能以及需求不断增加,面向对象的程序设计被逐步提出,在对象的世界中 ,程序设计中大大减少了重复设计的部分,数据结构在这个阶段逐渐变得丰富,大量的封装类出现,减少了程序设计者的负担,数据结构因此变得更加友好。

2.何为算法

请你回答一下如何使用计算机C语言编程计算1到100的和(1+2+3+……+100),相信大多数人会直接给出以下答案:

#include <stdio.h>
in main() {
    int ans=0,i;
    for(i=1;i<=100;i++){
        ans+=i;
    }
    printf("%d",ans);
    return 0;
}

这几乎是计算机中最为简单的程序了。

但是,这样去完成这个功能真的好么?早在300年前的小学生高斯在课堂上被老师要求去计算这个结果,在同班同学还在手推写结果的时候,高斯早就已经做完了,他利用等差数列求和的算法,轻易打败了同班同学。

相关代码如下:

#include <stdio.h>
int main() {
    int ans=(1+100)*100/2;
    printf("%d",ans);
    return 0;
}

相比第一份答案,我们进行了100次的运算,才得出我们想要的结果,而对于第二份答案,我们仅进行了1次运算就得到了想要的结果,而在实际中计算机的计算远远不止这点计算量,以此如果我们去计算1到1000000的和呢?使用了等差数列还是一步算好,而这就是算法的魅力。

算法基础

1. 算法的特性

  1. 输入输出

算法具有零个或者多个输入,同时,算法具有至少一个的输出。

对于在屏幕上打印”Hello World”一样,你可以不需要有任何的输入,直接输出得到结果即可,而对于一个没有输出的算法,没有任何意义。

  1. 确定性

算法的每一步都具有确定的含义,无二义性。任何条件下,算法只有唯一的一条执行路径,即对于相同的输入只能得到相同的输出。

请注意,如果算法的目的是产生一个随机数字,每一次运行产生了不同的结果,看上去好像违反了算法确定性原则,但计算机产生随机数亦是使用一种(或多种)算法解决,以线性同余产生随机数为例,其利用了CPU时间的不同产生的不同的结果,当CPU的时间完全一样的时候依旧会产生相同结果,只不过人类无法察觉到如此精确的时间区别。

3)有穷性

一个算法总是需要(输入合法的情况下)在有限的步骤结束,即每个算法需要在有穷的时间内完成。

这是算法与程序的最主要的区别,程序可以无限制循环的执行下去。对于此,你可以理解为一个算法必须要有一个”边界“,即使一个算法需要计算机连续运算50年,但依旧是有穷的,只不过这个算法意义已经不是很大了。

4)可行性

一个算法是可以被执行的,即算法中的每个操作都可以通过已经实现的基本运算执行有限的次数完成。

尽管在目前计算机解存在着没有实现成功的极为复杂的算法,但是并不能说的上是无法实现,只不过是受到现在的工具和人类的大脑限制了,这属于理论研究的范围。

2. 算法设计要求

  1. 正确性

正确性(Correctness)指的是该算法能够满足预先指定的功能与性能的需求,即能够得到正确答案。

其大致可以分为以下四点:

a)该算法中不含任何语法错误。

b)程序对于几组输入数据能够得到满足需求的结果。

c)程序对于非法的输入也能够得到满足需求说明的结果(如抛出异常)。

d)程序对于精心挑选的严苛数据依旧能够产生满足需求的结果。

2)健壮性

健壮性(Robustness)指的是当输入数据不合法时,算法也能做出相关的处理,而不是产生不可预计的效果。

3)可读性

可读性(Readability)指的是算法是可以阅读,理解和交流的。

4)耗时低,占用空间少

运行时间(Running time)与占用空间(Storage space)概念,在设计算法时,我们总是希望能够更少的使用时间和空间达成我们的目标。

我们算法与数据结构的研究的重点就是为了让程序运行快,占用空间低。

1. 基本概念和术语

1)数据

数据(Data)是信息的载体,是可以被计算机识别,存储并加工处理的描述客观事物的信息符号的总称。数据不仅仅包括了整形,浮点数等数值类型,还包括了字符甚至声音,视频,图像等非数值的类型。

2)数据元素

数据元素(Data Element)是描述数据的基本单位,也被称为记录。一个数据元素有若干个数据项组成。

如禽类,鸡鸭都属于禽类的数据元素。

3)数据项

数据项(Data Item)是描述数据的最小单位,其可以分为组合项和原子项:

a)组合项

如果数据元素可以再度分割,则每一个独立处理单元就是数据项,数据元素就是数据项的集合。

b)原子项

如果数据元素不能再度分割,则每一个独立处理的单元就是原子项。

如日期2019年4月25日就是一个组合项,其表示日期,但如果单独拿25日这个数据出来观测,这就是一个原子项,因为其不可以再分割。

4)数据对象

数据对象(Data Object)是性质相同的一类数据元素的集合,是数据的一个子集。数据对象可以是有限的,也可以是无限的。

5)数据结构

数据结构(Data Structures)主要是指数据和关系的集合,数据指的是计算机中需要处理的数据,而关系指的是这些数据相关的前后逻辑,这些逻辑与计算机储存的位置无关,其主要包含以下四大逻辑结构。

2. 四大逻辑结构(Logic Structure)

  1. 集合结构

集合结构(Set Structure)中所有数据元素除了同属于一个集合外,并无其他关系。

如图:

  1. 线性结构

线性结构(Linear Structure)指的是数据元素之间存在“一对一的关系”

如图:

  1. 树形结构

树形结构(Tree Structure)指的是数据元素之间存在“一对多”的层次关系。

如图:

  1. 图形结构

图形结构(Graphic Structure,也称:网状结构)指的是数据元素之间存在“多对多的关系”(注:此时的“多对多”中的多表示,至少有一个)

图示:

3.数据类型

  1. 数据类型

数据类型(Data Type)是高级程序设计语言中的概念,是数据的取值范围和对数进行操作的总和。数据类型规定了程序中对象的特性。程序中的每一个变量,常量或者表达式都属于一种数据类型。

  1. 抽象数据类型

抽象数据类型(Abstract Data Type,ADT)只是一个数学模型以及定义在模型上的一组操作。通常是对数据的抽象,定义了数据的取值范围以及对数据操作的集合。

抽象数据类型的特征是实现与操作分离,从而实现封装。

我们拿《魔塔》做比方:我们给予主角打,跳,移动的基本操作,这些操作就可以看作是抽象数据类型,这一组操作就属于一个模型,这组抽象的数据类型可以在《魔塔》这个游戏环境中使用。

数据结构与算法是作为一名程序员必不可少的,既然你已经看到了这里,说明你是一个对编程感兴趣的人,那么如何学习数据结构与算法呢,不是去网上看个视频就会立马懂,编程是个需要动手的事情。

如果你想要更好的学习数据结构与算法,作者给你提供一套完整的学习资料,避免你去网上寻找,