73
数数数数 (C 数数数 )

数据结构 (C 语言版 )

Embed Size (px)

DESCRIPTION

数据结构 (C 语言版 ). 数据结构 (C 语言版 ). 教材: 数据结构 (C 语言版 ) 参考书: 1 《 数据结构题集 》 严蔚敏 2 《 数据结构 与算法分析 ——C 语言描述 》 (英文版 . 第 2 版)人邮社 陈越改编 3《 数据结构 —— 使用 C 语言(第 3 版) 》 ,西安交大出版社, 2003 年 朱战立编著. 课程地位. 计算机专业及相关专业的 核心课程 之一,是计算机及相关专业的 重要骨干基础课程 。. 时间安排 考试. 80 学时 周 4 60 上课 20 上机. 平时 :30% 期末 :70%. 学习要求. - PowerPoint PPT Presentation

Citation preview

Page 1: 数据结构 (C 语言版 )

数据结构 (C语言版 )

Page 2: 数据结构 (C 语言版 )

数据结构 (C语言版 )教材:数据结构 (C语言版 )参考书:1 《数据结构题集》严蔚敏2 《 数据结构 与算法分析—— C 语言描述》 (英文版 . 第 2 版)人邮社 陈越改编3 《数据结构——使用 C 语言(第 3 版)》,

西安交大出版社, 2003 年 朱战立编著

Page 3: 数据结构 (C 语言版 )

课程地位 计算机专业及相关专业的核心课程之一,

是计算机及相关专业的重要骨干基础课程。

Page 4: 数据结构 (C 语言版 )

时间安排 考试 80 学时周 4

60 上课20 上机

平时 :30%

期末 :70%

Page 5: 数据结构 (C 语言版 )

学习要求1 、上课认真听讲,适当做好笔记,按时交作业。2 、复习和预习。3 、课后需要多读课本和参考书,上网查看相关内

容,在理解基本内容的基础上,多看、多做习题。4 、上机实践。

Page 6: 数据结构 (C 语言版 )

1.1 数据结构讨论的范畴

1.2 基本概念

1.3 算法和算法的量度

第一章 绪论

Page 7: 数据结构 (C 语言版 )

1.1 数据结构讨论的范畴Niklaus Wirth : Algorithm + Data Structures = Programs

程序设计 :

算法 : 数据结构 :

为计算机处理问题编制 一组指令集 处理问题的策略问题的数学模型

Page 8: 数据结构 (C 语言版 )

f(x)=ax2+bx+c

例如 : 数值计算的程序设计问题

─━ 一元二次方程求解

─━ 一元线性回归分析经济预测

Page 9: 数据结构 (C 语言版 )

例一:计算机对弈

算法: ?

模型: ?

对弈的规则和策略

棋盘及棋盘的格局

非数值计算的程序设计问题

Page 10: 数据结构 (C 语言版 )

例二:学生的数据库管理

算法: ?

模型: ?

需要管理的项目?

如何管理? 用户界面?

各种表格

Page 11: 数据结构 (C 语言版 )

概括地说: 数据结构是一门讨论“描述现实世界实体的数学模型 (非数值计算 )及其上的操作在计算机中如何表示和实现”的学科。数据结构 =逻辑结构 +存储结构 +运算

Page 12: 数据结构 (C 语言版 )

1.2 基本概念

一、数据与数据结构

二、数据类型

三、抽象数据类型

Page 13: 数据结构 (C 语言版 )

一、数据与数据结构所有能被输入到计算机中,且能被计算机处理的符号的集合。

数据 :

是数据(集合)中的一个“个体”数据元素 :

是数据结构中讨论的基本单位

Page 14: 数据结构 (C 语言版 )

数据项:是数据结构中讨论的最小单位

数据元素可以是数据项的集合

例如:描述一个学生的数据元素可以是

年 月 日

称之为组合项

姓名 性别 出生日期 入学日期 系科 成绩

Page 15: 数据结构 (C 语言版 )

数据结构:带结构的数据元素的集合假设用三个 4 位的十进制数表示一个含 12

位数的十进制数。

3214,6587,9345 ─ a1(3214),a2(6587),a3(9345)

则在数据元素 a1 、 a2 和 a3 之间存在着“次序”关系 a1,a2 、 a2,a3

3214 , 6587 , 9345 a1 a2 a3

6587 , 3214 , 9345 a2 a1 a3

例如 :

Page 16: 数据结构 (C 语言版 )

再例,在一维数组 {a1, a2, a3, a4, a5, a6}

的数据元素之间存在如下的次序关系 :

{<ai, ai+1>| i=1, 2, 3, 4, 5}

或者说,数据结构是相互之间存在着某种逻辑关系的数据元素的集合。

数据结构:带结构的数据元素的集合

可见,不同的“关系”构成不同的“结构”

Page 17: 数据结构 (C 语言版 )

数据的逻辑结构可归结为以下四类 :

线性结构树形结构图状结构

集合结构

1 对 1

1 对多

多对多

松散

非线性

Page 18: 数据结构 (C 语言版 )

例:例: UNIXUNIX 文件系统的系统结构图文件系统的系统结构图

Page 19: 数据结构 (C 语言版 )

例:例: nn 个网站之间的连通关系个网站之间的连通关系

树形关系树形关系 网状关系网状关系

Page 20: 数据结构 (C 语言版 )

数据结构的形式定义为 :

数据结构是一个二元组

Data_Structures = (D, S)

其中 :D 是数据元素的有限集, S 是 D 上关系的有限集。

Page 21: 数据结构 (C 语言版 )

逻辑结构示例:

S=(D, R) D={ a, b, c, d, e, f } R={(a,e), (b,c), (c,a), (e,f), (f,d)}

解: 上述表达式可用图形表示为:

b c a e f d

此结构为线性的。

例 1 :用图形表示下列数据结构,并指出它们是属于线性结构还是非线性结构。

Page 22: 数据结构 (C 语言版 )

d1

d5 d2

d4 d3

该结构是非线性的。

解:上述表达式可用图形表示为:

( 2 ) S=(D, R) D={di | 1≤i≤5} R={(di , dj ), i<j}

课堂练习

Page 23: 数据结构 (C 语言版 )

数据的存储结构 —— 逻辑结构在存储器中的映象

“数据元素”的映象 ?

“关系”的映象 ?

Page 24: 数据结构 (C 语言版 )

数据元素的映象方法:

用二进制位 (bit) 的位串表示数据元素

(321)10 = (501)8 = (101000001)2

Page 25: 数据结构 (C 语言版 )

关系的映象方法:(表示 x, y 的方法)顺序映象

以相对的存储位置表示后继关系

链式映象以附加信息 (指针 )表示后继关系

Page 26: 数据结构 (C 语言版 )

对于一个数据结构 B= ( K ,R )其中 K={k1,k2,k3,k4,k5,k6,k7,k8,k9}R={r}r={<k1,k2>,<k2,k3>,<k3,k4>,<k4,k5>,<k5,k6>,<k6,k7>,<k7,k8>,<k8,k9>}它的顺序存储方式如图所示

例 2- ( 1 )

Page 27: 数据结构 (C 语言版 )

对于一个数据结构 B= ( K ,R )其中 K={k1,k2,k3,k4,k5}R={r}r={<k1,k2>,<k2,k3>,<k3,k4>,<k4,k5>}它的链式存储方式如图所示

例 2- ( 2 )

Page 28: 数据结构 (C 语言版 )

在不同的编程环境中,

存储结构可有不同的描述方法。

通常可用高级编程语言中提供的数据类型描述之。

Page 29: 数据结构 (C 语言版 )

二、数据类型

在用高级语言的源程序中,对程序中出现的每个变量、常量或表达式,需要说明它们所属的数据类型。

Page 30: 数据结构 (C 语言版 )

数据类型 是一个 值的集合和定义在此集合上的 一组操作的总称。

Page 31: 数据结构 (C 语言版 )

三、抽象数据类型 (Abstract Data Type 简称 ADT)

是指一个数学模型以及定义在此数学模型上的一组操作。

Page 32: 数据结构 (C 语言版 )

ADT 有两个重要特征 :

数据抽象 用 ADT 描述程序处理的实体时,强调的是其本质的特征、其所能完成的功能以及它和外部用户的接口。

数据封装 将实体的外部特性和其内部实现细节分离,并且对外部用户隐藏其内部实现细节。

Page 33: 数据结构 (C 语言版 )

抽象数据类型的描述方法

抽象数据类型可用( D , S , P )三元组表示。

其中: D 是数据对象; S 是 D 上的关系集; P 是对 D 的基本操作集。

