数据结构chapter1——绪论
Part1 数据结构
知识点总结:
-
数据(Data)描述客观事物的数字、字符以及所有能输入到计算机中并被计算机接受的各种符号的统称。
——是计算机处理的信息的某种特定的符号表示形式。
——是计算机操作的对象的总称 -
数据元素(Data Element):表示一个事物的一组数据
-
数据项(Data Item):是数据元素种有独立含义的,不可分割的最小标识单位
4. 数据结构(data structure)指数据元素之间存在的关系。
数据结构包含三方面:①数据的逻辑结构,②数据的存储结构,③对数据的操作
1. 数据的逻辑结构 集合+关系:
(1)线性结构:数据元素只有一个前驱数据元素和一个后继数据元素。
结构中的数据元素之间存在一对一的关系。
(2)树结构:每个数据元素只有一个前驱数据元素,可有零个或若干个后继数据元素。
结构中的数据元素之间存在一对多的关系。
(3)图结构:每个数据元素可有零个或若干个前驱数据元素,零个或若干个后继数据元素。
结构中的数据元素之间存在多对多的关系。
2. 数据的存储结构 独立性
(1)顺序存储结构=逻辑次序 数组
(2)链式存储结构 地址信息 指针
3. 数据操作 定义在逻辑结构实现在物理结构
- 初始化。
- 判断是否空状态。
- 求长度:统计元素个数。
- 存取:取值:获取指定元素值。置值:设置指定元素值。
- 遍历:按某种次序访问所有元素,每个元素只被访问一次。
- 插入:增加指定元素。删除:移去指定元素。
- 查找:寻找满足条件的数据元素。
- 排序:按关键字值大小次序重新排列数据元素。
数据类型(data type)是指一个类型和定义在这个类型上的操作集合。
类型:相同逻辑意义的一组值:int
基本数据类型和构造数据类型
数据类型:特性+操作
数据结构:关系,与类型无关。
抽象数据类型(Abstract Data Type,ADT)是指一个数学模型以及定义在此数学模型上的一组操作。
所有高级语言中都有"整型"数据类型,实现方法不同,但对程序员而言,它们是"相同"的。各种语言中实现的是同一个"整数类型",而这个"整数类"的定义仅对"整数的数学特性"有明确规定。可称这个"整数类型"为"抽象数据类型"。
数据抽象:逻辑含义和具体实现分离
用ADT描述程序处理的实体时,强调的是其本质的特征、其所能完成的功能以及它和外部用户的接口(即外界使用它的方法)。
ADT Set
{ 数据:集合中有n(n≥0)个数据元素,元素类型为T
操作:
boolean isEmpty(); //判断集合是否为空
int size (); //返回集合的元素个数
boolean contains(T x); //判断集合是否包含元素x
boolean add(T x); //增加元素x
boolean remove(T x); //删除首次出现的元素x
void clear(); //删除集合所有元素
void print(); //输出集合中所有元素
boolean equals(Set s); //比较集合是否相等
boolean containsAll(Set s);
//判断是否包含s中的所有元素,s是否子集
boolean addAll(Set s); //集合并
boolean removeAll(Set s);//集合差
boolean retainAll(Set s);
//仅保留那些也包含在集合s中的元素
}
java实现
public interface SSet<T>
{ //集合接口,T是泛型参数,指定元素类型
boolean isEmpty(); //判断集合是否为空
int size(); //返回集合的元素个数
String toString(); //返回集合元素的描述字符串
T search(T key); //查找,返回关键字为key元素
boolean contain(T x); //判断集合是否包含元素x
void add(T x); //增加元素x
void remove(T x); //删除首次出现的元素x
void removeAll(); //删除集合所有元素
}
Java语言的接口(interface)是一组抽象方法、常量和内嵌类型的集合。
声明接口
public interface Set<T> //集合接口,T是泛型参数
声明实现接口的类
public abstract class AbstractSet<T> implements Set<T>
//抽象集合类,没有实现所有抽象方法
public class HashSet<T> implements Set<T> //散列表类
接口是引用类型
Set<T> set = new HashSet<T>(); //接口对象引用实例
set.add(x) //运行时多态性,执行HashSet<T>类实现的add(x)方法
Part2 算法
什么是算法
算法是一个有穷规则的集合,其规则确定一个解决某一特定类型问题的操作序列
算法定义:
①有穷性
②确定性:明确规则
③输入
④输出
⑤可行性
算法设计目标:
- 正确性
a.程序中不含语法错误;
b.程序对于一切合法的输入数据都能得出满足要求的结果;
-
可读性
算法主要是为了人的阅读与交流,其次才是为计算机执行,因此算法应该易于人的理解;另一方面,晦涩难读的程序易于隐藏较多错误而难以调试。
-
健壮性:可控结果
当输入的数据非法时,算法应当恰当地作出反映或进行相应处理,而不是产生莫名奇妙的输出结果。并且,处理出错的方法不应是中断程序的执行,而应是返回一个表示错误或错误性质的值,以便在更高的抽象层次上进行处理。
-
高时间效率,高空间效率。
通常,效率指的是算法执行时间;
存储量指的是算法执行过程中所需的
最大存储空间,两者都与问题的规模
有关。
算法分析
度量算法的时间效率——时间复杂度
算法的时间效率指算法的执行时间随问题规模的增长而增长的趋势,通常采用时间复杂度来度量算法的时间效率。
T(n)=O(f(n))
时间复杂度 ---- T(n)变化时呈现什么规律。
一般情况下,算法中基本操作重复执行的次数是问题规模n的某个函数,用T(n)表示
若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,
则称f(n)是T(n)的同数量级函数。
记作T(n)=O(f(n)),称O(f(n)) 为算法的渐进时间复杂度,简称时间复杂度。----n是问题的规模
T (n) = Ο(f (n)) 表示存在一个常数C,使得在当n趋于正无穷时总有 T (n) ≤ C * f(n)。
简单来说,就是T(n)在n趋于正无穷时最大也就跟f(n)差不多大,与n无关
也就是说当n趋于正无穷时T (n)的上界是C * f(n)
时间复杂度随n变化情况的比较
//一个简单语句的时间复杂度为O(1)。
int count=0;
//一个循环的时间复杂度为O(n)。
int n=8, count=0;
for (int i=1; i<=n; i++)
count++;
//时间复杂度为O(log₂ n)的循环语句。
int n=8, count=0;
for (int i=1; i<=n; i*=2)
count++;
//时间复杂度为O(n²)的二重循环。
int n=8, count=0;
for (int i=1; i<=n; i++)
for (int j=1; j<=n; j++)
count++;
//时间复杂度为O(nlog₂n)的二重循环。
int n=8, count=0;
for (int i=1; i<=n; i*=2)
for (int j=1; j<=n; j++)
count++;
循环次数为 。
时间复杂度为O(nlog₂n)。
//时间复杂度为O(n)的二重循环。
int n=8, count=0;
for (int i=1; i<=n; i*=2)
for (int j=1; j<=i; j++)
count++;
总的循环次数为 。
时间复杂度为O(n)。
度量算法的空间效率——空间复杂度
空间复杂度指算法在执行时为解决问题所需要的额外内存空间,不包括输入数据所占用的存储空间。
S(n)=O(f(n))
算法设计