(第二章)知识点:数据结构与算法

1、引入

凭借一句话获得图灵奖的Pascal之父——Nicklaus Wirth,让他获得图灵奖的这句话就是他提出的著名公式:“算法+数据结构=程序”。

2、算法

解决问题的方法(广义)

(1)算法的特点:

1)有效性;

2)可行性;

  对于浮点数(科学计数法),考察这样的问题:

  3e18 + 3e-18

  这个运算在很多计算机系统中,是不可行的。

3)有限步骤;

4)至少有一个输出;

5)稳定性(可重现性)。

解决问题的方法绝对没有唯一性(没有标准答案);但是,解决问题的方法之间是可以进行比较,比较的是性能等方面。在讨论某种算法性能时会发现,没有任何一个算法能成为“完美”的!任何算法都有优、缺点(世界上没有单面的硬币)。

(2)衡量算法性能指标

衡量算法性能指标有两个:1)时间复杂度;2)空间复杂度。

 

1)时间复杂度:问题规模和解决该问题所执行的基本指令的次数(量)的函数关系。

 

eg1.关于数据逆置的方法:

有一组数据,要求逆置这些数据。或者说,有数组int  ar[10],并赋初值,要求编程实现对该数组元素的逆置。

方法1:

准备临时数组int  temp[10];从后向前地将arr数组的元素,存储到temp数组中:

for(i  =  0;  i  <  10;  i++){

     temp[i]  =  arr[10-i-1];

}

分析:ar[0]  ->  temp[9]

          ar[1]  ->  temp[8]

          ar[2]  ->  temp[7]

          ar[3]  ->  temp[6]

          ar[4]  ->  temp[5]

          ar[5]  ->  temp[4]

          ar[6]  ->  temp[3]

          ar[7]  ->  temp[2]

          ar[8]  ->  temp[1]

          ar[9]  ->  temp[0]

 

          ar[i]  ->  temp[10-1-i]

 

然后,再将逆置了的,但是存储于temp数组中的数据,再放回到arr数组:

for(i  =  0;  i  <  10;  i++){

     ar[i]  =  temp[i];

}

 

总共需要2倍的10次运算;若原数组中的数据个数是n个,那么,需要的基本操作次数是2*n次,可以写成:O(2n)

(当n趋向于无穷大时,其与O(n)同阶无穷大),于是,可以说,这个算法的时间复杂度是:O(n)。

另外,这个算法需要n个元素的临时空间,因此,空间复杂度为O(n)。

 

方法2:

将数组中,按中轴对称的元素“对调”,也可以实现逆置:

int  tmp;

for(i  =  0;  i  <  10/2;  i++){

     tmp  =  ar[i];

     ar[i]  =  ar[10-i-1];

    ar[10-i-1]  =  tmp;

}

上述操作需要10/2次循环(基本操作);若原数组中的数据个数是n个,那么,其时间复杂度是:O(n/2);空间复杂度为O(1)

(这个O(1)的意思是,辅助空间的大小,与问题规模(就是数组数据个数)无关)。

见博客:https://blog.csdn.net/weixin_42072280/article/details/82954088

 

eg2.课堂小练习:要求计算n以内的正整数之和,假设n在10万到1亿之间(不考虑int取值范围溢出问题)。

方法1;

int i;

int sum = 0;

for(i = 0; i < n; i++)

     sum += i;

printf(“%d\n”, sum);

上面的程序的时间复杂度是O(n)。

 

方法2:

printf(“%d\n”, (1+n)*n/2);

这段具有相同功能的算法,时间复杂度是O(1)。

 

对于时间复杂度的基本计算规则:

时间复杂度主要体现在循环的循环次数;

多重嵌套循环,时间复杂度是各层循环的循环次数之积!

并列多个循环,时间复杂度是各个循环的循环次数之和!

具体的说,要进行“变量跟踪”才能真正的搞清楚时间复杂度问题。

 

