问题描述
程序=数据结构+算法
自从沃斯提出这个伟大的公式以来,为广大的编程爱好者的前行指明了方向,同时也因为抽象程度过高,导致很多人无法深入的理解这个公式的含义。
本文将以1到100求和来揭示其背后的道理。
什么是数据结构
什么是数据结构?
数据结构这个短语可以拆分为“数据+结构”这两个词,接下来将分别介绍这两个词的含义。
(1)什么是数据?
数据指的是客观事物的符号表示,是所有能输入到计算机中并被计算机程序处理的符号的总称。如数学计算中经常用到的整数和实数,word文本编辑器中经常用到的字符串,美图秀秀等软件处理的图形、图像,还有绘声绘影等软件处理的声音、动画等,这些都是输入到计算机且能够被word、美图秀秀、绘声绘影等计算机程序处理的都称之为数据。
(2)什么是结构?
结构一词平时大家生活中接触最多的一类可能是被称之为公司的“组织结构图”,如下所示:
这就是最常见的结构图,在这张图里面,不仅有数据如董事长、总经理、行政总监等之类的字符串,而且还非常清晰的表达了这些数据之间的层级关系。
如果这张图没有结构只有一些字符串数据,则图中的这些字符串是杂乱无章的,当数据有了结构以后,才会出现上面的非常清晰的公司组织结构关系。
因此结构可以理解为是数据的某种关系,那如何抽象、归纳总结现实世界中的这种数据有哪些关系呢?现实生活中,这种数据之间的关系,主要有四种,分别是:
从上面两个问题的分析,可以得出所谓数据结构包含了两个方面的含义:一是数据,二是数据之间的关系。
什么是算法
算法指的是解决某类问题的有限长的操作步骤,那算法和数据结构之间是什么关系呢?
一般情况下,不同的数据结构决定了不同的算法,下面将通过1到100求和的实例来揭示这二者之间的关系。
1到100求和这个问题中涉及到的数据非常明显,那就是1,2,···,100这一百个整数,这些整数之间可能存在哪些关系呢?
根据前面的分析,可以得到其存在的关系主要有四种:
(1) 集合关系
100个整数之间没有明显的前后关系,只是堆积在一个集合里面,这种数据结构如何实现求和呢?
由于数据之间无任何关系,因此只有定义100个变量来保存100个实数,然后再依次添加每一个整数。
int a1 = 1;
int a2 = 2;
···
int a100 = 100;
int sum = a1 + a2 + ··· + a100;
(2)线性关系
线性关系体现了这100个整数不再像上面的集合关系那样杂乱无章了,而是存在一定的组织结构,这种关系最大的特点是每个元素最多只有一个前驱和后继。当数据有了这种关系后,其求和计算会带来哪些变化呢?
程序中要想体现这种数据关系,最好的数据类型就是选择数组来存储这些整数。
int a[100] = {1,2,···,100};
int sum = 0;
for( int i = 0; i < 100; i++){
sum += a[i];
}
因此可以看到数组是体现线性关系的最好的表示方法,有了数组很快就可以写出求和算法。
采用线性关系来描述数据的最大的好处就是,只要给定任意一个元素的内存地址,就可以找到其他所有元素的地址进而得到所有元素的值。而集合关系则做不到这一点,因为每个元素之间没有关系,不能根据一个元素的地址去计算其他元素的地址。
(3)树关系
当这一百个整数之间具备了上面的这种树形关系的时候,其求和的思路则是通过访问这棵树中所有的元素的值,访问的方式主要有:层次遍历、先序、中序和后序等。
按照上面的方式依次遍历树中每一个节点的值,然后累加到sum变量中实现求和。
(4)图关系
当100个整数具有上面这种图的关系的时候,则需要通过深度优先、广度优先等算法来遍历图中的每一个元素实现求和。
综上所述,可以看到采用不同的数据结构来描述问题,其求和的算法会有所不同。而解决1到100求和问题的核心就在于两个方面:
一是你选择什么样的数据结构来描述1到100这些整数;
二是你选择什么样的算法来访问这些数据、执行什么样的计算。
这两个方面正是体现了”程序=数据结构+算法“的核心理念。
结语
本文介绍了什么是数据结构,什么是算法,通过1到100求和实例,采用不同的数据结构来求解问题,感受数据结构和算法之间的关系,最后进一步强调了“程序=数据结构+算法”的理念。