1、数据结构与算法基础,第一章 绪论,本章目录,数据结构的研究对象 数据结构发展概况 抽象数据型 逐步求精的程序设计方法 关于本书采用的描述语言,数据结构的研究对象,数据结构是研究什么的?,数据结构主要研究内容,数据对象的结构形式。 各种数据结构的性质及其在计算机内的表示。 每种数据结构上定义的基本操作和算法。 算法的效率。 数据结构的应用和数据分类、检索等方面的技术。,什么是数据结构?(1),数据,数据是用于描述客观事物的数值、字符、以及一切可以输入到计算机中并由计算机程序加以处理的符号的集合。,数据元素,数据的基本单位。,数据对象,性质相同的数据元素的集合。,什么是数据结构?(2),结构,数据
2、元素之间的相互关系称为结构。,计算机程序是作用(访问、加工)在一组数据上的,这组数据事先必须存储在一个信息表中,信息表中的数据不是杂乱无章的排列,它们之间有一定关系。,数据结构,数据元素之间抽象的相互关系,而不涉及数据元素的具体内容称为数据结构。,信息表的结构形式,线性表,树,图,无论多么复杂的信息表都是由这三种结构组成。而信息表是由结点组成的,每一个结点是由若干相邻存储单元组成,这些存储单元构成若干个域。,信息表举例,在计算机中表示多项式:,struct Polynodeint coef;int exp;struct Polynode *link;,信息表举例,P(x)=3x3-7x2+5x
3、+1,p,数据结构发展概况,数据结构作为一门独立课程是在1968年。,在1968年前,关于数据结构的内容都在其他 课程中讲解。在以数据为中心的语言中只解决了 表结构和树结构的问题;而在以程序为中心的语 言中只解决了简单的数据结构问题,只适合于数 值计算问题;以数据结构为中心的语言,适合于 解决非数值问题,即复杂的数据结构问题。,自从1968年开始,美国一些大学将其作为一 门独立的课程,课程内容没有明确规定,开始时 同图论,特别是表和树是相同的。后来扩充了网 络、集合代数论、格、关系等现称为“离散结构” 的内容,后又扩充了文件管理的内容。,抽象数据型定义,定义,抽象数据型是一个数学模型和在该模型
4、上定义的操作集合的总称。,举例,在我们研究数据结构的时候,不是考虑某个具有此性质的特例,而是研究其共同的性质,和具有这一共同性质的数据如何在计算机中表示的,以及对这一结构的操作。,排队现象日常生活中见到的很多,这种现象如何表示在计算机中?如何处理?,抽象过程,舍去复杂系统中非本质的细节,只把其中某些本质的,能够反映系统重要宏观特性的东西提炼出来,构成系统的模型。,一个复杂的软件系统是由数据结构、操作过程和控制机制所组成,因而在软件系统设计中,也可对三种不同对象进行抽象:,过程抽象 控制抽象 数据抽象,排队的实现,struct nodetypedatatype data;struct nodet
5、ype *link;,lp,rp,排队的实现,后端插入操作:void enqueue(datatype x, queue Q)INSERT(x, END(Q), Q);,前端删除操作:void dequeue(queue Q)DELETE(FIRST(Q), Q);,数据型、数据结构和抽象数据型,数据型,变量所有可能取值的集合。,抽象数据型,一个数学模型和在该模型上定义的操作集合的总称。,数据结构,抽象数据型中数学模型的表示。,抽象数据型的规格描述,为什么进行抽象数据型的规格描述? 既是程序实现的依据,又是程序文 档的重要内容,它便于程序的调试与维 护。,规格描述的要求: 完整性:要能反映所定
6、义的抽象数据型的全部特征。 统一性:是前后协调的整体。 通用性:所定义的抽象数据型应适用尽量广的对象。,规格描述的语言: 自然语言: 程序语言: 类程序语言:,规格描述的步骤: 抽象数据的定义域。 语法规格说明:指定操作的名称和各操作的操作数及类型。 语义规格说明:给出合法表达式的语义。,规格描述的举例,下面是栈的规格描述。,什么是栈?,栈顶指针,栈,语法格式说明,指明操作名称以及各操作数的类型。,type Stack Elementtype; NEWSTACK( ) Stack, PUSH(Elementtype, Stack)Stack, POP(Stack) StackUNDEFINED
7、, TOP(Stack) ElementtypeUNDEFINED, EMPTY(Stack) Boolean;,语义格式说明,指明合法表达形式的语义,即该表达形式起什么作用,或它的效果是什么。,declare stk: Stack, elm: Elementtype; POP(NEWSTACK)=NEWSTACK, POP(PUSH(elm,stk)=stk, TOP(NEWSTACK)=UNDEFINED, TOP(PUSH(elm,stk) = elm, EMPTY(NEWSTACK) =TRUE, EMPTY(PUSH(elm,stk)=FALSE;,抽象数据型的实现原则,应符合规格描
8、述的定义; 应有尽可能好的通用性; 应尽可能独立于程序的其他部分,不仅在结构上应成为独立的模块,而且应将非本质的内部细节屏蔽起来。,抽象数据型的实现1,以栈的抽象数据型为例,实现抽象数据型的操作:,型的描述:,enum boolean (FALSE, TRUE); struct node elementtype val;node *next; typedef node *stack;,抽象数据型的实现2,stack NEWSTACK( ) stack s;s=new node;s-next=NULL;return s; ,建立新栈:,S,抽象数据型的实现3,void PUSH(elementt
9、ype elm,stack stk) stack s;s=new node;s-val=elm;s-next=stk-next;stk-next=s; ,压入栈操作:,stk,s,抽象数据型的实现4,void POP(stack stk) stack s;if (stk-next!=NULL)s=stk-next;stk-next=s-next;delete s; ,弹出栈操作:,如果语义定义为:POP(NEWSTACK)=UNDEFINED,POP(PUSH(elm, stk)=stk; POP操作必须写成如下形式:,viod POP(stack stk) if(stk-next)s=stk
10、-next;stk-next=s-next;delete s;else ERROR(“stack is empty“);,抽象数据型的实现5,elementtype top(stack stk) if (stk-next!=NULL)return(stk-next-val)elsereturn NULL; ,取栈顶元素操作:,抽象数据型的实现6,boolean EMPTY(stack stk) if(stk-next!=NULL)return FALSE;elsereturn TRUE; ,测栈空操作:,多层次抽象技术,学校,院,院,院,系,系,系,多层抽象描述方向,多层抽象修正方向,树型结构
11、,线性表结构,抽象数据型的优点,降低了软件设计的复杂性。 提高了程序的可读性和可维护性。 程序的正确性容易保证。,逐步求精的程序设计方法,如何求解一个问题?,寻求尽可能完整和精确描述该问题的数学模型。 根据数学模型设计出求解该问题的算法。,算法举例欧几里得算法,给定两个正整数m和n,求他们的最大公约数。,E1求余数: m/n的余数r (显然0rn)。 E2余数为0?: 若r=0算法结束, n即为答案。 E3交换: 置mn, nr, 转移到E1。,举例,求28和16的最大公约数。,28/16 余 12,16/12 余 4,12/4 余 0,算法的五大特性,有穷性:一个算法总是执行有穷步后结束。
12、确定性:算法的每一个步骤必须有明确的意义。 输入:一个算法有0个或多个输入。 输出:一个算法有一个或多个输出。 能行性:算法中的每个运算步骤都可以精确执行,而且人们用纸和笔作有穷次即可完成。,一个具有多条通路的交叉路口,当允许某些通路上的车辆在交叉路口“拐弯”时,必须对其他一些通路上的车辆加以限制,不许同时在交叉路口“拐弯”,以免发生碰撞。,算法的逐步求精以交通路口为例,现有如图的交叉路口,有五条通路A、B、C、D、E。其中通路C、E是单行道。问该路口最少用几个颜色的指示灯?,算法的逐步求精2,给出数学模型:,交通路口的数学模型,解决着色的三种方法,将原题转变为用最少的不同颜色对数学模型图中的
13、顶点着色使得任意相邻顶点的颜色不同。,穷举法: 利用提供的与问题有关的附加条件,寻找最有可能的颜色数。 贪心法:,贪心算法的实现,void greedy(GRAPH G, SET newclr) /*G为未着色的顶点集合*/ /*newclr为已着色的顶点集合*/ newclr = ;while(G中有未着色的顶点v)if(v不与newclr中的任何一个顶点相邻)给v着色;将v放入newclr中; ,贪心算法第一步求精,void greedy(GRAPH G, SET newclr) int found;newclr = ;while(G中有为着色的顶点v)found=0;for(newclr
14、中的每一个顶点w)if (v与w相邻) found=1;if(!found)给v着色;将v放入newclr中; ,贪心算法第二步求精,void greedy(GRAPH G, SET newclr) int found;newclr = ; v=G中第一个未着色的顶点;while(v!=0)found=0; w=newclr中第一个顶点;while(w!=0)if (v与w相邻) found=1;w=newclr中的下一个顶点;if(!found)给v着色;将v放入newclr中;v=G中下一个未着色的顶点; ,贪心算法第三步求精,设G和S分别是抽象数据型GRAPH和SET的实例。,在实例G上
15、定义操作如下: FIRSTG(G)返回G中第一个未标记的元素。若无这样的元素,则返回NULL。 EDGE(v,w,G)若v和w在G中相邻,则返回TRUE,否则,返回FALSE。 MARK(v,G)标记G中的元素v。 ADDG(v,G)将元素v放入G中。 NEXTG(G)返回G中下一个未加标记的元素,若无这样的元素,则返回NULL。,在实例S上定义操作如下: MAKENULL(S)将集合S置空。 FIRSTS(S)返回S中第一个元素。若S为空,则返回NULL。 NEXTS(S)返回S中下一个元素,若S中无下一个元素,则返回NULL。 ADDS(v,S)将元素v放入S中。,void greedy(
16、GRAPH G, SET newclr) int found; elementtype v, w;MAKENULL(newclr); v=FIRSTG(G);while(v!=NULL)found=0; w=FIRSTS(newclr);for(w!=NULL)if (EDGE(v, w, G) found=1;w=NEXTS(newclr);if(!found)MARK(v, G);ADDS(v, newclr);v=NEXTG(G); ,本书采用的描述语言,本课程采用的是类C语言,部分采用类 C+。同时,为了便于理解和编程,采用 了C语言的非标准函数和类型,但此非标 准函数和类型可简单地使
17、用标准C语言来 描述。,结构类型说明 在结构体的类型声明中,struct不省略, 而在结构体变量的定义中,可省略struct。 struct node float x;float y;; struct node a,b; node a, b;,输入输出: 本课程在例题中输入输出使用的是C+中 的输入流cin和输出流cout,而不是C语言 中的scanf和printf。 输入: cin 变量名; 输出:cout 变量名;cout “字符串“;,用new和delete的动态存储分配 虽然在C语言中使用malloc( )和free( )申请 或释放结点的存储空间,在本课程中,为 了便于书写和理解,而
18、采用C+中的方式, 使用new和delete。 指针变量名=new 类型名; delete 指针变量名;,引入引用类型: 本课程在书写算法时涉及到参数返回值问 题。在C语言中,哑实参数传递是值传递, 修改哑元的值,对实元无影响;如想将哑 元的值传回给实元,必须采用指针传递, 但在书写时又麻烦。,引入引用类型: 本课程引入了类似于pascal中变量参数、 C+的概念“引用参数”。他类同于指针传 递的性质,函数调用时,将实元的指针传 递给哑元,只是书写方法不同。,引用参数举例,两个数据交换的三种程序实例。,用值传递,用指针传递,用引用参数,值传递实现交换,#include void swap(in
19、t x, int y) int t;t=x; x=y; y=t; main ( ) int a, b;a=10; b=20;cout a“ “bn;swap(a, b);cout a“ “bn; ,指针传递实现交换,#include void swap(int *x, int *y) int t;t=*x; *x=*y; *y=t; main ( ) int a, b;a=10; b=20;cout a“ “bn;swap( ,引用参数实现交换,#include void swap(int ,本书采用的描述语言,布尔类型: 在C/C+语言中,没有布尔类型,即逻辑 类型,为了便于书写和讲课,定义了布尔 类型boolean,在算法具体实现时,可如下 定义:enum boolean (FALSE , TRUE),关于数组下标: C语言的数组下标都是从开始的,而在 日常采用的是从开始的,为了描述更自 然,因而在本课程中数组下标为的元素 空着不用。,#include语句: 本课程可省略文件头嵌入语句#include。,第一章结束,