# 20192315 2020-2021-1 《数据结构与面向对象程序设计》课程总结
20192315 2020-2021-1 《数据结构与面向对象程序设计》课程总结
一、课程内容总结
1.1 Java程序设计语言
Java平台:Java SE、Java EE、Java ME
类定义: public class XXX{};
main方法的定义是固定的
public static void main(String [] args){}
注释
//单行注释
/*
多
行
注
释
*/
标识符和保留字
常见的标识符有:class、public、static、void、main、String、args、System、out、println......我们命名的在程序中使用的标识符可以由任意字母、数字、下划线和美元符号组成,但不能以数字开头。
常见的保留字有:package、this、do、if、throw、boolean、double、protected、else、import......
空白:包括空格、制表符和换行符。所有的Java程序都用空白作为程序中使用的字和符号的分隔符。
1.2 程序开发
程序设计语言
机器语言:取决于CPU
汇编语言:机器语言的助记符
高级语言:可移植
第四代语言
编辑器/编译程序和解释程序
三类错误
编译时错误:语法错误
运行时错误:异常处理
逻辑错误:可通过调试来定位错误
1.3 问题求解
理解问题
设计方案
考虑方案的选择并优化方案
实现方案
测试方案并修改存在的问题
1.4 软件开发行为
四个基本的开发行为:
建立需求:做什么?
生成设计:如何做?
实现设计:设计到代码
测试:做对没?
三种代码
伪代码
产品代码
测试代码
1.5 面向对象程序设计
基本术语:
对象
属性
方法
类
面向对象三要素:封装,继承,多态
2. 第二章
2.1 字符串
print及print方法
Systom.out对象表示输出设备或是文件,默认时指的是屏幕。
println方法将送给它的信息输出后,将光标换到下一行的行首。
print方法类似于println,但输出之后不会换到下一行。
字符串连接:"+"。
转义字符
\b:回退键
\t:制表符
\n;换行
\r:回车
\ ":双引号
\ ':单引号
\ \:反斜杠
2.2 变量和赋值
变量:变量名和变量值
赋值:=
常量:final,其值不能改变
2.3 基本数据类型
8 种基本类型(byte,short,int,long,float,double,boolean,char)
6种数字类型(byte,short,int,long,float,double)
4种整数类型(byte,short,int,long),
char占两个字节
boolean只有true和false
2.4 表达式
算术运算:+、-、*、/、%
关系运算:、>、>=、<、<=、==、!=
逻辑运算:&&、||、!
运算符优先级:从左到右的结合律,具有相同优先级的算术运算符从左到右依次计算。表达式中的优先级可以通过圆括号来改变。
自增,自减:i++、i--、++i、--i
2.5 数据转换
基本类型之间的转换:加宽转换与缩窄转换,缩窄转换对比加宽转换,很可能会丢失信息。
赋值转换
提升
强制类型转换
2.6 读输入数据
标准输入System.in
标准输出System.out.println
3. 第三章
3.1 创建对象
new:返回指向新建对象的引用
别名:引用保存的内存地址
3.2 String 类
String (String str)
char charAt (int index)
int compareTo (String str)
3.3 包
Java标准类库中的类按包来组织。每个类都属于一个具体的包。
3.4 Random类
伪随机数生成器执行复杂的计算产生随机数
3.5 Math类
Math类中的方法都是static的可以用Math.XXX()来调用。
3.6 格式化输出
NumberFormat:有两个方法getCurencyInstance和getPercentInstance返回用于格式化数值的对象。getCurencyInstance返回货币格式对象,getPercentInstance返回百分比格式对象。
DecimalFormat:按惯例使用new运算符来实例化对象。
print,println,printf方法。
3.7 枚举类型
列出这个类型的变量的所有可能取值。
常用enum。
3.8 包装类
包装类是一种特殊的基本类型,能够按对象的方式处理基本类型。
自动包装与拆包。
4. 第四章
4.1 布尔表达式
控制流:顺序(存储程序)、分支(条件语句,特殊情况、循环(自动化)
4.2 if语句
if
if...else
if...else if ... esle
4.3 数据比较
浮点数的比较:计算两个差值的绝对值,在与公差进行比较。
字符比较:Unicode顺序,大小写字母,数字要联系ASCII表中的编码。
对角比较:equals。
4.4 switch语句
switch(){
case :
case :
default:
}
4.5 while语句
break可以跳出多重循环。
continue语句也类似,但是要再次计算循环条件,如果仍未真,则再次执行循环体。
4.6 迭代器
迭代器是一个对象,可以使用它的一些方法每次处理集合中的一个元素。也就是说,迭代器可以按需一项项地处理每一个元素。
4.7 do 语句
do ... while
4.8 for 语句
for( ; ; ),与while等价
5. 第五章
5.1 再谈类和对象
类:属性(变量/常量)+方法(函数)。
类是对象的抽象\蓝图,而对象是类的具体实例。
5.2 类的剖析
UML类图:实现、关联、聚合、组合、继承。
5.3 封装
public、private
5.4 方法的剖析
return:返回值
局部数据:作用域只在其声明所在的方法内。
5.5 静态类成员
静态变量(static):有时也称类变量,它由类的所有实例共享,在一个对象中修改静态变量的值,就等于修改了其他所有对象中该静态变量的值。
静态方法:不需要为了调用方法而实例化类的一个对象,只能访问静态变量或局部变量。
5.6 类关系
依赖
聚合
UML中的表示
this
5.7 方法设计
参数传递:传值、传引用
5.8 方法重载
参数类型与数量
不管返回值
5.9 测试
评审
缺陷测试:发现错误,质量保证
单元测试:模块测试,确保方法的正确性
集成测试:系统大组件的正确性
系统测试:与需求保持一致性
测试驱动开发,在编写方法前先编写测试用例,从而为正在开发的系统提供功能。
5.10 调试
6. 第六章
GUI元素
在Java中建立一个GUI程序至少需要三类对象:组件、事件、窃(防和谐)听(防和谐)器。
四要素:组件、容器、布局、事件
7. 第七章
7.1 数组元素
从0开始。
7.2 数组的声明及使用
要用new实例化,new指定大小,之后数组大小不能改变。如:int [] arr = new int[2316];int arr [] = new int[2316];
Java中访数组元素不能越界,用数组的length属性控制
第一次声明数组可以使用初值表代替new实例化数组
7.3 对象数组
对象数组的实例化,只是分配了保存引用的空间,每个元素中保存的对象还必须分别实例化。
7.4 命令行参数
args[0]的值是类名,args是字符串数组。
7.5 变长参数表
7.6 二维数组
8. 第八章
8.1 创建子类
extends继承,继承的作用之一是代码复用,Java只支持单继承
super与this常用于调用构造方法
8.2 方法的重载与重写
定义上的区别:
重载是指不同的函数使用相同的函数名,但是函数的参数个数或类型不同。调用的时候根据函数的参数来区别不同的函数。
覆盖(也叫重写)是指在派生类中重新对基类中的虚函数(注意是虚函数)重新实现。即函数名和参数都一样,只是函数的实现体不一样。
规则上的不同:
重载的规则:
①必须具有不同的参数列表。
②可以有不同的访问修饰符。
③可以抛出不同的异常。
重写方法的规则:
①参数列表必须完全与被重写的方法相同,否则不能称其为重写而是重载。
②返bai的类型必须一直与被重写的方法的返du类型相同,否则不能称其为重写而是重载。
③访问修饰符的限制一定要大于被重写方法的访问修饰符。
④重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常。
类的关系上的区别:
重写是子类和父类之间的关系,是垂直关系;重载是同一个类中方法之间的关系,是水平关系。
子类中的方法与父类一样是重写,可以用@Override从语法上保证
8.3 类层次
类层次中公共特性放父类中
Object类是所有类的父类
abstract抽象类达抽象概念,不能用new实例化
抽象类的子类:实现父类的抽象方法变成具体类,不实现父类抽象方法仍要用abstract修饰
8.4 可见性
8.5 设计继承
9. 第九章
9.1 后绑定
多态引用在不同的时候可以指向不同类型的对象
多态引用运行时才将方法调用与它的定义绑定在一起
9.2 通过继承实现多态
引用变量可以指向声明继承于它的任意类的任何对象
9.3 接口
interface,implements 等价于class,extends
接口是一组抽象方法,与抽象类一样不能被实例化
接口层次:接口可以继承接口;类可以实现接口,但不能继承接口。
Comparable接口:compareTo()
Iterator接口:hasNext()、nextZ()
9.4 通过接口实现多态
和class一样,接口可以用来声明对象引用变量
接口引用可以指向实现这个接口的任意类的作何对象
方法的参数可以是多态的
10. 第十章
10.1 异常处理
错误和异常代表不常见的或不正确处理的对象
错误(Error)不用捕获
处理异常:在异常发生的地方处理;在程序的其他地方处理
10.2 捕获异常
程序中出现异常不捕获异常,程序会崩溃
调用栈跟踪:第一行给出原因,异常类型;栈的第一行给出产生异常的代码(这个般就是产生异常的原因)
10.3 try-catch 语句
Java中把正常流程放try块中,错误(异常)处理放catch块中
每个catch 子句处理try块中可能抛出的一种特定类型的异常
注意多个catch一定把父类放后面处理
finally:总会执行,用于资源管理
10.4 异常传播
如果没有在异常发生处捕获及处理,异常会被传播给调用的方法
catch
throw:方法中抛出Checked Exception,方法声明中必须有throws。
10.5 异常类的层次
Error及其子类写程序不用处理
Java异常处理是要处理Exception类及其子类:
RuntimeException及其子类也不用处理(Unchecked Exception),是免检异常;
产生RuntimeException的问题在调用代码
Multi-catch:类之间不能有继承关系
自定义异常
10.6 I/O异常
几乎所有的IO API都可能抛出异常
异常:除0、数组越界、找不到类、找不到方法……
流:字节流、字符流
标准流:System.in、System.out、System.err
11. 第十一章
11.1 递归思想
11.2 递归程序设计
11.3 使用递归
12. 第十二章
12.1 算法效率
12.2 增长函数和大O符号
计算复杂度
12.3 比较增长函数
13. 第十三章
13.1 查找
线性查找:可以设置哨兵提高查找效率。
二分查找:从中间开始,要求表是有序的,每次比较后可以减少查找池中的一半元素。
分块查找:先二分查找,再线性查找。
哈希查找:直接通过关键字找到存储地址,是的查找时间可以常数级。
散列查找
13.2 排序
选择排序:分别将每个值放在排好序的最终位置,从而完成一组值的排序。
插入排序:将一个具体的值插入到表中已有序的子系列中,从而完成一组值的排序。
冒泡排序:重复地比较表中的相邻元素,如果它们不符合要求则交换他们。
快速排序:根据一个任意选定的划分元素来对表进行划分,然后再递归地对划分元素两边的字段进行排序,从而完成对表的排序。
归并排序:递归地对分表,知道每个子表只含有一个元素时为止,然后再将子表按序合并,从而完成对表的排序。
13.3 分析查找和排序算法
考虑当问题大小增大时算法的渐进复杂度。
考虑每个算法的最优情形和最差情形。
14. 第十四章
14.1 集合的介绍
集合是收集并组织其他对象的对象,它定义了访问及管理成为集合元素的其他对象的而一种具体方式。
集合中元素之间的组织方式通常由它们加入集合的次序和元素之间的某些固有的关系决定。
14.2 栈集合
后进先出
push将元素添加到栈顶
pop删除栈顶元素
peek查看栈顶元素
isEmpty判断栈是否为空
size判断栈中元素的个数
14.3 继承、多态和泛型
14.4 栈的ADT
栈接口定义为Stack,是对泛型T进行操作的。
14.5 使用栈:计算后缀表达式
计算机容易识别后缀表达式。
可用栈操作
从左到右扫描表达式
操作数入栈
遇到操作符则pop两个数计算后再push。
14.6 异常
后缀表达式计算中潜在的异常情况:
入栈时栈满
出栈时栈空
扫描完表达式时栈中的值多于1个
14.7 使用数组实现栈
14.8 ArrayStack类
定义ArrayStack类来表示基于数组实现的、可保存泛型T对象的栈集合。
14.9 将引用作为链
与有固定大小的数组不一样,链表没有容量上限。
链表被看成是一个动态结构,它的大小总随着所保存的元素个数在变大或变小。
14.10 管理链表
访问元素
插入结点
删除结点
哨兵结点
14.11 没有链的元素
定义一个独立的结点类,用来将元素连在一起。
双向链表。
14.12 使用链实现栈
链表实现栈
插入/删除都在栈顶
Top指向栈顶元素
数组可以随机存取,随时取得某个数,但是链表必须从头开始
需要遍历链表while(head != null){操作};
14.13 使用java.util.Stack 类实现栈
14.14 包
15. 第十五章
15.1 队列ADT
队列是一个线性集合,它在一端添加元素,在另一端删除元素————先进先出。
接口中一般有以下功能:
enqueue:将元素插入到队尾。
dequeue:从队头删除元素。
first:检测队头的元素。
isEmpty:判定队列是否为空。
size:断定队列中的元素个数。
15.2 使用队列:编码K值
Caesar密码
15.3 使用队列:模拟票务柜台
提出假设、模拟实现
15.4 实现队列:使用链表
使用LinearNode对象的链表实现队列,所不同的是必须在链表的两段进行操作。所以,除了有一个指向链表第一个元素的引用(front),还必须使用第二个引用(rear)指向表的最后一个元素。此外还用一个整型变量count记录队列中的元素个数。
15.5 实现队列:使用数组
使用一个循环数组来实现队列,定义类Circular-ArrayQueue。将数组当做一个环来使用,第一个下标接在最后一个下标的后面。
16. 第十六章
16.1 树
节点+边
子节点
兄弟结点
满二叉树
完全二叉树
16.2 树的遍历
先序遍历
中序遍历
后序遍历
层序遍历
16.3 树的实现策略
数组
16.4 二叉树的实现
16.5 决策树
简单的决策树可用一棵二叉树来表示。诊断时,从根节点的问题开始,根据答案选择适当的路径直至到达叶结点。
17. 第十七章
17.1 二叉查找树
查找类:
getRoot()返回根节点
getParent()返回父结点
getChildCount返回孩子结点数
getFirstChild()返回第一个孩子结点
getNextChild()返回下一个兄弟结点
isEmpty()判定树是否为空树
depth()求树的深度
traverse()遍历树
插入类:
tree()构造函数,初始化置空数
assign()给当前结点赋值
insert()插入操作,可以是结点或子树
删除类:
makeEmpty()将树清空
Delete()删除操作,可以是节点或子树
17.2 二叉查找树的实现
17.3 平衡二叉查找树
18. 第十八章
18.1 堆
完全二叉树
addElement(),向堆中添加一个新元素。
removeMin(),删除最小值,并重构堆。
removeMax(),删除最大值,并重构堆。
findMin(),寻找最小值。
18.2 堆的实现
18.3 堆排序
可以使用数组形式,用顺序结构存储最为合适。
最小堆(小顶堆)
最大堆(大顶堆)
18.4 优先队列
具有更高优先级的项排在前面
具有相同优先级的项按先进先出的规则排列。
19. 第十九章
19.1 无向图
图中表示边的顶点对是无序的图是无向图,意味着两点间的连接是双向的。
19.2 有向图
图中的边是顶点的有序对的图为有向图,意味着有向图的边是有方向的边。
19.3 带权图
图中每条边都对应一个权值的图成为带权图,有时也称为网络。
19.4 常用的图算法
广度优先遍历
深度优先遍历
无向图的最小生成树(Prim算法或Kruscal算法)
有向图的拓扑排序
有向图的最短路径求解(迪杰斯特拉算法)
19.5 图的实现策略
邻接表
邻接矩阵
二、作业总结
作业1:安装虚拟机
作业2:第一周作业
对专业的认识和期望
虚拟机安装
Linux命令的学习
实验楼Linux命令实践学习
作业3:使用VIM编辑器编写Java程序
任务1:使用VIM编辑器编写Java程序。要求输入2个Int类型的数值m和n,当m不为0时,计算(m!)+(m的n次方),并输出。当m为0时提示重新输入。
任务2:使用VIM编辑器编写Java程序。要求输入1个Int类型的数值n。当m>0时,输出一个m行的三角形(丑或漂亮的三角形都行)。当m小于等于0时提示重新输入。
作业4:编写简单的类
编写一个类(书、人、动物、汽车、球员、游课程、戏角色等),定义类的属性和方法。
编写测试类(暂用包含main方法的类),new一个上面类的对象并初始化,然后调用类的属性和方法。
编译运行通过,代码传到码云。
作业5:复数计算器
实现复数类加减乘除运算和比较大小,要求使用Comparable接口、要求自定义接口、要求使用继承。
作业6:类继承作业
编写一个类,要求实现继承,可以以游戏、书籍、球员、复数等为例。
必须包含至少1个抽象方法。
必须测试,测试参数来自命令行参数。
简单测试一下Object类的方法。
要求能够实现两个对象的比较(Comparable接口)
作业7:栈实践
用数组实现自己的栈,ArrayStackADT,需要包含栈的常规操作(push、pop、peek、size、isEmpty等),并测试。
作业8:二分查找实践
给Searching类添加二分查找算法的递归实现方法。创建驱动程序来演示这个实现机制。
编程实现递归。
创建一个测试类,测试递归实现的二分查找是否正确。
作业9:排序
使用选择和插入排序法,写出第3次排序的结果:3 1 9 3 6 2 10。
作业10:查找及ASL作业
给定关键字序列19 14 23 1 68 20 84 27 55 11 10 79,试分别用顺序查找、折半查找、二叉排序树查找、散列查找(用线性探查法和链地址法)来实现查找。试画出它们的对应存储形式(顺序查找的顺序表,二分查找的判定树,二叉排序树查找的二叉排序树,两种散列查找的散列表),并求出每一种查找的成功平均查找长度。其中,散列函数H(k)=k%13。
作业11:树计算
有1023个结点的完全二叉树,其高度是多少?叶结点数是多少?
高度为h的完全二叉树至少有多少个结点?至多有多少个结点?
已知一棵度为m的树中有n1个度为1的结点,n2个度为2的结点,…,nm个度为m的结点,问该树中有多少个叶结点?
作业12:二叉树的建立和层序遍历法实践
给定一个序列AB#CD###E#F##建立一颗树,根据“二叉树的生成”算法构造这颗树。
使用层序遍历方法完成遍历并测试。
作业13:哈夫曼编码测试
画出哈夫曼树,写出各个叶子节点的编码。
作业14:地图染色问题
给图染色,具体算法如下:
将图的结点按照度数递减的次序排列。
用第一种颜色对第一个结点着色,并按照结点排列的次序对与前面着色点不邻接的每一点着以相同颜色。
用第二种颜色对尚未着色的点重复步骤2,直到所有点着色完为止。
作业15:Dijkstra(迪杰斯特拉)算法测试
使用Dijkstra(迪杰斯特拉)算法计算单源(V1出发)最短路径。
作业16:最小生成树测试
画出Prim算法的最小生成树的生成过程
画出Kruscal算法的最小生成树的生成过程
计算最小权值
作业17:哈夫曼编码实践
设有字符集:S={a,b,c,d,e,f,g,h,i,j,k,l,m,n.o.p.q,r,s,t,u,v,w,x,y,z}。
给定一个包含26个英文字母的文件,统计每个字符出现的概率,根据计算的概率构造一颗哈夫曼树。
并完成对英文文件的编码和解码。
要求:
(1)准备一个包含26个英文字母的英文文件(可以不包含标点符号等),统计各个字符的概率
(2)构造哈夫曼树
(3)对英文文件进行编码,输出一个编码后的文件
(4)对编码文件进行解码,输出一个解码后的文件
(5)撰写博客记录实验的设计和实现过程,并将源代码传到码云
(6)把实验结果截图上传到云班课
三、实验报告总结
实验一:linux命令行和编写简单java程序
基于命令行和IDEA(Intellj IDEA 简易教程]进行简单的Java程序编辑、编译、运行和调试。
练习Linux基本命令;
学习Java程序的JDB调试技能
编写简单的Java程序。
实验二:编写简单的计算器
编写简单的计算器,完成加减乘除模运算。
要求从键盘输入两个数,使用判定语句选择一种操作,计算结果后输出,然后使用判定和循环语句选择继续计算还是退出。
编写测试代码,测试验证。
实验三:面向对象程序设计
初步掌握单元测试和TDD
理解并掌握面向对象三要素:封装、继承、多态
初步掌握UML建模
实验四:Java Socket编程与密码学
Java Socket编程
Java和密码学
编写有理数/复数计算器
远程有理数计算器
远程复数计算器
实验五:Android程序设计
Android Stuidio的安装测试
Activity测试
UI测试
布局测试
事件处理测试
实验六:线性结构之链表
通过键盘输入一些整数,建立一个链表
实现节点插入、删除、输出操作
使用冒泡排序法或者选择排序法根据数值大小对链表进行排序
在android上实现以上操作
实验七:查找与排序
定义一个Searching和Sorting类,并在类中实现linearSearch,SelectionSort方法,最后完成测试
重构你的代码
参考http://www.cnblogs.com/maybe2030/p/4715035.html ,学习各种查找算法并在Searching中补充查找算法并测试
补充实现课上讲过的排序方法:希尔排序,堆排序,二叉树排序等
编写Android程序对实现各种查找与排序算法进行测试
实验八:树
参考教材完成链树LinkedBinaryTree的实现(getRight,contains,toString,preorder,postorder)
基于LinkedBinaryTree,实现基于(中序,先序)序列构造唯一一棵二㕚树的功能,比如给出中序HDIBEMJNAFCKGL和后序ABDHIEJMNCFGKL,构造出附图中的树
自己设计并实现一颗决策树
输入中缀表达式,使用树将中缀表达式转换为后缀表达式,并输出后缀表达式和计算结果
实验九:图
初始化:根据屏幕提示(例如:输入1为无向图,输入2为有向图)初始化无向图和有向图(可用邻接矩阵,也可用邻接表),图需要自己定义(顶点个数、边个数,建议先在草稿纸上画出图,然后再输入顶点和边数)
图的遍历:完成有向图和无向图的遍历(深度和广度优先遍历)
完成有向图的拓扑排序,并输出拓扑排序序列或者输出该图存在环
完成无向图的最小生成树(Prim算法或Kruscal算法均可),并输出
完成有向图的单源最短路径求解(迪杰斯特拉算法)
哈夫曼编码实践
- 给出statistic.sh的运行结果,说明本学期的代码量目标达到没有?
代码总量约为5200行,没有达到预期的目标,还是缺少一定的练习。
-
加点代码,改点代码是理解的最好方式,参考编程的智慧,谈谈你的心得
我赞同,这样能够在很大程度上提高任务完成效率,并且能汲取百家所长为我所用并有所收获。 -
积极主动敲代码做到没?教材实践上有什么经验教训?
并未做到,基本上都是为了完成任务而去写代码,缺乏积极性,要多看教材,回归课本,且多练习方能学好学精。
课程收获与不足
- 收获与不足
- 收获:学会了自主学习和自我钻研。
- 不足:编程能力有待提高,练习量还是太少。
- 自己需要改进的地方
容易因找不到出错源或是解决不了系统提供问题就心浮气躁,这点需要改进,以及需要多看课本。 - 结对学习是不是真正贯彻了?写一下你提供的帮助或接受了什么帮助,并对老师提供参考建议
没有贯彻,本学期的结对学习我只是参考了他人的运行模式,然后自己独自完成了双方代码的编写和运行,希望下一次可以真正做到结对学习。
问卷调查
你平均每周投入到本课程有效学习时间有多少?
12个小时左右。
每周的学习效率有提高吗?你是怎么衡量的?
有提高,代码写完后调试时间占比不断下降。
蓝墨云班课的使用对你的学习有促进吗?有什么建议和意见吗?
有促进,上边有很多视频和PPT等学习资源,能够让我在课前及时预习或是在课上没听懂的情况下课后进行再学习。建议资源视频多放一些全套性课程而非只取其中部分知识点章节。
你觉得这门课老师应该继续做哪一件事情?
继续教我们!
你觉得这门课老师应该停止做哪一件事情?
无。