您的位置:首页 > 理论基础 > 数据结构算法

[数据结构]第一章--绪论(读书笔记)

2013-01-03 14:05 417 查看

第一章--绪论

□1.1 什么是数据结构

为了编写出一个好的程序,必须分析待处理的对象的特征以及各处理对象之间存在的关系,这就是数据结构。

数据结构是一门研究非数值计算的程序设计问题中计算机的操作对象以及它们之间的关系和操作等的学科。

数据结构是介于数学,计算机硬件,计算机软件三者之间的一门核心课程。它不仅是一般程序设计的基础,而且是设计和实现编译程序,操作系统,数据库系统及其它系统程序和大型应用程序的重要基础。

□1.2 基本概念和术语

1.数据(data):是对客观事物的符号表示,在计算机科学中是指所有能输入到计算机中并被计算机程序处理的符号的总称。数据的含义极为广泛,如图像声音等都可以通过编码而归之于数据的范畴。

2.数据元素(data element):数据的基本单位,在计算机程序中通常作为一个整体进行考虑和处理。如树中的棋盘格局,图都是一个数据元素。

3.数据对象(data object):是性质相同的数据元素的集合。是数据的一个子集。

4.数据结构(data structure):是相互之间存在一种或者多种特定关系的数据元素的集合。

5.数据类型(data type):是一个值的集合和定义在这个值上的一组操作的总称。

6.抽象数据类型(abstract data type):是指一个数学模型以及定义在该模型上的一组操作。

7.多形数据类型(polymorphic data type):是指其值的成分不确定的数据类型。例如数据类型Triplet,其元素e1,e2和e3可以是整数或字符或字符串,甚至更复杂地由多种成分构成。然而不论其元素具有何种特性,元素之间的关系相同,基本操作也相同。

四种基本的数据结构:

1.集合:结构中的数据元素之间除了同属于一个集合的关系外,别无其它的关系。

2.线形结构:结构中的数据元素之间存在一个对一个的关系。

3.树形结构:结构中的数据元素之间存在一个对多个的关系。

4.图状结构和网状结构:结构中的数据元素之间存在多个对多个的关系。

□1.3 抽象数据类型的表示与实现

ADT抽象数据类型名{

数据对象:(数据对象的定义)

数据关系:(数据关系的定义)

基本操作:(基本操作的定义)

}ADT抽象数据类型名

□1.4 算法和算法分析

算法(algorithm)是对特定问题求解步骤的一种描述,它是指令的有限序列,其中每一条指令表示一个或多个操作。

算法的重要特征:有穷性(每一步都可在有穷时间内完成),确定性(没有二义),可行性,输入(一个算法有0个或多个输入),输出(一个算法有一个或多个输出)。

算法设计的要求:正确性(correctness),可读性(readability),健壮性(robustness),效率与低存储量需求。

□算法效率的度量

度量一个程序的执行时间通常有两种方法:事后统计的方法,事前分析估算的方法。

一个用高级语言编写的程序在计算机上运行时所消耗的时间取决于下列因素:

1.依据的算法选用何种策略

2.问题的规模,例如求100以内还是1000以内的素数。

3.书写程序的语言,对于同一个算法,实现语言的级别越高,执行效率就越低。

4.编译程序所产生的机器代码的质量。

5.机器执行指令的速度。

一个特定算法运行工作量的大小,只依赖于问题的规模,或者说它是问题规模的函数。

时间复杂度:又叫做渐近时间复杂度(asymptotic time complextiy)他表示随问题规模n的增大,算法执行时间的增长率和F(n)的增长率相同。时间复杂度在一般情况下指的是最坏情况下的时间复杂度。

语句的频度:指的是该语句重复执行的次数。通常有常量阶,线形阶,平方阶。关于频度,我们应该尽可能选用多项式阶的算法,而不希望用指数阶的算法。

空间复杂度(space complexity):作为算法所需存储空间的量度。

代码1:数据类型Triplet的定义

typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int ElemType; /* 定义抽象数据类型ElemType在本程序中为整型 */

/* 采用动态分配的顺序存储结构 */
typedef ElemType *Triplet; /* 由InitTriplet分配三个元素存储空间 */
/* Triplet类型是ElemType类型的指针,存放ElemType类型的地址 */

