数据结构与算法原理基本关系和原理

Posted 一只写诗的程序员

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构与算法原理基本关系和原理相关的知识,希望对你有一定的参考价值。

在计算机科学中,数据结构(英语:data structure)是计算机中存储、组织数据的方式。---来自维基百科

那我们计算机中有哪些常见的数据结构了?数据结构与算法又有什么关系?数据结构和计算机底层联系是否非常紧密?基于这些问题,同时为了方便的理解数据结构,我们尽量使用高级一些的语言(python、Java、C++、C)虽然数据结构与堆栈、甚至用汇编中的概念会更深入理解一点,但实际上我们实践操作是不需要这么深入了解到这么细致的。(当然这里我会将汇编和各种高级语言混合在一起进行操作,这样的话,理解起来就轻松一点,强调一点,写博客喜欢从原理性的东西说起,所以要是有大佬精通这一块的跳过,或者指出错误,(* ̄) ̄))

 

首先我们假设在python中写了如下程序(这里会将python 中的程序用汇编解释):

import  numpy as np

#小明给了你50块钱,小红给了你7块...

getMoney=[50,7,20,30,80]

#你开始数一下一共给了多少钱给你

s=sum(getMoney)

#打印钱数

print(s)

以上程序在高级语言中的数据结构很简单

1.将数据存到数组中

2.进行求和存到一个变量中

那计算机中操作怎样将数据存到内存并运算的了,数据在内存中怎样保存的了?

我们现在一步步来,首先我将如上步骤翻译成汇编语言如下(看不懂汇编没关系,后面再说这个数据的结构的原理和特性):

运行在x86上的汇编环境

.386

.model flat,stdcall

.stack 4096

ExitProcess PROTO, dwExitCode:dword

 

.data

getMoney DWORD 32h,7h,14h,1Eh,50h

DWORD ?

 

.code

main proc

 

       mov  ecx,LENGTHOF getMoney          数组的中元素个数用于循环中断

       mov  eax,0                                    初始化总和0

L1:                                                          开始循环

       add  eax,[edi]                               放入寄存器,cup加法器进行累加操作

       add  edi,TYPE getMoney             指针移动一个这个数据类型的字节

       loop L1                                            ; ECX = 0 时这个循环结束

       mov s,eax                                       将cpu中寄存器的值写入到s内存中

       invoke ExitProcess,0

main endp

end main

这里的汇编语言是直接运行在intel x86环境(64位不容易观看)我们直接用vs2015打开(在校企的的那段时间学的是C#,但是这个工具编写汇编也是很友好和强大的),现在一步步讲解那段代码的一个运行过程。

汇编运行过程是:汇编语言-编译成机器语言(即0-1用来驱动计算机电子元件)-通过链接器-cpu执行这段程序。

大家可以看到首先,我们的程序会向CPU发送指令(不同的计算机厂商,会有不同的内存指令操作)申请一段内存,这段内存段没有程序使用,并是空闲的,并将数据写入到内存中。

这里用的是16进制表示法,实际在计算机硬件中是二进制高低电平表示,但是一般我们书写表示方法都习惯用16位进制表示。

数据结构与算法原理基本关系和原理

所以我们需要知道数组大小,和这个数据每个所占用的字节(所以一般高级语言显示或者隐式的声明这个数据类型,就是想知道这个数据在内存中占用多少字节)用于循环累加,这里的累加使用的是硬件上的加法器如下格式:

数据结构与算法原理基本关系和原理

我们可以看到如下图中执行的过程

数据结构与算法原理基本关系和原理

很明显最后CPU加法器运算出来的结果和我们在python中输出的结果是一致的:

数据结构与算法原理基本关系和原理

数据结构与算法原理基本关系和原理

以下是我们常见的数据结构:

数据结构与算法原理基本关系和原理

我们可以举一个数据结构影响效率的例子。

如下:

数据结构与算法原理基本关系和原理

同样的字符串相加的操作前者比后者慢了上百倍,导致这个的原因是因为字符串的数据结构是堆栈,而字符生成器使用的数据结构是链表,这样说可能很抽象,我这边画一个图形就好理解了。

第一个使用字符相加的时候,每次相加就重新申请一个可以容纳该字符加上已有字符的内存空间:

数据结构与算法原理基本关系和原理

数据结构与算法原理基本关系和原理

从效率上将第二个是非常高的。

除了数据结构外,算法(实际上算法就是解决问题明确而有限的步骤,不要想的有多高大上)也在程序中对效率影响很高,这里我直接用python举一个例子(这个例子是1+2+3…+100000 算出结果):

import  numpy as np

import time

sum=0

i=100000

s_k=time.time()

while i>0: #n*c1

    sum=sum+#n*c2

    i = i - 1  # n*c3

print(time.time()-s_k)

print(sum)

s_k=time.time()

sum=(1+100000)*100000/2 #1*c1

print(time.time()-s_k)

print(sum)

如上程序我们严格按照一般算法RAM模型指令代价

第一个累积函数执行的这几条语句所需的指令代价为:

S1=n*c1+n*c2+n*c3  (这里的n=1000,c1、c2、c3为每条语句执行的代价常量---计算机使用时钟震荡一般是固定的,我们这里不考虑内存访问层次需要的时间)

提取公因式

S1=n(c1+c2+c3)  很明显消耗时间是线性的

第二个相加之和执行语句所需要的代价为:

S2=c1

从该模型理论上来讲S2耗时应该来说是非常短的,我们实际运行一下:

那算法和数据结构又怎样联系了,事实上我们知道qq空间中的评论这种数据像一颗树如下:

我们常规的数据库是关系型数据库,这样存放评论信息也可以做到评论与评论和回复之间相关联。

但是我们要进行用户相关性计算的时候,除了考虑相似度算法,还需要考虑合理的数据结构,这样用于分层或者别的计算时,算法可以不仅可以节省指令运算的时间,同时取数据,存数据的时间或者空间也大大节省,这样程序在性能上会有飞速的提升。

所以以上回答了所有问题,接下来写的文章大多是与数据结构和算法相关的,这样不仅仅对自己深入理解,也可以和大家讨论。


以上是关于数据结构与算法原理基本关系和原理的主要内容,如果未能解决你的问题,请参考以下文章

随机森林(RF)的原理

数据库系统原理之SQL与关系数据库基本操作

Knn算法原理

数据库系统原理(第四章:SQL与关系数据库基本操作 )

数据库系统原理之关系代数

操作系统基本原理