数据结构C语言版讲义
- 格式:doc
- 大小:6.55 MB
- 文档页数:135
1 第一章 绪论
第一节 什么是数据结构?
估猜以下软件的共性:学生信息管理、图书信息管理、人事档案管理。
数学模型:用符号、表达式组成的数学结构,其表达的内容与所研究对象的行为、特性基本一致。
信息模型:信息处理领域中的数学模型。
数据结构:在程序设计领域,研究操作对象及其之间的关系和操作。
忽略数据的具体含义,研究信息模型的结构特性、处理方法。
第二节 概念、术语
一、有关数据结构的概念
数据:对客观事物的符号表示。
例:生活中还有什么信息没有被数字化?
身份证,汽车牌号,电话号码,条形代码……
数据元素:数据的基本单位。相当于"记录"。
一个数据元素由若干个数据项组成,相当于"域"。
数据对象:性质相同的数据元素的集合。
数据结构:相互之间存在特定关系的数据集合。
四种结构形式:集合、线性、树形、图(网)状
形式定义:(D,S,P)
D:数据元素的集合(数据对象)
S:D上关系的有限集
P:D上的基本操作集
逻辑结构:关系S描述的是数据元素之间的逻辑关系。
存储结构:数据结构在计算机中的存储形式。
顺序映象、非顺序映象、索引存储、哈希存储
逻辑结构与存储结构的关系:
逻辑结构:描述、理解问题,面向问题。
存储结构:便于机器运算,面向机器。
程序设计中的基本问题:逻辑结构如何转换为存储结构?
二、有关数据类型的概念
数据类型:值的集合和定义在该值集上的一组操作的总称。
包括:原子类型、结构类型。 2 抽象数据类型(ADT):一个数学模型及该模型上的一组操作。
核心:是逻辑特性,而非具体表示、实现。
课程任务:
学习ADT、实践ADT。
如:线性表类型、栈类型、队列类型、数组类型、广义表类型、树类型、图类型、查找表类型……
实践指导:
为了代码的复用性,采用模块结构。
如:C中的头文件、C++中的类
第三节 ADT的表示与实现
本教材中,算法书写习惯的约定。
数据元素类型ElemType:int,float,char, char[] ……
引用参数 &
算法:
void add(int a,int b,int &c) { c=a+b; }
程序:
void add(int a,int b,int *p_c){ *p_c=a+b; }
第四节 算法的描述及分析
一、有关算法的概念
算法:特定问题求解步骤的一种描述。
1)有穷性 2)确定性 3)可行性
二、算法设计的要求
好算法:
1)正确性 2)可读性 3)健壮性 4)高效,低存储
三、时间复杂度
事前估算:问题的规模,语言的效率,机器的速度
时间复杂度:在指定的规模下,基本操作重复执行的次数。
n:问题的规模。
f(n):基本操作执行的次数
T(n)=O(f(n)) 渐进时间复杂度(时间复杂度)
例:求两个方阵的乘积 C=A*B 3 void MatrixMul(float a[][n],float b[][n],float c[][n])
{ int i,j,k;
for(i=0; i
for(j=0; j
{ c[i][j]=0; // n*n
for(k=0; k
c[i][j]+ = a[i][k] * b[k][j]; // n*n*n
}
}
时间复杂度: )(1232)(323nOnnnnT
一般情况下,对循环语句只需考虑循环体中语句的执行次数,可以忽略循环体中步长加1、终值判断、控制转移等成分。
最好/最差/平均时间复杂度的示例:
例:在数组A[n]中查找值为k的元素。
for(i=0; i
if(A[i]==k) return i;
四、常见时间复杂度
按数量级递增排序:
)1(O < )(log2nO < )(nO < )log(2nnO < )(2nO < )(3nO
< )2(nO < )!(nO < )(nnO
将指数时间算法改进为多项式时间算法:伟大的成就。
五、空间复杂度
实现算法所需的辅助存储空间的大小。
S(n)=O(f(n)) 按最坏情况分析。
六、算法举例
例1:以下程序在数组中找出最大值和最小值
void MaxMin(int A[], int n)
{ int max, min, i;
max=min=A[0];
for(i=1; i
if(A[i]>max) max=A[i];
else if(A[i]
printf("max=%d, min=%d\n", max, min); 4 }
若数组为递减排列,比较次数是多少?
if(A[i]>max):n-1次
if(A[i]
若数组为递增排列,比较次数是多少?
if(A[i]>max):n-1次
if(A[i]
例2:计算f(x)=a0+a1x+a2x2+....+anxn
解法一:先将x的幂存于power[],再分别乘以相应系数。
float eval(float coef[],int n,float x)
{ float power[MAX], f;
int i;
for(power[0]=1,i=1;i<=n;i++)
power[i]=x*power[i-1];
for(f=0,i=0;i<=n;i++)
f+=coef[i]*power[i];
return(f);
}
解法二:f(x)=a0+(a1+(a2+……+(an-1+anx)x)… x)x
f(x)=a0+(a1+(a2+(a3+(a4+a5x)x)x)x)x
float eval(float coef[],int n,float x)
{ int i; float f;
for(f=coef[n],i=n-1;i>=0;i--)
f=f*x+coef[i];
return(f);
}
五、思考题
1、问:“s=s+i*j;”的执行次数?时间复杂度?
for(i=1;i<=n;i++)
if(5*i<=n)
for(j=5*i;j<=n;j++)
s=s+i*j;
2、问:“a[i][j]=x;”的执行次数?时间复杂度? 5 for(i=0; i
for(j=0; j<=i; j++) a[i][j]=x;
第二章 线性表
线性结构:在数据元素的非空集中,
①存在唯一的一个首元素,
②存在唯一的一个末元素,
③除首元素外每个元素均只有一个直接前驱,
④除末元素外每个元素均只有一个直接后继。
第一节 逻辑结构
形式定义:
Linear_list=(D,S,P)
D = {ai| ai∈ElemSet, i=0,1,2,…,n-1}
S = {| ai-1,ai∈D, i=1,2,…,n-1}
为序偶,表示前后关系
基本操作P:
①插入、删除、修改,存取、遍历、查找。
void ListAppend(List L, Elem e) ;
void ListDelete(List L, int i) ;
int SetElem(List L, int i, Elem e);
int GetElem(List L, int i, Elem &e);
int ListLength(List L);
void ListPrint(List L);
int LocateElem(List L, Elem e);
②合并、分解、排序
基本操作的用途:
集合的并、交、差运算
有序线性表的合并、多项式的运算
例:利用线性表LA和LB分别表示集合A和B,求A=A∪B。
void union(List &La,List Lb)
{ int La_len, Lb_len;
La_len=ListLength(La); // 计算表长
Lb_len=ListLength(Lb); 6 for(i=1; i<=Lb_len; i++)
{ GetElem(Lb, i, e); // 取Lb的第i个元素
if(!LocateElem(La, e)) // 在La中查找e
ListAppend(La, e); // 在La中插入e
}
}
第二节 顺序存储结构
一、概念
逻辑结构中的“前后关系”:物理结构中的“相邻关系”
loc(ai)=loc(a0)+i*sizeof(单个数据元素)
静态顺序存储结构:一维数组。
注意:第i个元素的下标是i-1
动态顺序存储结构:
#define LIST_INIT_SIZE 100
#define LIST_INCREMENT 10 // 存储空间的分配增量
typedef struct
{ ElemType *elem;
int length; //当前表长
int listsize; //当前已分配的存储空间
}SqList;
二、基本操作:
1、在ai之前插入x:
a0 a1 … ai-1 ai … … an-1
如何移动元素?
a0 a1 … ai-1 x ai … … an-1
void SqList_Insert(SqList A, int i, ElemType e)
{ for(j=A.length-1; j>=i; j--)
A.elem[j+1] = A.elem[j];
A.elem[i]=e; A.length++;
}
2、删除ai:
a0 a1 … ai-1 ai ai+1 … … an-1