Page 34: 数据结构 (C 语言版 )

ADT 抽象数据类型名 {

数据对象:〈数据对象的定义〉 数据关系:〈数据关系的定义〉 基本操作:〈基本操作的定义〉} ADT 抽象数据类型名

其中基本操作的定义格式为 :基本操作名(参数表) 初始条件:〈初始条件描述〉 操作结果:〈操作结果描述〉

Page 35: 数据结构 (C 语言版 )

赋值参数 只为操作提供输入值。引用参数 以 & 打头,除可提供输入值外,还将返回操作结果。初始条件 描述了操作执行之前数据结构和参数应满足的条件,若不满足,则操作失败,并返回相应出错信息。

操作结果 说明了操作正常完成之后,数据结构的变化状况和应返回的结果。若初始条件为空,则省略之。

Page 36: 数据结构 (C 语言版 )

例如,抽象数据类型复数的定义:

数据对象: D = {e1,e2 | e1,e2 RealSet }∈

数据关系: R1 = {<e1,e2> | e1 是复数的实数部分 | e2 是复数的虚数部分 }

ADT Complex {

Page 37: 数据结构 (C 语言版 )

基本操作:

AssignComplex( &Z, v1, v2 )

操作结果:构造复数 Z, 其实部和虚部 分别被赋以参数 v1 和 v2 的值。 DestroyComplex( &Z)

操作结果:复数 Z被销毁。 GetReal( Z, &realPart )

初始条件:复数已存在。操作结果:用 realPart 返回复数 Z的实部值。

Page 38: 数据结构 (C 语言版 )

GetImag( Z, &ImagPart )

初始条件:复数已存在。操作结果:用 ImagPart 返回复数 Z的虚部值。

Add( z1,z2, &sum )

初始条件: z1, z2 是复数。操作结果:用 sum 返回两个复数 z1, z2 的 和值。

} ADT Complex

Page 39: 数据结构 (C 语言版 )

抽象数据类型的表示和实现

抽象数据类型需要通过固有数据类型 ( 高级编程语言中已实现的数据类型 )来实现。

例如,对以上定义的复数。

Page 40: 数据结构 (C 语言版 )

typedef struct { float realpart ; float imagpart ;}complex ;

// ----- 存储结构的定义

// ----- 基本操作的函数原型说明

void Assign( complex &Z, float realval, float imagval ) ;// 构造复数 Z, 其实部和虚部分别被赋以参数 // realval 和 imagval 的值

Page 41: 数据结构 (C 语言版 )

float GetReal( complex Z ) ; // 返回复数 Z 的实部值

float Getimag( complex Z ) ; // 返回复数 Z 的虚部值

void add( complex z1, complex z2,

complex &sum ) ; // 以 sum 返回两个复数 z1, z2 的和

Page 42: 数据结构 (C 语言版 )

// ----- 基本操作的实现

void add( complex z1, complex z2,

complex &sum ) {

// 以 sum 返回两个复数 z1, z2 的和 sum.realpart = z1.realpart + z2.realpart;

sum.imagpart = z1.imagpart + z2.imagpart;

}

{ 其它省略 }

Page 43: 数据结构 (C 语言版 )

三、抽象数据类型 (Abstract Data Type 简称 ADT)

是指一个数学模型以及定义在此数学模型上的一组操作。

Page 44: 数据结构 (C 语言版 )

ADT 有两个重要特征 :

数据抽象 用 ADT 描述程序处理的实体时,强调的是其本质的特征、其所能完成的功能以及它和外部用户的接口。

数据封装 将实体的外部特性和其内部实现细节分离,并且对外部用户隐藏其内部实现细节。

Page 45: 数据结构 (C 语言版 )

抽象数据类型的描述方法

抽象数据类型可用( D , S , P )三元组表示。

其中: D 是数据对象; S 是 D 上的关系集; P 是对 D 的基本操作集。

Page 46: 数据结构 (C 语言版 )

ADT 抽象数据类型名 {

数据对象:〈数据对象的定义〉 数据关系:〈数据关系的定义〉 基本操作:〈基本操作的定义〉} ADT 抽象数据类型名

其中基本操作的定义格式为 :基本操作名(参数表) 初始条件:〈初始条件描述〉 操作结果:〈操作结果描述〉

Page 47: 数据结构 (C 语言版 )

赋值参数 只为操作提供输入值。引用参数 以 & 打头,除可提供输入值外,还将返回操作结果。初始条件

操作结果

Page 48: 数据结构 (C 语言版 )

抽象数据类型的表示和实现

抽象数据类型需要通过固有数据类型 ( 高级编程语言中已实现的数据类型 )来实现。

例如,对于一个三元组的实现 ( 类 C 语言 ) 。

Page 49: 数据结构 (C 语言版 )

typedef ElemType *Triplet;

Status InitTriplet(Triplet &T, ElemType v1, ElemType v1, ElemType v1);

Status DestroyTriplet(Triplet &T);

Status Get(Triplet T,int i, ElemType &e);

Status IsAscending(Triplet T);

Status Max(Triplet T,Element &e);

Status InitTriplet(Triplet &T, ElemType v1, ElemType v1, ElemType v1)

{

T=(ElemType *)malloc(3*sizeof(ElemType));

if(!T) exit(OVERFLOW);

T[0]=v1;T[1]=v2;T[2]=v3;

return OK;

}

类 C 语言描述三元组

Page 50: 数据结构 (C 语言版 )

Status DestroyTriplet(Triplet &T){ free(T); T=NULL; return OK;}Status Get(Triplet T,int i, ElemType &e){ if(i<1||i>3) return ERROR; e=T[i-1]; return OK;}Status IsAscending(Triplet T){ return (T[0]<=T[1]&& T[1]<=T[2]);}Status Max(Triplet T,Element &e){ e=(T[0]<=T[1])? ((T[0]<=T[2])?T[0]:T[2]) : ((T[1]<=T[2])?T[1]:T[2]) ; return OK; }

Page 51: 数据结构 (C 语言版 )

小结数据结构

逻辑结构 + 存储结构 + 运算逻辑结构:线性,树,图,集合存储结构:顺序存储和非顺序存储数据类型和抽象数据类型作业:教学主页上:( 1 )练习 1 ( 2 )用 C 语言实现教材 12 页的三元组的 AD

T 描述

Page 52: 数据结构 (C 语言版 )

1.3 算法和算法的衡量一、算法

二、算法设计的原则

三、算法效率的衡量方法和准则

四、算法的存储空间需求

Page 53: 数据结构 (C 语言版 )

算法是为了解决某类问题而规定的一个有限长的操作序列。一个算法必须满足以下五个重要特性:

1 .有穷性 2 .确定性 3 .可行性4.有输入 5 .有输出

一、算法

Page 54: 数据结构 (C 语言版 )

二、算法设计的原则设计算法时,通常应考虑达到以下目标:

1 .正确性

2. 可读性

3 .健壮性

4 .高效率与低存储量需求算法执行时间 所需的最大存储空间

Page 55: 数据结构 (C 语言版 )

三、算法效率的 衡量方法和准则通常有两种衡量算法效率的方法 : 事后统计法缺点: 1.必须执行程序 2.其它因素掩盖算法本质

事前分析估算法

Page 56: 数据结构 (C 语言版 )

#include <stdio.h>#include <stdlib.h>#include <time.h>#define N 1000int seqsearch ( int a[ ],const int n,const int x )/*n 是数组的长度 */{ int i; for (i = 1; i <= n; i++) if (a[i] == x) break; return 1;}

一个事后统计运行时间的程序

Page 57: 数据结构 (C 语言版 )

void timesearch ( ){ int i, a[N+1]; long int j; double runTime; clock_t start,end; for ( i = 1; i <= N; i++ ) /* 给数组赋值 */ a[i] = i;

start = clock(); for (j = 0; j <= 60000; j++) seqsearch(a,N,0); end = clock(); runTime = (double)(end - start); printf("This program run time: %6.3f \n",runTime);

}

void main( ){ timesearch( );}

Page 58: 数据结构 (C 语言版 )

一个特定算法的“运行工作量”的大小,只依赖于问题的规模(通常用整数量 n 表示),或者说,它是问题规模的函数。

Page 59: 数据结构 (C 语言版 )

假如,随着问题规模 n 的增长,算法执行时间的增长率和 f(n)

的增长率相同,则可记作:

T (n) = O(f(n))

称 T (n) 为算法的 (渐近 ) 时间复杂度。

Page 60: 数据结构 (C 语言版 )

3n+2=O(n) 因为 3n+24n 当 n2 时

