ImageVerifierCode 换一换
格式:PPT , 页数:44 ,大小:361KB ,
资源ID:4628119      下载积分:10 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.docduoduo.com/d-4628119.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录   微博登录 

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(Windows程序设计-第2章算法与数据结构(2).ppt)为本站会员(hyngb9260)主动上传,道客多多仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知道客多多(发送邮件至docduoduo@163.com或直接QQ联系客服),我们立即给予删除!

Windows程序设计-第2章算法与数据结构(2).ppt

1、Windows程序设计,第2章 算法与数据结构(2)谢晓芹,Windows程序设计,2,Topics,检索Search 快速排序Quicksort 大O记法Big “Oh” Vectors Lists Trees Hash Tables Summary,Windows程序设计,3,Trees,A binary tree is either NULL or contains a node with a left and right child which are themselves trees. Nodes contain values In a binary search tree (BST

2、) the values in the left child are smaller than the value at the node and the values in the right child are greater than the value at the node. O(log n) expected search and insertion time in-order traversal provides elements in sorted order.,Windows程序设计,4,Trees,数据结构中的树的定义 树是n个结点的有限集。在一棵非空树中(1)有且仅有一个

3、特点的称为根的结点;(2)当n1时,其余结点可分为m(m0)个互不相交的有限集T1, T2,Tm,其中每一个集合本身又是一棵树,称为根的子树。 形式化定义:Tree=(D, R) D是具有相同特性的数据元素的集合;若D只含一个数据元素,则R为空集,否则R是D上某个二元关系H的集合,即R=H. H为以下三种二元关系: (1)在D中存在唯一的根元素root,它在关系H下无前驱 (2)若D-root!=,则存在D-root 的一个划分D1,D2,Dm,对于j!=k,有DjDk= ,且对任意i,唯一存在数据元素xiDi,有(root,xi) H; (3)对应于D-root的划分,H-(root,x1)

4、,(root,xm)有唯一的一个划分H1,H2,Hm,对任意j!=k,有HjHk= ,且对任意i ,Hi是Di上的二元关系,(Di,Hi)是一棵符合本定义的树,称为root的子树.,Windows程序设计,5,Trees,树:一种分层性数据结构。 在一棵树里存储着一组项. 每个项保存一个值,它可以有指针指向0个或多个元素,但只能被另一个项所指。 树根是其中惟一的例外,没有其他项的指针向它. 树的应用 语法树 家族树 文件系统目录结构,Windows程序设计,6,Windows程序设计,7,Trees,树的效率 由于树的许多结点包含多个指向其他元素的指针,所以,很多在表或者数组结构中需要O(n)

5、时间的操作,在树中只需要O( logn)时间。结点存在多个指针能减少为寻找一个结点所需要访问的结点个数,从而降低操作的复杂性。,Windows程序设计,8,Trees,二叉树: 要么为空树;要么包含这样一个结点,其具有一个左孩子和右孩子,左孩子和右孩子本身也是二叉树. 二分检索树(binary search tree ,BST): 由结点中存储的值定义树的结构 对于一个特定节点,其左孩子的值比该节点的值小,其右孩子的值比该节点的值大.,Windows程序设计,9,TreesBinary Search Tree,typedef struct Nameval Nameval; struct Nam

6、eval char *name;int value;Nameval *left; /* lesser */Nameval *right /* greater */ ;,“smiley”,0x263A,“zeta”,0x03b6,NULL,NULL,“smiley”,0x263A,“smiley”,0x263A,“smiley”,0x263A,“Aacute”,0x00c1,“smiley”,0x263A,“Acirc”,0x00c2,NULL,NULL,“smiley”,0x263A,“AElig”,0x00c6,NULL,NULL,树结点定义,注释指明链接性质,Windows程序设计,10,

7、Trees,二分检索树的建构方式: 在树里递归地向下,根据情况确定向左或向右,直到找到了链接新结点的正确位置。结点初始化为Nameval类型的对象,它包含一个名字、一个值和两个空指针。 新结点总是作为叶子加进去的,它没有子结点。,已知条件:结点,位置,规则:值的大小, 叶子结点,Windows程序设计,11,Trees,重复项的处理,weprintf打印错误信息,在输出信息的前面加上前缀词warning,不终止程序执行,Windows程序设计,12,Trees,希望由树根到所有叶结点的最长距离与树全部结点个数成对数关系 平衡二叉树定义(数据结构) 或者是一棵空树,或者是具有下列性质的二叉树:其

