收藏 分享(赏)

《计算机导论》 introduction of computer science》.ppt

上传人:无敌 文档编号:929438 上传时间:2018-05-03 格式:PPT 页数:45 大小:402.50KB
下载 相关 举报
《计算机导论》 introduction of computer science》.ppt_第1页
第1页 / 共45页
《计算机导论》 introduction of computer science》.ppt_第2页
第2页 / 共45页
《计算机导论》 introduction of computer science》.ppt_第3页
第3页 / 共45页
《计算机导论》 introduction of computer science》.ppt_第4页
第4页 / 共45页
《计算机导论》 introduction of computer science》.ppt_第5页
第5页 / 共45页
点击查看更多>>
资源描述

1、计算机导论 Introduction of Computer Science,School of Information EngineeringZhejiang Forestry College,第6章 算法与数据结构,6.1 算法概述6.2 经典排序算法6.3 算法策略6.4 数据结构概述6.5 线性表6.6 树和图,6.1 算法概述,6.1算法概述6.2 经典排序算法6.3 算法策略6.4 数据结构概述6.5 线性表6.6 树和图,6.1算法概述(定义),计算机解题一般可分解成若干操作步骤,通常把对特定问题的求解步骤的描述称为算法。程序可以看作是用计算机语言描述的算法。,6.1算法概述(特

2、性),算法的五个重要特性 有穷性:一个算法必须保证执行有限步后结束;确定性:算法的每一步骤必须有确切的定义; 可行性:算法原则上能够精确地运行,且人们用笔和纸做有限次运算后即可完成。输入:一个算法有0个或多个输入,以刻画运算对象的初始情况,所谓0个输入是指算法本身定除了初始条件;输出:一个算法有一个或多个输出,以反映对输入数据加工后的结果。没有输出的算法是毫无意义的;,6.2 经典排序算法,6.1 算法概述6.2 经典排序算法6.2.1 冒泡排序6.2.2 插入排序6.2.3 快速排序6.3 算法策略6.4 数据结构概述6.5 线性表6.6 树和图,6.2 经典排序算法,排序问题就是将一组可比

3、较大小的元素按从小到大(或从大到小)的顺序排列。 现在主要的算法重要有:比较排序算法冒泡排序选择排序插入排序快速排序堆排序基数排序基数排序桶排序,6.2 经典排序算法(冒泡排序1/5 ),冒泡排序是最简单的排序方法基本思想:将待排序的元素看作是竖着排列的“气泡”,较小的元素相当于比较轻的气泡,从而要不断往重的气泡上面浮。在冒泡排序算法中我们要对这个“气泡”序列进行若干轮处理。每一轮处理都自底向上检查一遍这个序列,并时刻注意两个相邻的元素的顺序是否正确。如果发现两个相邻元素的顺序出现“轻”的元素在下面,就交换它们的位置。显然,处理一轮之后,“最轻”的元素就浮到了最高位置;处理第二轮之后,“次轻”

4、的元素就浮到了次高位置。在进行第二轮处理时,由于最高位置上的元素已是“最轻”元素,所以不必检查。一般地,第i轮处理时,不必检查第i位以上的元素,因为经过前面i-1轮的处理,它们已正确地排好序。,6.2经典排序算法(冒泡排序 2/5),冒泡排序算法步骤如下:Step 1:对于数组item中的1至n个数据,先将第0位和第1位数据进行比较,如果item0itemj+1时,itemj与itemj+1交换*/ temp=itemj; /*将itemj赋给temp*/ itemj=itemj+1; /* 将itemj赋给itemj+1 */ itemj+1=temp; /*将将itemj+1赋给temp*

5、/ ,6.2经典排序算法(冒泡排序 4/5),举例:依然以绪论中的排序任务为例:将3、74、23、89、22、99、65、109、55、45十个数按从小到大的顺序排列。 冒泡排序算法产生以下的排序过程: 第1遍:3、23、74、22、89、65、99、55、45、109第2遍:3、23、22、74、65、89、55、45、99、109第3遍:3、22、23、65、74、55、45、89、99、109第4遍:3、22、23、65、55、45、74、89、99、109第5遍:3、22、23、55、45、65、74、89、99、109第6遍:3、22、23、45、55、65、74、89、99、109

6、第7遍:3、22、23、45、55、65、74、89、99、109第8遍:3、22、23、45、55、65、74、89、99、109第9遍:3、22、23、45、55、65、74、89、99、109结果应为:3、22、23、45、55、65、74、89、99、109,6.2 经典排序算法(冒泡排序 5/5),根据以上例子,容易看出该算法在最坏的情况总共要进行n(n-1)/2次比较。如果交换过程消耗的时间不多的话,主要时间消耗在比较上,比较次数与待排序的数目即问题的规模n的平方是一个数量级的,故称其时间复杂性为O(n2)。根据该算法的实际执行过程看,我们可以对冒泡算法作一些改进,因为如果算法某次

7、在某轮处理过程中没有进行元素交换,则说明排序工作已经完成。另外,还可以将冒泡和沉底结合起来,进行双向处理,这样就得到所谓双向冒泡排序算法(Bi-Directional Bubble Sort)。,6.2 经典排序算法(插入排序 1/4),插入排序的基本思想是,经过i-1遍处理后,己按顺序排好。第i遍处理仅将第i个元素插入到前面i-1个元素的适当位置,使得前i个元素都是排好序的序列。要达到这个目的,我们可以用顺序比较的方法。首先比较第i个元素和第i-1个元素,如果第i-1个元素 第i个元素,则表明前i个元素已排好序,第i遍处理就结束了;否则交换这两个元素的位置,接着继续比较第i-1个元素和第i-

8、2个元素,直到找到某一个位置j(1ji-1),使得前i个元素已排好序为止。,6.2 经典排序算法(插入排序 2/4),算法可以描述如下:Step 1 初始时,item0自成1个有序区,无序区为item1到itemn-1。Step 2从i=1,依次将itemi插入当前的有序区item0与itemi-1之间中,生成含i个记录的有序区。Step 3 直到i=n-1为止, 生成含n个记录的有序区。,6.2 经典排序算法(插入排序 3/4),算法代码:void Insert_Sort(int item,int length) int i,j; /*定义两个整数变量 i,j*/int temp; /*定义

9、一个用于暂时存储一个数的整数变量*/for(i=1;i=0;j-) /*如果tempitemj则为真,否则为假*/ if(tempitemj) itemj+1=itemj; /*记录后移*/ itemj+1=temp; /* 插入 */,6.2 经典排序算法(插入排序 4/4),插入排序算法的排序过程: 第1遍:(3、74)、23、89、22、99、65、109、55、45第2遍:(3、23、74)、89、22、99、65、109、55、45第3遍:(3、23、74、89)、22、99、65、109、55、45第4遍:(3、22、23、74、89)、99、65、109、55、45第5遍:(3、

10、22、23、74、89、99)、65、109、55、45第6遍:(3、22、23、65、74、89、99)、109、55、45第7遍:(3、22、23、65、74、89、99、109)、55、45第8遍:(3、22、23、55、65、74、89、99、109)、45第9遍:(3、22、23、45、55、65、74、89、99、109)可见,需要经过共9轮的处理产生最终的排序结果,完成任务。其时间复杂性还是O(n2)。,6.2 经典排序算法(快速排序 1/5),快速排序的基本思想是基于分治策略的(参考6.3.1)。对于输入的子序列Lr,如果规模足够小则直接进行排序,否则分三步处理:分解(Divi

11、de):将输入的序列Lr划分成两个非空子序列Li(其中i=0,1.q-1)和Lj(j=q+1,.r-1),使Li中任一元素的值不大于Lj中任一元素的值。 递归求解:通过递归调用快速排序算法分别对L0到Lq-1和Lq+1到Lr-1进行排序。 合并(Merge):由于对分解出的两个子序列的排序是就地进行的,所以在Lq-1和Lr(其中下标从q+1开始算)都排好序后不需要执行任何计算Lr就已排好序。 这个解决流程是符合分治法的基本步骤的。,6.2 经典排序算法(快速排序 2/5),该算法可以描述如下:Step 1 第1个元素为标志;Step 2 通过一趟排序将待排序元素分割成独立的两部分,其中一部分元