/* 抽象数据类型Triplet和ElemType(由c1-1.h定义)的基本操作(8个) */
Status InitTriplet(Triplet *T,ElemType v1,ElemType v2,ElemType v3)
{ /* 操作结果:构造三元组T,依次置T的三个元素的初值为v1,v2和v3 */
*T=(Triplet)malloc(3 * sizeof(ElemType));
if(!*T)
exit(OVERFLOW);

(*T)[0]=v1,(*T)[1]=v2,(*T)[2]=v3;
return OK;
}

Status DestroyTriplet(Triplet *T)
{ /* 操作结果:三元组T被销毁 */
free(*T);
*T = NULL;
return OK;
}

Status Get(Triplet T, int i, ElemType *e)
{ /* 初始条件:三元组T已存在,1≤i≤3。操作结果:用e返回T的第i元的值 */
if(i <1 || i > 3)
return ERROR;
*e = T[i-1];
return OK;
}

Status Put(Triplet T, int i, ElemType e)
{ /* 初始条件:三元组T已存在,1≤i≤3。操作结果:改变T的第i元的值为e */
if(i<1||i>3)
return ERROR;
T[i-1] = e;
return OK;
}

Status IsAscending(Triplet T)
{ /* 初始条件:三元组T已存在。操作结果:如果T的三个元素按升序排列,返回1,否则返回0 */
return(T[0] <= T[1] && T[1] <= T[2]);
}

Status IsDescending(Triplet T)
{ /* 初始条件:三元组T已存在。操作结果:如果T的三个元素按降序排列,返回1,否则返回0 */
return(T[0] >= T[1] && T[1] >= T[2]);
}

Status Max(Triplet T,ElemType *e)/*嵌套的表达式*/
{ /* 初始条件:三元组T已存在。操作结果:用e返回T的三个元素中的最大值 */
*e = (T[0]>=T[1]) ? ((T[0]>=T[2]) ? T[0]:T[2])
:((T[1]>=T[2]) ? T[1]:T[2]);
return OK;
}

Status Min(Triplet T,ElemType *e)
{ /* 初始条件:三元组T已存在。操作结果:用e返回T的三个元素中的最小值 */
*e = (T[0]<=T[1]) ? (( T[0]<=T[2] ) ? T[0]:T[2])
:(( T[1]<=T[2] )?T[1]:T[2]);
return OK;
}

int _tmain(int argc, _TCHAR* argv[])
{
Triplet T;
ElemType m;
Status i;

i=InitTriplet(&T,5,7,9);
printf("调用初始化函数后,i=%d(1:成功) T的三个值为:%d %d %d\n",i,T[0],T[1],T[2]); /* 当ElemType的类型变化时,要相应改变printf()的格式符。 */
i=Get(T,2,&m);
if(i==OK)
printf("T的第2个值为:%d\n",m);
i=Put(T,2,6);
if(i==OK)
printf("将T的第2个值改为6后,T的三个值为:%d %d %d\n",T[0],T[1],T[2]);
i=IsAscending(T); /* 此类函数实参与ElemType的类型无关,当ElemType的类型变化时,实参不需改变 */
printf("调用测试升序的函数后,i=%d(0:否 1:是)\n",i);
i=IsDescending(T);
printf("调用测试降序的函数后,i=%d(0:否 1:是)\n",i);
if((i=Max(T,&m))==OK) /* 先赋值再比较 */
printf("T中的最大值为:%d\n",m);
if((i=Min(T,&m))==OK)
printf("T中的最小值为:%d\n",m);
DestroyTriplet(&T); /* 函数也可以不带回返回值 */
printf("销毁T后,T=%u(NULL)\n",T);
return 0;
}

代码2:冒泡算法的时间复杂度

/*
当初始序列为自大至小有序时,基本操作的执行次数为n(n-1)/2
则气泡算法在最坏情况下的时间复杂度为O(n2)
*/
void bubble_sort(int a[], int n)
{
int i = 0;
int j = 0;
int change = FALSE;/*change用来表示是否基本有序,是否需要交换整数*/
int temp;

for (i = n - 1, change = TRUE; i >= 1 && change; --i ){
change = FALSE;
/*完成一次冒泡排序*/
for (j = 0; j < i; ++j){
if (a[j] > a[j+1]){
/*交换序列中两个相邻的两个整数*/
temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
change = TRUE;
}
}
}
}

int _tmain(int argc, _TCHAR* argv[])
{
int intArray[] = {1,4,3,2,5};
/*将intArray中整数序列重新排列成自小至大有序的整数序列*/
bubble_sort(intArray, sizeof(intArray)/sizeof(intArray[0]));
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: