数据结构与算法
开发工具与关键技术:
作者:胡宁淇
撰写时间:2021年5月8日
数据结构的数学定义
◇数据结构是一个二元组
◇Data_Structure = (D,S)
◇D — 数据元素的有限集合
◇S — 定义在D上的关系的有限集合
逻辑结构和物理结构
◇逻辑结构:数据元素之间的逻辑关系
◇物理结构:数据结构在计算机中的表示又称存储结构
◇算法的设计取决于选定的逻辑结构
◇算法的实现依赖于采用的存储结构
数据类型与抽象的数据类型
数据类型
◇值的集合以及定义在这个集合上的一组操作。
◇例如:C语言中的整数类型。
抽象数据类型(ADT)
◇数学模型以及定义在该模型上的一组操作。
◇与其在计算机中的表示和实现无关。
算法和算法分析
◇算法:对特定问题求解步骤的一种描述
◇算法的五个重要特性:
1. 有穷性
2.确定性
3.可行性
4.输入
5.输出
◇冒泡排序算法
算法设计的要求
◇算法应达到的目标
1.正确性
2.可读性
3.健壮性
4.效率与低存储量
算法效率的度量
1.事后统计法 (大程序用这种方法)
2.事前分析估算法 (简单的小程序用这种方法)
算法的时间复杂度:基本操作重复执行的次数
它是问题规模n的某个函数f(n): T(n) = O(f(n))
例如:两个nxn矩阵相乘
两个nxn矩阵相乘的算法中乘法运算是基本操作,其重复执行的次数n³。
该算法的时间复杂度为T(n) = O(n³)。
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( i=2; i<=n;++i )
{
for( j =2; j<=n;++j )
{
++x; a[ i , j ] = x;
}
}
++x的执行次数关于n的增长率是O(n²)
具体的次数一般叫语句频度,考虑极限无穷大的情况叫复杂度。
第二章 线性表
线性结构的特点是:
△存在唯一的“第一个”数据元素;
△存在唯一的“最后一个”数据元素;
△除第一个以外,每一个数据元素均有且只有一个前驱元素;
△除最后一个以外,每一个数据元素均有且只有一个后继元素;
线性表的顺序表示与实现(物理结构)
△线性表(a1,a2,…,an)的顺序表示—用一组地址连续的存储单元依次存储线性表的数据元素
△插入一个元素的时间复杂度为O(n);
△删除一个元素的时间复杂度为O(n);
线性表的链式表示与实现
△顺序表示的优点是随机存取表中的任意元素;
△顺序表示的弱点是在插入或删除操作时,需大量移动元素;
△链式表示—没有顺序表示的弱点,也失去了顺序表示的优点;
△线性表的链式表示—是可以用一组任意的存储单元存储线性表的数据元素。
链表相关的名称
△数据域、指针域
△结点、头结点
△指针(链)
△链表、单链表(线性链表)
线性表的单链表存储结构
插入结点:指针p所指的结点后插入指针s所指的结点
插入结点程序
删除结点:删除指针p所指结点后的结点
删除结点程序
删除第i个元素,并由e返回其值
循环链表
△循环链表的特点—表中最后一个节点的指针域指向头结点,整个链表形成一个环。
△从表的任意结点出发可以找到表中其他结点。
双向链表
△双向链表的特点—表中的每一个结点都有两个指针域,一个指向后继结点,一个指向前趋结点,整个链表形成两个环。
△从表的任意结点出发可以通过正向环(或反向环)找到表中其他结点。
插入结点:
指针p所指的结点前插入指针s所指的结点
插入结点程序
删除结点:
删除指针p所指的结点
删除结点程序
删除第i个元素,并由e返回其值
栈和队列—操作受限的线性表
栈
抽象数据类型栈的定义
栈(stack):
○先进后出的线性表
○或后进后出的线性表
○或仅在表尾进行插入和删除操作的线性表
栈顶(top):线性表的表尾端,即可操作端。
栈的抽象数据类型
栈的顺序表示与实现——(顺序栈)
顺序栈示意图
顺序栈的操作实现举例(InitStack)
顺序栈的操作实现举例(Push)
插入新的栈顶元素时,堆栈变化示意图
顺序栈的操作实现举例(Pop)
顺序栈的操作实现举例(GetTop)