12、素的值均比标志的值小,而另一部分则比标志的值大。则可分别对这两部分元素继续进行排序,以达到整个序列有序;Step 3 分别对Step2产生的这两部分元素分别以同样的操作进行排序,以达到整个序列有序。,6.2 经典排序算法(快速排序 3/5),程序代码(1): int Partition(List L, int low, int high) /*以第一个为标志*/ int key = L.itemlow; /*low = key) high-; /*将比标志记录小的记录移到低端。*/ L.itemlow = L.itemhigh; while (low high ,6.2 经典排序算法(快速排序

13、 4/5),程序代码(2): void QSort(List L, int low, int high) if (low high) /*将L.itemlow.high一分为二*/ int pivotloc = Partition(L, low, high); /*对低子表递归排序*/ QSort(L, low, pivotloc - 1); /*对高子表递归排序*/ QSort(L, pivotloc + 1, high); ,6.2 经典排序算法(快速排序 5/5),插入排序算法产生以下的排序过程:第1遍:(3、74)、23、89、22、99、65、109、55、45第2遍:(3、23、7

14、4)、89、22、99、65、109、55、45第3遍:(3、23、74、89)、22、99、65、109、55、45第4遍:(3、22、23、74、89)、99、65、109、55、45第5遍:(3、22、23、74、89、99)、65、109、55、45第6遍:(3、22、23、65、74、89、99)、109、55、45第7遍:(3、22、23、65、74、89、99、109)、55、45第8遍:(3、22、23、55、65、74、89、99、109)、45第9遍:(3、22、23、45、55、65、74、89、99、109)可见,需要经过共9轮的处理产生最终的排序结果,完成任务。其时间

15、复杂性还是O(n2)。,6.3 算法策略,6.1算法概述6.2 经典排序算法6.3 算法策略递归和分治 枚举和动态规划 贪心法(又名贪婪法) 回溯法 6.4 数据结构概述6.5 线性表6.6 树和图,6.3 算法策略(概述),对于大型或者复杂问题进行算法设计,一般都采用“自顶向下,逐步求精”的方法,把大问题分解为若干小问题,逐步求精。大型问题的算法设计,可归纳为六个基本策略思想动态规划法子目标法图的搜索法回溯法分支与界限法 下面我们来介绍这几种常见的计算机算法。,6.3 算法策略(递归和分治 ),我们在有些娱乐节目中看到有猜商品价格的游戏,要求你在最短的时间内猜出商品的价格。假设商品的价格在1

16、00500之间,而且是整数。当然最笨的办法就是从100开始,不断的累加。这样显然时间会很费,一种较好的策略是先猜中间数(100500)/2300,如果偏高则是200它的基本思想是将一个规模为n的问题分解为k个规模较小的子问题,而且这些子问题互相独立且与原问题相同。先求出子问题的解,然后再由子问题的解得到整个问题的解。这种思想有的时候我们叫做递归,显然分治求解法采用的思想是可以用递归的思想来实现。,6.3 算法策略(枚举和动态规划 1/6),首先,我们来列举一个典型的决策问题。下图表示城市之间的交通路网,线段上的数字表示距离,单向通行由AE。试求出AE的最短距离。,6.3 6.3 算法策略(枚举

17、和动态规划 2/6),若用枚举法来解决上述问题,首先要列出所有从A到E的路径:A B1 C1 D1 EA B1 C1 D2 EA B1 C2 D1 EA B1 C2 D2 EA B2 C1 D1 EA B2 C1 D2 EA B2 C2 D1 EA B2 C2 D2 EA B2 C3 D2 EA B3 C1 D1 EA B3 C1 D2 EA B3 C2 D1 EA B3 C2 D2 EA B3 C3 D2 E比较以上的结果我们可以很容易的发现费用最少的路径是路径6 (A B2 C1 D2 E),距离为19。枚举法就是按照问题本身的性质,一一列举出该问题所有可能的解,并在逐一列举的过程中,检验

18、每个可能解是不是问题的真正解。,6.3 算法策略(枚举和动态规划 3/6),我们发现在求最少费用路径只有4步的时候就有14个解,如果现在是求40步,我们就难以用枚举来计算求解。所以仅当问题的所有可能解不太多的时候,才考虑使用枚举法。我们再用另外的一个方法来求解该问题。(1)由目标状态E向前推,分成四个阶段,每个阶段为一个子问题,即四个子问题。如上图所示。(2)我们采用的方法是:先求解简单的子问题的解,然后根据子问题的解来求解另外的相关问题的解,每个阶段到E的最短距离为本阶段的子问题的解。(3)D1,D2是第一次输入的结点。他们到E都只有一种费用,在D1框上面标5,D2框上面标2。目前无法定下,

19、那一个点将在全程最优策略的路径上。第二阶段计算中,5,2都应分别参加计算。,6.3 算法策略(枚举和动态规划 4/6),(4)C1,C2,C3是第二次输入结点,他们到D1,D2各有两种费用。此时应计算C1,C2,C3分别到E的最少费用。C1的决策路径是 min(C1D1),(C1D2)。计算结果是C1+D1+E,在C1框上面标为8。同理C2的决策路径计算结果是C2+D2+E,在C2框上面标为7。同理C3的决策路径计算结果是C3+D2+E,在C3框上面标为12。此时也无法定下第一,二阶段的城市那二个将在整体的最优决策路径上。(5)第三次输入结点为B1,B2,B3,而决策输出结点可能为C1,C2,

20、C3。仿前计算可得Bl,B2,B3的决策路径为如下情况:Bl:B1C1 费用 12+8=20, 路径:B1+C1+D1+EB2:B2C1 费用 6+8=14, 路径:B2+C1+D1+EB3:B2C2 费用 12+7=19, 路径:B3+C2+D2+E此时也无法定下第一,二,三阶段的城市那三个将在整体的最优决策路径上。,6.3 算法策略(枚举和动态规划 5/6),(6)第四次输入结点为A,决策输出结点可能为B1,B2,B3。同理可得决策路径为A:AB2,费用5+14=19,路径 A+B2+C1+D1+E。以上采用的办法就是动态规划法。它对所有的子问题都进行解答,计算过程是从小的子问题到较大的子

21、问题,每次的答案存入一个表格中,作为下面处理问题的基础。每个子问题的解决依赖于一系列子问题的结果。如何找出后面的子问题,要依赖于前面一系列子问题的递推关系式,这就是动态规划策略的核心。动态规划的最优化概念是在一定条件下,找到一种途径,在对各阶段的效益经过按问题具体性质所确定的运算以后,使得全过程的总效益达到最优。,6.3 算法策略(枚举和动态规划 6/6),动态规划法的关键步骤和特点:1)阶段的划分是关键,必须依据题意分析,寻求合理的划分阶段(子问题)方法。而每个子问题是一个比原问题简单得多的优化问题。2)每个子问题的求解中,均利用它的后部子问题的最优化结果,直到最后一个子问题所得最优解,它就

22、是原问题的最优解。3)最优化原理应在子问题求解中体现。,6.3 算法策略(贪心法1/3 ),顾名思义,贪心算法是一种在每一步选择中都采取在当前状态下最好或最优的选择,从而希望导致结果是最好或最优的算法。 贪心法是一种不追求最优解,只希望得到较为满意解的方法。贪心法一般可以快速得到满意的解,因为它省去了为找最优解要穷举所有可能而必须耗费的大量时间。我们下面来看一类非常典型的问题:装箱问题。,6.3 算法策略(贪心法2/3 ),装箱问题: 设有编号为0、1、n-1的n种物品,体积分别为v0、v1、vn-1。将这n种物品装到容量都为V的若干箱子里。约定这n种物品的体积均不超过V,即对于0in,有0v

23、iV。不同的装箱方案所需要的箱子数目可能不同。装箱问题要求使装进这n种物品的箱子数要少。,6.3 算法策略(贪心法 3/3), 输入箱子的容积; 输入物品种数n; 按体积从大到小顺序,输入各物品的体积; 预置已用箱子链为空; 预置已用箱子计数器box_count为0; for (i=0; in; i+) 从已用的第一只箱子开始顺序寻找能放入物品i 的箱子j; if (已用箱子都不能再放物品i) 另用一个箱子,并将物品i放入该箱子; box_count+; /* box_count的值加1 */ else 将物品i放入箱子j; ,6.3 算法策略(回溯),先试一试某一操作,如果以后发现这个操作不

24、适合,则允许退回去,另选一个操作来进行。这就是回溯法的控制策略。,6.4数据结构概述,6.1 算法概述6.2 经典排序算法6.3 算法策略6.4 数据结构概述6.5 线性表6.6 树和图,6.4数据结构概述,数据结构(Data Structure)是指互相之间存在着一种或多种关系的数据元素的集合。 根据数据元素间关系的不同特性,通常有下列四类基本的结构: 集合结构。在集合结构中,数据元素间的关系是“属于同一个集合”。集合是元素关系极为松散的一种结构。 线性结构。该结构的数据元素之间存在着一对一的关系。 树型结构。该结构的数据元素之间存在着一对多的关系。 图形结构。该结构的数据元素之间存在着多对

25、多的关系,图形结构也称作网状结构。,6.5 线性表,6.1 算法概述6.2 经典排序算法6.3 算法策略6.4 数据结构概述6.5 线性表6.2.1 数组6.2.2 栈6.2.3 队列6.6 树和图,6.5 线性表(数组),用一维数组来解决有名Fibonacci数列问题 main()int i; /*定义一个整数i*/long f40=0,1,1 /*赋初值0,1,1*/for(i=3;i40;i+) /* 前两个数相加作为下一个数并存在fi中 fi=fi-2+fi-1; for(i=0;i40;i+) if(i%4=0) printf(“n”); /*i%4表示:对i取余 */ printf

26、(“%12ld”,fi); /* 以12列输出,不足左边补空格*/,6.5 线性表,栈是先进后出的线性表。栈的基本操作有:在栈顶插入和删除元素、栈的初始化、清空和取栈顶元素等操作。队列是先进先出的线性表。队列的基本操作:从队头插入、队尾删除元素、初始化、清空和取队头和队尾元素。,6.6 树和图,6.5 线性表6.1 算法概述6.2 经典排序算法6.3 算法策略6.4 数据结构概述6.5 线性表6.6 树和图6.6.1 树6.6.1 图,6.6 树和图,树(Tree)是n(n0)个结点的有限集T,T为空时称为空树,否则它满足如下两个条件: (1)有且仅有唯一个无父结点的结点称为根(Root)结点

27、; (2)其余的结点可分为m(m0)个互不相交的子集Tl,T2,Tm,其中每个子集本身又是一棵树,并称其为根的子树(SubTree)。,6.6 树和图(树1/2),下面我们介绍一些树结构的基本术语:度(Degree):度是树中的一个结点拥有的子树数,一棵树的度是指该树中结点的最大度数。度为零的结点称为叶子(Leaf)或终端结点。度不为零的结点称分支结点或非终端结点。孩子(Child)和双亲(Parents):树中某个结点的子树之根称为该结点的孩子(Child)或儿子,相应地,该结点称为孩子的双亲(Parents)或父亲。兄弟:同一个双亲的孩子称为兄弟(Sibling)。,6.6 树和图(树2/

28、2),路径(path):若树中存在一个结点序列k1,k2,ki,使得ki是ki+1的双亲(1ij),则称该结点序列是从ki到kj的一条路径(Path)或道路。路径的长度指路径所经过的边(即连接两个结点的线段)的数目,等于j-1。从树的结构我们可以看到从根结点到树中其余结点均存在一条惟一的路径。树中结点k到ks存在一条路径,称k是ks的祖先(Ancestor),ks是k的子孙(Descendant)。一个结点的祖先是从根结点到该结点路径上所经过的所有结点,而一个结点的子孙则是以该结点为根的子树中的所有结点。结点的层数(Level)从根起算:根为第一层,其余结点的层数等于其双亲结点的层数加1。树中

29、结点的最大层数称为树的高度(Height)或深度(Depth)。,6.6 树和图(图1/2),定义:图由两个集合V和E组成记为G(V,E)V是顶点的有穷非空集合。E是边的有穷集合。 通常,也将图G的顶点集和边集分别记为V(G)和E(G)。E(G)可以是空集。若E(G)为空,则图G只有顶点而没有边。图可分为:有向图和无向图,6.6 树和图(图2/2),相关术语有向图:若图G中的每条边都是有方向的,则称G为有向图(Digraph)。无向图:若图G中的每条边都是没有方向的,则称G为无向图(Undigraph) 无向边和顶点关系:若(vi,vj)是一条无向边,则称顶点vi和vj互为邻接点(Adjacent),或称vi和vj相邻接;并称(vi,vj)依附或关联(Incident)于顶点vi和vj,或称(vi,vj)与顶点vi和vj相关联。有向边和顶点关系:若是一条有向边,则称顶点vi邻接到vj,顶点vi邻接于顶点vj;并称边关联于vi和vj或称与顶点vi和vj相关联。,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 经营企划

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报