6*2n+n2=O(2n) 因为 6*2n+n2 7*2n 当 n4

例:

渐进符号( O )的定义:当且仅当存在一个正的常数 C ,使得对所有的 n n0 ,有 f(n) Cg(n),则: f(n) = O(g(n))

Page 61: 数据结构 (C 语言版 )

时间复杂度 T(n) 按数量级递增顺序为:

多项式阶

Page 62: 数据结构 (C 语言版 )

如何估算 算法的时间复杂度?

Page 63: 数据结构 (C 语言版 )

从算法中选取一种对于所研究的

问题来说是 基本操作 的原操作,以该基本操作 在算法中重复执行的次数 作为算法运行时间的衡量准则。

算法的时间复杂度由嵌套最深层语句的频度决定

Page 64: 数据结构 (C 语言版 )

例一

两个矩阵相乘

void mult(int a[], int b[], int& c[] ) { // 以二维数组存储矩阵元素, c 为 a 和 b 的乘积 for (i=1; i<=n; ++i)

for (j=1; j<=n; ++j) {

c[i,j] = 0;

for (k=1; k<=n; ++k)

c[i,j] += a[i,k]*b[k,j];

} //for

} //mult基本操作 : 乘法操作时间复杂度 : O(n3)

Page 65: 数据结构 (C 语言版 )

例二

起泡排序

void bubble_sort(int& a[], int n) {

// 将 a 中整数序列重新排列成自小至大有序的整数序列。

for (i=n-1, change=TRUE; i>1 && change; --i)

} // bubble_sort

{ change = FALSE; //change 为元素进行交换标志 for (j=0; j<i; ++j)

if (a[j] > a[j+1])

{ a[j] ←→ a[j+1]; change = TRUE ;}

} // 一趟起泡

基本操作 : 交换赋值操作

Page 66: 数据结构 (C 语言版 )

例二

起泡排序

void bubble_sort(int& a[], int n) {

for (i=n-1, change=TRUE; i>1 && change; --i)

} // bubble_sort

最好的情况 :交换 0次 .最坏的情况 :交换 (n-1)+(n-2)+…+1=n(n-1)/2 次平均情况 : 略

{ change = FALSE;

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

if (a[j] > a[j+1])

{ a[j] ←→ a[j+1]; change = TRUE ;}

} // 一趟起泡

Page 67: 数据结构 (C 语言版 )

时间复杂度 最好时间复杂度 最坏时间复杂度 平均时间复杂度 思考 : 查找成功时 , 顺序搜索的最好 , 最坏 , 平均时间复杂度 ?int seqsearch ( int a[ ],const int n,const int x )/*n 是数组的长度 */{

int i; for (i = 1; i <= n; i++) if (a[i] == x)

break; return 1;

}

Page 68: 数据结构 (C 语言版 )

课堂练习 : 计算时间复杂度(1)i=1; j=0; 

while(i+j<=n) 

{

  if (i>j) j++;

  else i++;

}

基本操作 : if;

语句执行次数 :n

时间复杂度 :O(n)

Page 69: 数据结构 (C 语言版 )

课堂练习 : 计算时间复杂度(2)

x=n; // n>1 

y=0;

while (x>=(y+1)*(y+1))

y++; 基本操作 : y++;

语句执行次数 :向下取整 (n^0.5-1)

时间复杂度 :O( n )

Page 70: 数据结构 (C 语言版 )

四、算法的存储空间需求

算法的空间复杂度定义为 :

表示随着问题规模 n 的增大,算法运行所需存储量的增长率与 g(n) 的增长率相同。

S(n) = O(g(n))

Page 71: 数据结构 (C 语言版 )

算法的存储量包括 :

1.输入数据所占空间

2.程序本身所占空间

3.辅助变量所占空间

Page 72: 数据结构 (C 语言版 )

若输入数据所占空间只取决于问题 本身,和算法无关,则只需要分析除 输入和程序之外的辅助变量所占额外 空间。

若所需额外空间相对于输入数据量 来说是常数,则称此算法为原地工作。 若所需存储量依赖于特定的输入,则通常按最坏情况考虑。

Page 73: 数据结构 (C 语言版 )

1. 熟悉各名词、术语的含义,掌握基本概念。

2. 理解算法五个要素的确切含义。

本章学习要点

3. 掌握计算语句频度和估算算法时间复杂度的方法。