8、左右子树都是平衡树,且左右子树的深度之差的绝对值不超过 在平衡树里做项检索是个O(logn)操作,因为不同可能性的数目在每一步减少一半,就像在二分检索中那样。 特殊情况 如果项是按照出现的顺序插入一棵树中,那么这棵树就可能成为不平衡的,实际上它完全可能变成极不平衡的。 例如元素以排好序的方式出现,上面的代码就会总通过树的一个分支下降,这样产生出来的可能是一个由right链接起来的表。这样的树将与表结构具有同样的性能问题。 如果元素以随机的顺序到达,那么就很难出现这种情况,产生出的树或多或少是平衡的。建议:注意输入数据对算法的影响,Windows程序设计,13,Binary Search Tre

9、e Lookup,/* lookup: look up name in tree treep *. Nameval *lookup(Nameval *treep, char *name) int cmp;if (treep = NULL)return NULL;cmp = strcmp(name, tree-name);if (cmp = 0)return treep;else if (cmp left, name);elsereturn lookup(treep-right, name); ,Windows程序设计,14,Trees分析,lookup和insert两个算法的分析 首先,基本思

10、想相同lookup和insert两个算法看起来非常像二分检索算法。原因是,它们的基本思想与二分检索相同,都是“分而治之”,这是产生对数时间性能的根源。 第二,形式上相似这些程序是递归的。如果将其改写成循环算法,它们就更像二分检索。实际上,从lookup的递归形式通过一个优雅的变换,就可以直接构造出它的循环形式。除了已经找到对应项的情况,lookup的最后一个动作是返回对它自己递归调用的结果,这种情况称为尾递归。,Windows程序设计,15,Trees分析,/* lookup: binary search for name in tab; return index or 1 if not fo

11、und. */ int lookup(char *name, Nameval tab, int ntab) int low, high, mid, cmp;low = 0;high = ntab 1;while (low 0)low = mid + 1;else /* found match */return mid;return 1; /* no match */ ,二分检索函数,Windows程序设计,16,Trees分析,尾递归直接转化为循环的方法: 修补有关参数,并重新开始这个过程。 方法:是用一个goto语句; 方法:用一个while循环;,Windows程序设计,17,Trees通

12、用树遍历器,通用树遍历器 定义操作函数,对树的每个结点调用该函数。 操作的顺序选择 原则:依赖于我们用树表示的是什么东西。如果这里表示的是排序的数据(例如二分排序树),那么就该先访问左边一半,然后是右边。有时树的结构反映了数据的某种内在顺序(例如一棵家族树),这时对树叶的访问顺序应该根据树所表示的关系确定 方法:中序,后序,前序,Windows程序设计,18,Trees通用树遍历器,应用:适合于结点需要按照排序方式顺序处理时例如要按序打印树中数据:,Windows程序设计,19,Trees通用树遍历器,利用树的一种排序方法: 首先把数据项插入一棵树,接着分配一个正确大小的数组,然后用中序遍历方

13、式顺序地把数据存入数组中。,Windows程序设计,20,Trees通用树遍历器,后序遍历的应用 计算一棵树的高度(取两棵子树的高度中大的一个,再加上1 ) 计算总的存储量,函数指针,Windows程序设计,21,Trees通用树遍历器,讨论 通用代码的设计:重用性,可扩展性好 通用代码的抽取方法 建议 领域分析,确定领域范围和领域术语,明确共性和可变性 抽取源 基于源码 基于设计(UML等) 原则 不变性 抽象化(函数,过程,类,模式) 可重用性(个人,项目内部,项目之间,领域之间) 技术: 数据挖掘,统计学,软件工程,信息检索等 代码分析,使用日志等,Windows程序设计,22,Tree

14、s树的用途,常见用途之一是用于表示语句或表达式结构。例如,语句:语法分析树表示 要对这棵树做求值,只要对它做一次后序遍历,并在每个结点做适当的操作,Windows程序设计,23,Trees,讨论 设计一个类似资源管理器的界面,针对其中文件目录结构浏览,增删改功能,进行数据结构和算法的选择,请给出你的分析过程和选择依据,并给出最终的实现方案,Windows程序设计,24,树练习,练习2-11 比较lookup和nrlookup的执行性能.递归与循环相比耗费高多少? 练习2-12 利用中序遍历方式建立一个排序过程.它的复杂性怎样?在什么条件下它的性能会很差?它的性能与快速排序或库函数比较起来又怎么

