数据结构与算法基础
第一章
数据结构与算法基础(青岛大学-王卓)第01周–1.2基本概念与术语1
一、什么是数据结构
数据结构是一门研究非数值计算的程序设计中计算机的操作对象以及它们之间的关系和操作的学科;表树图等具有逻辑关系的数据。
在弄懂之前我们先要明白以下几个概念。
1.1.1 数据
数据:能被计算机处理的各种符号的集合 可分为数值型(如:整数,实数)和非数值型(如:文字、图像、图形、声音等)
1.1.2 数据元素
数据的基本单位,在计算机程序中通常作为一个整体来考虑和处理。(例,某张学生信息表中的一个学生的信息),简称元素,或记录、节点、顶点。
1.1.3 数据项
构成元素不可分割的最小单位。(接上个例子,这个学生姓名就是一个数据项,或者他的学号,性别等)
1.1.4 数据对象
性质相同的数据元素的集合,是数据的一个子集;面向对象编程就是说的这个对象。例:
- 整数数据对象是集合N = { ···,-2,-1,0,1, 2,··· }
- 员工信息表、学籍表也可以看做一个数据对象
数据 | 数据对象 | 数据元素 | 数据项 |
---|---|---|---|
学生信息表 | 张三的所有信息 | 张三的性别等 | |
集合N | 任意一个整数 | ||
总结:数据是最大的集合,数据对象是数据的子集,数据元素是数据或数据对象这两个集合中的一个元素。
数据结构与算法基础(青岛大学-王卓)第01周–1.3基本概念与术语2
二、数据结构
- 数据元素不是孤立存在的,他们互相之间存在着某种关系,这种关系称为结构;
- 数据结构就是指相互之间存在一种或多种特定关系的数据元素的集合
- 或者说是,带结构的数据元素的集合;
2.1数据结构包括以下三个方面的内容
- 数据元素之间的逻辑关系,也成为逻辑结构
- 数据元素及其关系在计算机内存中的映像,也称为物理结构或者存储结构
- 数据的运算和实现,也就是操作数据元素或者操作相应存储结构的实现
2.1.1 逻辑结构与物理结构
逻辑结构:数据元素之间逻辑关系,与存储无关,独立与计算机,是具体问题的数学模型;
物理结构(存储结构):数据元素及其关系,在计算机存储器中的存储方式。是数据结构在计算机中的存在方式。
逻辑结构与物理结构(存储结构)的关系:
物理结构(存储结构)是元素逻辑关系和元素本省的映像;逻辑结构是数据结构的抽象,存储结构是数据结构的事项;两者综合描述了数据元素之间的结构关系。
2.1.2 逻辑结构的划分
分类一:
-
线性结构:
所有节点(数据元素)之间呈线性排列,最多只有一个直接前驱和一个直接后继;
例如:线性表、栈、队列、串
-
非线性结构:
一个节点(数据元素)可能对应多个直接前驱和一个直接后继;
例如:树(人机对弈)、图(地图导航)
分类二:
- 集合结构:结构中的数据元素除了 同属于一个集合 之外没任何关系
- 线性结构:数据元素之间存在一对一的线性关系
- 树结构:数据元素之间存在 一对多 的层次关系(理解为直接父类只有一个)
- 图结构(网状结构):结构中的数据元素之间存在 多对多 的任意关系
2.2.1 存储结构的分类
-
顺序存储结构
用一组连续的存储单元依次存储数据源数,数据元素间的逻辑关系有元素的存储位置来表示;
例:数组[] 首地址来标记指定的内存空间。
-
链式存储结构
用任意存储单元储存数据元素
每个元素不仅储存了自己的地址还存储了下一个元素的地址,数据元素间的逻辑关系用指针来表示。
-
索引存储结构
在存储信息的同时,还建立附加的索引表;
如手机联系人(可通过首字母查找各个联系人信息);
-
散列存储结构
根据节点关键字直接计算除该点的存储地址
| key | 31 | 74 | 70 | 63 | 48 | 94 | 25 | 18 |
| ---- | ---- | ---- | ---- |---- | ---- | ---- | ---- | ---- |
| key %11 | 9 | 8 | 4 | 8 | 5 | 6 | 3 | 7 |得到散列表如下
0 1 2 3 4 5 6 7 8 9 25 70 48 94 18 74 31
数据结构与算法基础(青岛大学-王卓)第01周–1.4抽象数据类型的表示与实现
三、数据类型和抽象数据类型
概念小结:
随着计算机产业发展,其应用领域分为:
-
数值计算领域:加工处理的对象----纯粹的数值
注重如何具体的运算
-
非数值计算领域:加工处理对象为 1.工业检测 2.过程控制 3.管理系统 4.文字处理 等过程中的产生的的 字符、表格、图像、声音 等数据
数据结构研究的就是 非数值计算领域数据的 逻辑结构、存储结构 。
注重如何有效的实现这些数据之间的 运算 关系
数据元素 数据项
数据对象 + 数据元素之间的关系
数据结构 + 对其的操作
逻辑结构 存储结构 抽象数据类型
1.集合结构 1.顺序结构 包括:数据对象
2.线性结构 2.链式结构 数据关系
3.树状结构 3.索引结构 基本操作
4.图形结构 4.散列结构
数据类型的作用:
- 约束变量或常量的取值范围
- 约束变量或常量的操作
3.1.1数据类型(Data Type,DT)
定义:数据类型是一组性质相同的值的集合以及定义与这个值集合上的一组操作的总称。
3.2.1抽象数据类型(Abstract Data Type,ADT)
定义:一个数学模型以及定义在此数学模型的一组操作。
-
由用户定义,从问题抽象出数据模型(逻辑结构)
-
还包括定义在数据模型上的一组操作抽象运算(相关操作)
-
不考虑计算及内部的具体存储结构与运算的具体实现方法。
3.2.2抽象数据类型形式定义
抽象数据类型可用(D,S,P)三元组表示。
其中 D是数据对象;S是D上的关系集,P是对D的基本操作集
ADT 抽象数据类型名{
数据对象:<数据对象的定义>
数据关系:<数据关系的定义>
基本操作:<基本操作的定义>
}ADT 抽象数据类型名
基本操作定义格式:
- 基本操作名(参数表)
- 初始条件<初始条件描述>
- 操作结果<操作结果描述>
3.2.3基本操作定义格式说明:(用伪代码描述)
参数表:赋值参数 只为操作提供输入值
引用参数 以&打头,除可提供输入值外,还将返回操作结果。
*
初始条件:描述操作执行之前数据结构和参数应满足的条件,若不满足,则操作失败,并返回相应出错信息。若初始条件为空,则省略之。
操作结果:说明操作正常完成之后,数据结构变化状况和相应返回的结果。
定义举例:Circle的定义
ADT Circle{
数据对象:D={r,x,y|r,x,y均为实数}
数据关系:R={<r,x,y,>|r是半径,<x,y>是圆心坐标}
基本操作:
Cirlce(&C,r,x,y)
操作结果:构造一个圆
double Area(C)
初始条件:圆已存在。
操作结构:得出面积
double Circumference(C)
初始条件:圆已存在
操作结果:得出周长
}ADT Circle
定义举例:复数的定义
ADT Complex{
D={r1,r2|r1,r2均为实数}
S={<r1,r2>|r1是实部,r2是虚部}
assign(&C,v1,v2)
初始条件:空的复数已存在。
操作结构:构造复数C,r1,r2分别赋值为v1,v2
assign(&Z,v1,v2)
初始条件:空的复数Z已存在。
操作结构:构造复数Z,其实部虚部分别赋值为v1,v2
destroy(&C)
初始条件:复数C已存在。
操作结构:复数C已销毁
destroy(&Z)
初始条件:复数Z已存在。
操作结构:复数Z已销毁
GetReal(Z,&realPart)
初始条件:复数Z已存在。
操作结构:返回实部
GetImag(Z,&ImagPart)
初始条件:复数Z已存在。
操作结构:返回虚部
}ADT Complex
3.3.1在Java中如何实现抽象类数据类型
-
用类来定义描述它的存储结构
-
用方法定义描述它的操作
定义后就可以在JVM中运行使用。
抽象数据类型可以通过固有的数据类型(如整型、浮点型、字符型等)来表示和实现;
即利用基本数据类型和已经定义过的类来说明新的类,调用已经定义过的方法、构造器来组合形成新的方法、构造器;
以java为例:
/*
ADT Complex{
D={r1,r2|r1,r2均为实数}
S={<r1,r2>|r1是实部,r2是虚部}
*/
class Complex{
float realPart;
float imagPart;
/* void assign(&C,v1,v2)
初始条件:空的复数已存在。
操作结构:构造复数C,r1,r2分别赋值为v1,v2
这部分相当于构造器
*/
Complex(float v1, float v2) {
this.realPart = v1;
this.imagPart = v2;
}
/* destroy(&C)
初始条件:复数C已存在。
操作结构:复数C已销毁
这部分操作是GC自动完成的,java中局部变量离开作用域,或者没有被引用的对象会被自动销毁
*/
/* GetReal(Z,&realPart)
初始条件:复数Z已存在。
操作结构:返回实部
*/
Complex getReal(){
return this.realPart;
}
/* GetImag(Z,&ImagPart)
初始条件:复数Z已存在。
操作结构:返回虚部
*/
Complex getImag(){
return this.imagPart;
}
/*
具体赋值以及加减乘除方法
void assign(Complex*A,real,imag)
void add(Complex*A,float real,float imag)//A + B
void minus(Complex*A,float real,float imag)//A - B
void multiply(Complex*A,float real,float imag)//A * B
void divide(Complex*A,float real,float imag)//A / B
赋值:
Complex*A *为指针,Java中去除了指针;视频中的操作:
void assign(Complex*A,real,imag)
A->realPart=real;
A->imagPart=imag;
*/
//等效于Java中,调用如下构造器赋值:
Complex(float real, float imag) {
this.realPart = real;
this.imagPart = imag;
}
Complex A = new Complex(real,imag);//这个创建对象的过程中完成了*A的操作,即变量A的指针指向新创建的对象
/*
void add(Complex*A,float real,float imag)//A + B
*/
//等效于Java中,调用如下构造器:
Complex(Complex a, Complex b) {
this.realPart = a.realPart + b.realPart;
this.imagPart = a.imagPart + b.imagPart