数据结构和算法期末复习
- 第一章 绪论
- 1.1 数据结构
- 1.2 基本概念和术语
- 1.3 算法与算法分析
- 1.4 数据结构与表示
- 1.*小结
- 第二章 线性表
- 2.1 线性表的定义
- 2.2 顺序表
- 2.2.1 线性表的顺序存储
- 2.2.2 顺序表基本操作的实现
- 2.3链表
- 2.3.1 线性表的链式存储
第一章 绪论
数据结构是一门研究非数值计算的程序设计问题中的操作对象,以及它们之间的关系和操作等相关问题的学科。
程序设计=数据结构+算法
1.1 数据结构
- 数据结构(data structure)是计算机中存储、组织数据的方式。
- 数据结构要研究的问题:分析待处理的对象的特征及各对象之间存在的关系。
- 数据结构的内容:计算机程序对信息进行加工处理,信息(数据)之间具有重要的结构关系。
- 数据的结果,直接影响算法的选择和效率。
1.2 基本概念和术语
- 数据(data):是描述客观事物的符号表示。所以能够输入计算机并被计算机程序处理的符号的总称。
- 数据元素(data element):是组成数据的、有一定意思的基本单位、在计算机中通常作为整体处理。(也被称为记录)
- 数据项(data item):一个数据元素可以由若干个数据项组成。是数据不可分割的最小单位。
- 数据对象(data object):性质相同的数据元素的集合,是数据的一个子集。
- 数据结构:是相互之间存在一种或多种特定关系的数据元素的集合。
- 数据结构包括三个组成成分:数据的逻辑结构、数据的存储结构和数据的运算。
- 数据的逻辑结构的两个要素:数据元素和关系。
- 四类基本结构:集合结构、线性结构、树结构、图结构或网状结构。
- 集合结构:集合结构中的数据元素除了同属于一个集合外,它们之间没有其他关系。
- 线性结构:线性结构中的数据元素之间是一对一的关系。
- 树形结构:树形结构中的数据元素之间存在一种一对多的层次关系。
- 图形结构:图形结构的数据元素是多对多的关系。
- 数据对象在计算机中的存储表示称为数据的存储结构也称为物理结构。
- 物理结构:数据的逻辑结构在计算机中的存储形式。
- 数据元素在计算机中两种基本的存储结构:顺序存储结构,链式存储结构。
- 顺序存储结构:借助元素在存储器中的相对位置来表示数据元素之间的逻辑结构。要求所有元素依次存放在一片连续的存储空间,其数据间的逻辑关系和物理关系是一致的。
- 链式存储结构: 无须占用一整块存储空间,这组存储单元可以是连续的,也可以是不连续的。为了表示结点之间的关系,要给每一个结点附加指针字段,用于存放后继元素的存储地址。
- 数据类型:顺序存储结构借助数组类型描述,链式存储结构借助指针类型描述。
抽象数据类型: - 原子类型:是不可以再分解的基本类型,包括整型、实型、字符型等。
- 结构类型:由若干个类型组合而成,是可以再分解的。
整型数组是有若干整型数据组成的。抽象是指抽取出事物具有的普遍性的本质。
1.3 算法与算法分析
- 算法:对特定问题解题方案的准确而完整的描述,是一系列解决问题的清晰指令。算法代表着用系统的方法描述解决问题的策略机制。
- 五个重要的特性
- 有穷性。一个算法必须总是在执行有穷步后结束,不能形成无穷循环或不结束。
- 确定性。对于每种情况下所应执行的操作,在算法中都有确切的规定,不会产生二义性,算法中的所有操作都可以通过已经实现的基本操作运算执行有限次来实现。
- 可行性。算法中的所有操作都可以通过已经实现的基本操作运算执行有限次来实现。
- 输入。一个算法有零个或多个输入。当用函数描述算法时,输入多数是通过形参表示的。
- 输出。一个算法有一个或多个输出。它们是算法进行信息加工后得到的结果,无输出的算法没有任何意义。
- 算法描述(algorithm description):对设计出的算法,用一种方式进行详细的描述,自然语言、伪代码、程序流程图。
- 算法分析
- 正确性
- 对于几组输入数据能够得出满足要求的结果。
- 对于精心选择的典型、苛刻而带有刁难性的输入数据能够得出满足要求的结果
- 对于一切合法的输入数据都能产生满足要求的结果。
- 可读性
- 便于入门理解和相互交流。
- 健壮性
- 输入数据非法时,好的算法能够适当做出正确反应进行相应的处理。
- 高效性
- 时间 (时间复杂度)
- 算法设计合理
- 执行效率高
- 空间 (空间复杂度)
- 存储容量合理
常见的时间复杂度频率表
- 最好时间复杂度:最好情况下的时间复杂度,算法计算量可能达到的最小值。
- 最坏时间复杂度:最坏情况下的时间复杂度,算法计算量可能达到的最大值。
- 原地工作:算法执行所需要的辅助空间相对于输入数据量而言是个常数。
普通求解1加到100和
int i, sum = 0,n = 100;
for(i = 0;i <= n;i++)
{
sum = sum + i;
}
printf(" %d ", sum);
使用一点点算法求解
int i, sum = 0,n = 100;
sum = (1 + n) * n / 2;
printf(" %d ", sum);
1.4 数据结构与表示
- 全局变量:程序中所有函数都可以访问的变量。
- 局部变量:只能在本函数中访问的变量。
- 参数传递方式:
- 传值 (int a,int b)形参=实参
- 传指 (int *a,int *b)形参=实参地址
- 传址 (int &a,int &b)
1.*小结
- “数据结构”是一门研究非数值计算程序设计中操作对象,以及这些对象之间的关系和操作的学科。
- 数据结构包括两个方面的内容:数据的逻辑结构和存储结构。同一逻辑结构采用不同的存储方法,可以得到不同的存储结构。
- 逻辑结构是从具体问题抽象出来的数学模型,从逻辑 关系上描述数据,它与数据的存储无关。根据数据元素之间关系的不同特性,通常有四类基本逻辑结构:集合结构、线性结构、树结构和图结构。
- 存储结构是逻辑结构在计算机中的存储表示,有两类存储结构:顺序存储结构和链式存储结构。
- 抽象数据类型是指由用户定义的、表示应用问题的数学模型,以及定义在这个模型上的一组操作的总称,具体包括三部分:数据对象、数据对象上关系的集合,以及对数据对象的基本操作的集合。
- 算法是为了解决某类问题而规定的一个有限长的操作序列。算法具有五个特性:有穷性、确定性、可行性、输入和输出。一个算法的优劣应该从四个方面来评价:正确性、可读性、健壮性和高效性。
- 算法分析的两个主要方面是分析算法的时间复杂度和空间复杂度,以考查算法的时间和空间效率。
第二章 线性表
线性表(linear list)
线性表是线性结构的抽象,线性结构的特点是数据元素之间具有一对一的线性关系。
线性表有顺序存储和链式存储两种物理结构。
除第一元素之外,
基本操作:插入、删除和查找。
2.1 线性表的定义
- 线性表是由具有相同数据类型的n(n>=0)个数据元素组成的有限序列,通常记作(,, ,,,,,)。
- 线性表第一个元素无直接前驱,最后一个元素无直接后继。
- 一个线性表中的数据元素必须属于同一数据类型。
- 表中每一元素只有一个前趋,除最后一个元素之外,表中每一元素仅有一个后继。
- 线性表中元素个数n被定义为线性表的长度。 n=0时,线性表称为空表。
- 线性表特点:
- 同一性:表中所有数据元素属于同一数据类型。
- 有穷性:表又有限个数据元素组成,表长即为表中数据元素的个数。
- 有序性:元素之间存在顺序。
- 线性表抽象数据类型定义:
- 类型名称:线性表(List)
- 数据对象集:n(n>=0)个元素组成的有序序列。
- 操作集:
- List CreateList():线性表的初始化,返回一个空表。
- ElementType FindKth(List L, ElementType k):返回线性表L中指定位置k上的数据元素。
- Position FindX(List L, ElementType X):在线性表中查找第一个与X相同的数据元素在线性表L中的位置。
- int Insert(List L,ElementType X,int i):在线性表L的指定位置i上插入一个元素X;如果i有效,返回1,否则返回0。
- int Del(List L, int i, ElementType *e):在线性表L中删除指定位置i上的数据元素;如果i有效,返回1并带回所删除的数据元素,否则返回0。
- int Length(List L):求线性表L的长度。
2.2 顺序表
2.2.1 线性表的顺序存储
数据类型的定义
线性表的长度last等于线性表中最后一个元素的下标加1
#define MAXSIZE 50 //线性表的最大值
typedef struct LNode *SeqList;
struct LNode{
int data[MAXSIZE];
int last;
};
SeqList 结构类型指针
引用数据项
L->data[i];
L->last;
2.2.2 顺序表基本操作的实现
- 顺序表的初始化
构造一个空表:对线性表的各个数据项赋初值。
SeqList CreateList()
{
/*创建一个线性表并返回*/
SeqList list;
list = (SeqList)malloc(sizeof(struct LNode));
list->last=0;
return list;
}
因为是空表,没有任何元素,设置list->last为0
- 查找
<按值查找>
给定一个数据元素,在线性表中逐一比较。找到则返回位置序号,否则返回错误信息。
int FindX0(SeqList list,int X)
{
/*在顺序表list中查找X,如果查找到,则返回逻辑地址,否则返回false*/
int i;
for(i=0;i<list->last;i++)
if(list->data[i]==X)
return i+1;
return false;
}
X的平均时间复杂度(1+2++n)/n=(n+1)/2。 即:O(n)
<按序查找>
检查给定的逻辑地址i是否有效,有效返回数组元素;list->data[i-1],否则返回错误。
int FindX1(SeqList list,int index)
{
/*检查给定的逻辑地址index是否有效,有效返回对应数组元素,否则返回错误信息*/
if(index<0||index>list->last)
return false;
else
return list->data[index];
}
时间复杂度:O(1)。
- 插入
在线性表第i(1 <= i <= n+1)位上,插入值为X的元素。插入成功,线性表长度+1。
i=1时,表头前面插入,i=n+1时,在表尾插入
算法描述:
1. 判断插入位置是否有效,有效进行下一步,无效则返回False。
2. 插入位置后的元素后移。
3. X存入对应值,更新长度。
4. 返回True。
int Insert(SeqList list, int x,int index)
{
if(index<1 || index>list->last ||list->last == MAXSIZE-1)
return false;
for(int j=list->last;j>=index;j--)
list->data[j]=list->data[j-1];
list->data[index-1]=x;
list->last++;
return true;
}
插入时注意下标是否越界
检查逻辑地址index是否合法,插入之后保证线性表有序
移动数据时,从后往前一次移动
平均移动次数(0+1+…+n)/(n+1)=n/2
平均时间复杂度:O(n)
- 删除
将顺序表中的逻辑地址为i(1 <= i <= n)的数据元素从线性表中去掉,删除成功之后,线性表长度减一。i=1时,删除第一个元素。i=n时,删除最后一个元素。
算法描述:
- 检查逻辑地址是否有效,无效返回false。
- 逻辑地址之后的所有元素依次前移。
- 修改线性表长度,返回正值。
int Del(SeqList list, int index,int *item)
{
if(index<1 || index>list->last-1)
return false;
*item = list->data[index-1];
for(int j=index-1;index<list->last-1;j++)
list->data[j]=list->data[j-1];
list->last--;
return true;
}
(1)检查待删除数据元素的逻辑地址i的有效性,i的范围[1,n],其中n是线性表长度。
(2)将下标i~n-1的数据依次前移。
平均时间复杂度:O(n)
2.3链表
2.3.1 线性表的链式存储
线性表中的数据元素可以存放在任意的一组存储单元。