15、样?,Windows程序设计,25,Topics,检索Search 快速排序Quicksort 大O记法Big “Oh” Vectors Lists Trees Hash Tables Summary,Windows程序设计,26,Hash Tables,Provides key lookup and insertion with constant expected cost Used to create table lookup where it is not possible to reserve a slot for each possible element hash function

16、 maps key to index (should evenly distribute keys) duplicates stored in a chain (list) other mechanisms are possible.,Windows程序设计,27,Hash Tables,散列表 是由数组、表和一些数学方法相结合,构造起来的一种能够有效支持动态数据的存储和提取的结构。 典型应用 符号表:在一些值(数据)与动态的字符串(关键码)集合的成员间建立一种关联。 编译系统十之八九是使用了散列表 用于管理你的程序里各个变量的信息。 网络浏览器:使用散列表来维持最近使用的页面踪迹。 你与In

17、ternet的连接可能也用到一个散列表,缓存最近使用的域名和它们的IP地址。,Windows程序设计,28,Hash Tables,基本思想 散列表的思想就是把关键码送给一个散列函数,产生出一个散列值,这种值平均分布在一个适当的整数区间中。 散列值被用作存储信息的表的下标。 语言支持 Java提供了散列表的标准界面。 在C和C+ 里,常见做法是为每一个散列值关联一个项的链表,这些项共有这同一个散列值,如下图所示:,Windows程序设计,29,Hash Table,typedef struct Nameval Nameval; struct Nameval char *name;int val