eg3.

for(a = 0; a < 100; a++)

     for(b = 0; b < 100; b++)

         for(c = 0; c < 100; c++)

                …

很简单,时间复杂度为O(n^3)

 

eg4.

for(a = 0; a < 100; a++)

      for(b = a+1; b < 100-a; b++)

              …

分析(变量跟踪):

当a为0时,内层循环:for(b = 1; b < 100; b++),即,99次;

当a为1时,内层循环:for(b = 1+1; b < 100-1; b++),即,99-2次;

当a为2时,内层循环:for(b = 1+2; b < 100-2; b++),即,99-4次;

当a为3时,内层循环:for(b = 1+3; b < 100-3; b++),即,99-6次;

当a为49时,内层循环:for(b = 1+49; b < 100-49; b++),即,1次;

共50轮;即,总循环次数是:1+3+5+ … + 99=>O((n/2)^2)=>O(n^2)

3、数据结构

(1)数据结构的要素:

数据结构有三个要素:

1)数据;

2)数据间关系(又称数据结构);

3)数据关系上的运算(操作、算子)。

(2)逻辑结构和物理结构

https://www.cnblogs.com/tonglingliangyong/p/3944979.html

a.逻辑结构

数据元素之间的相互联系方式称为数据的逻辑结构 。数据的逻辑结构是对数据元素之间逻辑关系的描述,它可以用一个数据元素的集合和定义在此集合上的若干关系来表示。数据的逻辑结构经常被简称为数据结构。

按照数据的逻辑结构来分,有两种形式:

1)线性结构:除第一个和最后一个数据元素外,每个数据元素有且只有一个前驱元素和一个后继元素(数据与数据之间是一对一关系)。

2)非线性结构:会有零个或多个前驱元素和零个或多个后继元素(数据与数据之间是一对多关系或多对多关系)。

数据的逻辑结构是从逻辑关系角度观察数据,它与数据的存储无关,是独立于计算机的。

b.物理结构

数据元素在计算机中的存储表示方式称为数据的(内存)存储结构 ,也称物理结构。任何需要计算机进行管理和处理的数据元素都必须首先按某种方式存储在计算机中,数据存储结构能正确地表示出数据元素间的逻辑关系。

按照数据的存储结构来分,有两种类型:

1)顺序存储结构:把数据元素存储在一块连续地址空间的内存中,其特点是逻辑上相邻的数据元素在物理上(即内存存储位置上)也相邻,数据间的逻辑关系表现在数据元素的存储位置关系上。

(内存的连续存储/访问的空间申请/释放机制;(数组))

2)链式存储结构:关键是使用节点,节点是由数据元素域与指针域组合的一个整体,指针将相互关联的节点衔接起来。其特点是逻辑上相邻的元素在物理上不一定相邻,数据间的逻辑关系表现在节点的衔接关系上。

(内存的非连续存储/访问的空间申请/释放机制;(链表))

而数据的存储结构是逻辑结构在计算机内存中的实现,它是计算机处理的逻辑。

c.逻辑结构与物理结构的关系

逻辑结构需要用物理结构最终“实现”;

 

                               

上图表明了逻辑结构与物理结构之间的“实现”关系。

 

 

eg.1)查找一个数据,线性存储结构可以使用折半查找  最差情况时间复杂度为O(logn) log是以2为底  这里关键在于“连续存储”支持“随机访问”,又称“下标访问”;log(2_10) log以2为底10的对数=3表示:在有10个数据组成的数组中查找一个数据,最多只需要找3次

     2)但是非线性存储结构(链式结构)只能使用线性查找或顺序查找  平均时间复杂度为O(n/2) => O(n)

 

     从上述这个例子可知:数据结构的选取,将直接影响到算法的性能。

 

d.逻辑非线性结构用线性存储结构实现的

约瑟夫环

 

下面还有一些 没有写 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安安csdn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值