20192312 2019-2020-2《数据结构与面向对象程序设计》课程总结
课程内容总结
第一章 绪论
- Java是面向对象程序设计语言
- 注释: 应阐明程序编写目的并描述处理步骤
- 标识符: 由数字、字母、下划线及美元符号组成(数字不能做开头)(习惯上定义常数大写),空白: 空格键、Tab键、回车换行键(单词与符号的分隔符)
- 计算机语言发展:机器语言、汇编语言、高级语言、第四代语言,Java语言是高级语言
- 错误:1.编译时错误 2.运行时错误 逻辑错误:编译运行没有问题,但是得到的结果与预期不符
- 四个基本的开发行为: 1. 建立需求 2. 生成设计 3. 实现设计 4. 测试
- 基本术语:对象 属性 方法 类 封装 继承 多态
- 类是对象的蓝图
第二章 数据和表达式
- print及prinlnt方法
- 字符串连接:"+"
- 转义字符:\b:回退键 \t:制表符 \n;换行 \r:回车 \ ":双引号 \ ':单引号 \ \:反斜杠
- 变量声明:通知程序预留位置并标志存储位置名称
- 变量名=(赋值)变量值
- 常量:final,其值不能改变
- 基本数据类型: 8种(byte,short,int,long,float,double,boolean,char)
- boolean只有true和false
- 算术运算:+、-、*、/、%, 关系运算:、>、>=、<、<=、==、!=, 逻辑运算:&&、||、!
- 运算符优先级:相同优先级满足从左到右的结合律。
- 自增,自减:i++、i--、++i、--i
- 基本类型之间的转换:避免缩窄转换,可能会丢失信息。
- System.in 与System.out.println
- Scanner类方法:next();nextInt();nextFloat();useDelimiter()等
第三章
- new:返回指向新建对象的引用
- 多个引用变量可以指向同一个对象
- String类方法:compareTo (String str);equals();length()等。
- Java标准类库中的类按包来组织。每个类都属于一个具体的包。
- Random类:伪随机数生成器执行复杂的计算产生随机数
- Math类:方法都是静态的,可以直接调用。
- NumberFormat类:有两个方法getCurencyInstance和getPercentInstance返回用于格式化数值的对象。getCurencyInstance返回货币格式对象,getPercentInstance返回百分比格式对象。
- DecimalFormat类:按惯例使用new运算符来实例化对象。
- print,println,printf方法(printf属于C,便于移植)。
第四章
- if与if-else语句
- 浮点数的比较:计算两个差值的绝对值,在与公差进行比较。
- 字符比较:Unicode顺序,大小写字母,数字要联系ASCII表中的编码。
- 对角比较:equals。
- switch语句:switch()
- while语句 break跳出循环。
- do-while 语句:do{}while();
- for 语句:for( ; ; ),与while等价
第五章
- 类:属性(变量/常量)+方法(函数)。
- 类是对象的抽象\蓝图,而对象是类的具体实例。
- UML类图:实现、关联、聚合、组合、继承。
- 封装public、private
- 静态类
1.静态变量(static):有时也称类变量,它由类的所有实例共享,在一个对象中修改静态变量的值,就等于修改了其他所有对象中该静态变量的值。
2.静态方法:不需要为了调用方法而实例化类的一个对象,只能访问静态变量或局部变量。 - 类关系:依赖,聚合
- 方法重载与重写:重载:根据参数类型与数量确定初始化方法 重写:重新编写父类方法
- 测试
第八章
- extends继承,代码复用,Java只支持单继承
- super与this常用于调用构造方法
- 方法重载与重写:重载:根据参数类型与数量确定初始化方法 重写:重新编写父类方法
- Object类是所有类的父类
- abstract抽象类达抽象概念,不能用new实例化
- 抽象类的子类:实现父类的抽象方法变成具体类,不实现父类抽象方法仍要用abstract修饰
第九章
- 多态引用在不同的时候可以指向不同类型的对象
- 多态引用运行时才将方法调用与它的定义绑定在一起
- 引用变量可以指向声明继承于它的任意类的任何对象
- 接口是一组抽象方法,与抽象类一样不能被实例化
- 接口层次:接口可以继承接口;类可以实现接口,但不能继承接口。
- Comparable接口:compareTo()
- 和class一样,接口可以用来声明对象引用变量
- 接口引用可以指向实现这个接口的任意类的作何对象
- 方法的参数可以是多态的
第十章
- 错误和异常代表不常见的或不正确处理的对象
- 错误(Error)不用捕获
- 处理异常:在异常发生的地方处理;在程序的其他地方处理
- 程序中出现异常不捕获异常,程序会崩溃
- try-catch 语句: Java中把正常流程放try块中,错误(异常)处理放catch块中,每个catch 子句处理try块中可能抛出的一种特定类型的异常,注意多个catch一定把父类放后面处理, finally:总会执行,用于资源管理
- 如果没有在异常发生处捕获及处理,异常会被传播给调用的方法
- throw:方法中抛出Checked Exception,方法声明中必须有throws。
- Java异常处理是要处理Exception类及其子类:
- 产生RuntimeException的问题在调用代码
- I/O异常: 几乎所有的IO API都可能抛出异常
第十三章
查找
- 线性查找:设置哨兵在数组开头或结尾,以便提高查找效率。
- 二分查找:从中间开始,要求表是有序的,每次比较后可以减少查找池中的一半元素
- 分块查找:先二分查找,再线性查找
- 哈希查找:直接通过关键字找到存储地址。
- 散列查找
排序
- 选择排序:分别将每个值放在排好序的最终位置,从而完成一组值的排序。
- 插入排序:将一个具体的值插入到表中已有序的子系列中,从而完成一组值的排序。
- 冒泡排序:重复地比较表中的相邻元素,如果它们不符合要求则交换他们。
- 快速排序:根据一个任意选定的划分元素来对表进行划分,然后再递归地对划分元素两边的字段进行排序,从而完成对表的排序。
- 归并排序:递归地对分表,知道每个子表只含有一个元素时为止,然后再将子表按序合并,从而完成对表的排序。
第十四章
- 栈:先进后出
- 栈常见方法
- push():将元素添加到栈顶
- pop():删除栈顶元素
- peek():查看栈顶元素
- isEmpty():判断栈是否为空
- size():判断栈中元素的个数
- 使用栈计算后缀表达式:从左到右扫描表达式,操作数入栈,遇到操作符则pop两个数计算后再push。
- 链表:与有固定大小的数组不一样,链表没有容量上限。
- 链表被看成是一个动态结构,它的大小总随着所保存的元素个数在变大或变小。
第十五章
- 队列是一个线性集合,它在一端添加元素,在另一端删除元素————先进先出。
第十六章
- 树:节点+边
- 完全二叉树(满二叉树也是完全二叉树)
- 树的遍历: 先序遍历、 中序遍历、 后序遍历、 层序遍历
- 二叉树的实现
- 决策树:用二叉树来表示。
第十七章
- 二叉查找树: 查找、插入、 删除
- 二叉查找树的实现
- 平衡二叉查找树
第十八章
- 堆:完全二叉树(根节点小于左右孩子)
- 堆的实现
- 堆排序
- 优先队列:具有更高优先级的项排在前面,具有相同优先级的项按先进先出的规则排列。
第十九章
- 无向图:图中表示边的顶点对是无序的图是无向图,意味着两点间的连接是双向的。
- 有向图:图中的边是顶点的有序对的图为有向图,意味着有向图的边是有方向的边。
- 带权图:图中每条边都对应一个权值的图成为带权图,有时也称为网络。
- 图遍历:广度优先遍历、 深度优先遍历
- 无向图的最小生成树(Prim算法或Kruscal算法)
- 有向图的拓扑排序
- 有向图的最短路径求解(迪杰斯特拉算法)
- 图的实现策略:邻接表邻接矩阵
二、作业总结
作业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的运行结果,说明本学期的代码量目标达到没有?
代码总量约为6800行,没有达到预期的目标,还是缺少一定的练习。 - 加点代码,改点代码是理解的最好方式,参考编程的智慧,谈谈你的心得
确实,这样能很大程度上减少构架体系和编写的时间,同时能很好的学习到一些思维更巧妙,代码效率更高的方法,但是我觉得最好开始还是要从基本的做起,要不然在平时编写以及修改代码时总会出现很多基本错误。 - 积极主动敲代码做到没?教材实践上有什么经验教训?
我觉得还差一点,总是很难挤出一定的整块时间留代码的学习,教材上的代码很多在IDEA中并不能实现,需要自己去重新运用。
课程收获与不足
- 收获与不足
收获:我觉得自己最大的收获就是学会了自主学习。以前上课对老师的依赖度很高,现在遇到不会的能够自己寻找有关资料进行学习。
不足:感觉自己的编程能力还不行,在经过理论学习后能理解解决问题的思路,但将之转变成代码真的废了很多时间,尤其是调试上,总是因为没有考虑到这样或者那样的方面导致异常,又不断调试。每次作业代码编写很快,但有时要花几个小时调试各种情况。 - 自己需要改进的地方
缺乏练习的时间,还有总是没有提前构思好整个的架构就去敲代码,在发现新的问题在原有架构上难以实现时又要花费很多时间重新编写。 - 结对学习是不是真正贯彻了?写一下你提供的帮助或接受了什么帮助,并对老师提供参考建议
几乎没有,实验四中要求结对学习才有了交互,但平时很少,几乎都是自己学习。接受的帮助是实验四的结对传输,以及有时会参考别的同学的思路。我觉得可以适当的增加一些需要结对完成的作业。
问卷调查
- 你平均每周投入到本课程有效学习时间有多少?
16个小时左右 - 每周的学习效率有提高吗?你是怎么衡量的?
有提高,经过一定时间的学习,花费在调试上的时间越来越少,虽然还是占了很大的部分,但很多问题在提前思考后节约了很多时间。 - 蓝墨云班课的使用对你的学习有促进吗?有什么建议和意见吗?
有,我觉得老师上课用到的PPT对解决问题提供思路很有帮助,可以每一章节都放进去,还有课堂一些没有详细介绍的但书上有涉及的部分,也希望能有PPT以供学习,比起教材官方晦涩的语言,PPT更简单明确,更好理解。 - 你觉得这门课老师应该继续做哪一件事情?
结合具体代码讲解相关的理论知识,这样在理解代码时更加清楚。 - 你觉得这门课老师应该停止做哪一件事情?
无,都挺好。