18、ue;Nameval *next; /* in chain */ ;Nameval *symtabNHASH;/* a symbol table */,NULL,NULL,NULL,NULL,NULL,NULL,name 1,data 1,name 2,data 2,NULL,name 3,data 3,散列表是链接表的数组,一个具有n个项的散列表是个数组,其元素是一组平均长度为n/(数组大小)的链表。,问题:1)如何获取数据? 2)数组取多大?链表多长合适?,桶,Windows程序设计,30,Hash Table Lookup,/* lookup: find name in symtab,

19、with optional create */ Nameval *lookup(char *name, int create, int value) int h;Nameval *sym;h = hash(name);for (sym = symtabh; sym != NULL; sym = sym-next)if (strcmp(name, sym-name) = 0)return sym;if (create) sym = (Nameval *) emalloc(sizeof(Nameval);sym-name = name; /* assumed allocated elsewhere

20、 */sym-value = value;sym-next = symtabh;symtabh = sym;return sym; ,功能:散列表中做查询/插入,散列函数求链接表位置,遍历链接表,为什么这里要插入?,查询和插入的结合,Windows程序设计,31,Hash Function,enum MULTIPLIER = 31;/* hash: compute hash value of string */ unsigned int hash(char* str) unsigned int h;unsigned char *p;h = 0;for (p = (unsigned char *

21、) str; *p != 0; p+)h = MULTIPLIER * h + *p;return h % NHASH; ,常见散列算法:逐个把字节加到已经构造的部分散列值的一个倍数上,经验:在对ASCII串的散列函数中,选择31和37作为乘数是很好的,数组大小,对ASCII串的散列函数,只要散列函数能把关键码均匀地散布到数组里,就不必特别关心数组的大小,Windows程序设计,32,Hashtables,散列函数应具有的特征: 函数必须是确定性的, 应该能算得很快, 应该把数据均匀地散布到数组里。建议:用素数作为数组的大小是比较明智的,因为这样能保证在数组大小、散列的乘数和可能的数据值之间不

22、存在公因子。,Windows程序设计,33,Hash Function,散列函数对输入集合的依赖性强 对一类输入集合(例如短的变量名字)工作得非常好的散列函数,也可能对另一类输入集合(例如URL )工作得很差。 建议:应该用各种各样的典型输入集合来测试散列函数 它对于短小的字符串散列得好不好?对于长的串如何?对于长度相同但有微小差别的串怎么样?,Windows程序设计,34,Hash Function,优点 提供了一个对元素访问的O( 1 )期望性能 散列表如果使用得当,常数时间的检索、插入和删除操作是任何其他技术都望尘莫及的 缺点 如果散列函数不好,或者所用的数组太小,其中的链接表就可能变得

23、很长。由于这些链接表没有排序,得到的将是O(n)操作。即使元素排了序也无法直接访问它们。但是这后一个问题比较容易对付:可以分配一个数组,在里面存储指向各个元素的指针,然后对它做排序。,Windows程序设计,35,Hash Function,应用 实现符号表,采用散列表结构是最好的。 Grand Holzman为分析通信规程和并发系统而开发的Supertrace程序。Supertrace取得被分析系统每个可能状态的全部信息,将这种信息散列到存储器中单个二进制位的地址上。如果一个位已置位,那就表示对应状态已经检查过,否则就是没检查过。 XML等格式文件的存储,Windows程序设计,36,Has

24、h Tables,Java Hashtable, HashMap (Hashtable的使用不被推荐,因为HashMap提供了所有类似的功能,并且速度更快).,创建一个hashtable,保存1, 2, 3三个对象。 Hashtable numbers = new Hashtable(); numbers.put(“one“, new Integer(1); numbers.put(“two“, new Integer(2); numbers.put(“three“, new Integer(3);查找 Integer n = (Integer)numbers.get(“two“);,Wind

25、ows程序设计,37,Exercises,练习2-14 我们的散列函数对字符串而言是个极好的散列函数,但是,某些特殊数据也可能使它表现欠佳。请设法构造出能使这个散列函数性能极差的数据集。对于NHASH的不同值,要找到这样的坏数据集合很容易吗? 练习2-15 写一个函数,以某种顺序访问散列表里所有的元素。 练习2-16 修改lookup函数,使得当链表的平均长度大于某个x值时,数组将按照y的某个因子扩大,并重新构造整个散列表。 练习2-17 设计一个散列函数,用它存储二维点的坐标。如果要改变坐标的类型,你的函数很容易修改吗?例如从整数坐标改为浮点数坐标,从笛卡儿坐标改为极坐标,或者从二维改到高维

26、?,Windows程序设计,38,Iterator,现状 There are lots of ways to stuff objects into a collection, for example Array, Stack, List, Map. 需求 Wants to iterate over your object. 问题 You dont want to show him your implementation. 这也不是专业的做法. 方案 让客户遍历对象,而无须知道你是如何存储这些对象的.,Windows程序设计,39,Iterator,迭代子(Iterator)/游标(Cursor

27、)模式 意图:提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。 适用性: 访问一个聚合对象的内容而无需暴露它的内部表示。 支持对聚合对象的多种遍历。 为遍历不同的聚合结构提供一个统一的接口(即, 支持多态迭代)。,Windows程序设计,40,Topics,检索Search 快速排序Quicksort 大O记法Big “Oh” Vectors Lists Trees Hash Tables Summary,Windows程序设计,41,Summary,算法选择的步骤 首先,应参考所有可能的算法和数据结构,考虑程序将要处理的数据大概有多少。 如果被处理数据的量不大,那

28、么就选择最简单的技术。 如果数据可能增长,请删掉那些不能对付大数据集合的东西。 然后,如果有库或者语言本身的特征可以使用,就应该使用。如果没有,那么就写或者借用一个短的、简单的和容易理解的实现。如果实际测试说明它太慢,那么就需要改用某种更高级的技术。,Windows程序设计,42,Summary,数据结构 一般程序员主要使用的:数组、链表、树和散列表 基本操作:建立新元素,寻找一个元素,在某处增加一个元素,删除一个元素,以及把某个操作作用于所有的元素,Windows程序设计,43,Summary,数据结构的比较和适用性 数组支持在常数时间里访问任何元素,但不能方便地增长或缩短。 链表对于插入、

29、删除可以很好地适应,但对它做随机元素访问要求O(n)的时间。 树与散列表提供了好的折衷,既支持对特定元素的快速访问,又支持方便的增长,条件是只要能维持好某种平衡性。 算法性能分析和记法,Windows程序设计,44,补充阅读,Bob Sedgewick的一套“算法”丛书( Algorithms,Addison - Wesley )是查找有用算法的绝好去处,其处理也很容易理解。C + +算法(Algorithms in C+)的第3版有一段关于散列函数和表大小的讨论非常有意思。Don Knuth 的计算机程序设计技巧(The Art of Computer Programming,Addison

30、 - Wesley )永远是对许多算法的严格分析的信息源,它的第3卷(第2 版,1998 )专门讨论排序和检索。 Gerard Holzman的计算机规程的设计与验证(Design and Validation of Computer Protocols,Prentice Hall,1991 )里讨论了Supertrace的问题。 Jon Bentley和Doug McIlroy在文章“ Engineering a sort function”( SoftwarePractic eand Experience, 23, 1, pp.12491265, 1993)里讨论了如何构造出一个高速的、强壮的快速排序程序。,

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


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

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

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