20202302 2021-2022-1 《数据结构与面向对象程序设计》课程总结
课程内容总结
第一章 简要内容
本章为绪论,主要介绍
- Java程序设计语言
- 程序编译运行的步骤
- 理解问题求解的一般方法
- 软件开发的一般过程
- 面向对象技术相关概念
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
- 汇编语言:机器语言的助记符
- 高级语言:可移植
- 第四代语言
编辑器/编译程序和解释程序
开发环境
我们主要使用IDE,不得不说这东西比命令行阳间好多倍!!!!!!
错误
主要分为三类错误
- 编译时错误:语法错误
- 运行时错误:异常处理
- 逻辑错误:可通过调试来定位错误
1.3 问题求解
- 理解问题
- 设计方案
- 考虑方案的选择并优化方案
- 实现方案
- 测试方案并修改存在的问题
1.4 软件开发行为
四个基本的开发行为:
- 建立需求:做什么?
- 生成设计:如何做?
- 实现设计:设计到代码
- 测试:做对没?
三种代码
- 伪代码
- 产品代码
- 测试代码
1.5 面向对象程序设计
重要术语:
- 对象
- 属性
- 方法
- 类
- 面向对象三要素:封装,继承,多态(记不住的不能说是超人的学生)
继承可以复用,用继承实现多态;封装是继承的基础;继承是多态的基础。
第二章 简要内容
2.1 字符串
print及print方法
- Systom.out对象表示输出设备或是文件,默认时指的是屏幕。
- println方法将送给它的信息输出后,将光标换到下一行的行首。
- print方法类似于println,但输出之后不会换到下一行。
字符串连接
字符串链接运算符是加号(+)。
转义字符:一共有7类
- \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.1 创建对象
- new:返回指向新建对象的引用(这里有一个关于“蓝图”的比喻)
- 别名:引用保存的内存地址
3.2 String 类
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方法。
4.1 布尔表达式
控制流:顺序(存储程序)、分支(条件语句,特殊情况、循环(自动化)
4.2 if语句
- if
- if...else
- if...else if ... esle
4.3 数据比较
- 浮点数的比较:计算两个差值的绝对值,在与公差进行比较。
- 字符比较:Unicode顺序,大小写字母,数字要联系ASCII表中的编码。
- 对角比较:equals。
4.4 switch语句(有点像Verilog语言哈哈哈)
switch(){
case :
case :
default:
}
4.5 while语句
break可以跳出多重循环。
4.6 迭代器
迭代器是一个对象,可以使用它的一些方法每次处理集合中的一个元素。也就是说,迭代器可以按需一项项地处理每一个元素。
4.7 do 语句
do ... while
4.8 for 语句
for( ; ; ),与while等价,与C语言中循环的使用较相似
第五章 简要内容
5.1 再谈类和对象
- 类:属性(变量/常量)+方法(函数)。
- 类是对象的抽象\蓝图,而对象是类的具体实例。
5.2 类的剖析
UML类图:实现、关联、聚合、组合、继承。
5.3 封装
public、private,包括this等的使用
5.4 方法的剖析
- return:返回值
- 局部数据:作用域只在其声明所在的方法内。
5.5 静态类成员
- 静态变量(static):有时也称类变量,它由类的所有实例共享,在一个对象中修改静态变量的值,就等于修改了其他所有对象中该静态变量的值。
- 静态方法:不需要为了调用方法而实例化类的一个对象,只能访问静态变量或局部变量。
5.6 类关系
- 依赖
- 聚合
- UML中的表示
- this
5.7 方法设计
- 方法的分解
- 参数传递:传值、传引用
5.8 方法重载
- 参数类型与数量
- 不管返回值
5.9 测试
- 评审
- 缺陷测试:发现错误,质量保证
- 单元测试:模块测试,确保方法的正确性
- 集成测试:系统大组件的正确性
- 系统测试:与需求保持一致性
- 测试驱动开发,在编写方法前先编写测试用例,从而为正在开发的系统提供功能。
5.10 调试
需要熟悉开发环境中的调试方法,找出程序中的错误。
第六章 简要内容
GUI元素
- 在Java中建立一个GUI程序至少需要三类对象:组件、事件、窃(防和谐)听(防和谐)器。
- 四要素:组件、容器、布局、事件
第七章 简要内容
7.1 数组元素
Java中数组索引从0开始。
7.2 数组的声明及使用
- Java数组是对象,要用new实例化,new指定大小,之后数组大小不能改变。如:
int [] arr = new int[2302];
int arr [] = new int[2302];
- Java中访数组元素不能越界,用数组的length属性控制
- 第一次声明数组可以使用初值表代替new实例化数组
7.3 对象数组
对象数组的实例化,只是分配了保存引用的空间,每个元素中保存的对象还必须分别实例化。
7.4 命令行参数
args[0]的值是类名,args是字符串数组。
7.5 二维数组
int[][] arr = new int[M][N];
第八章 简要内容
8.1 创建子类
- extends继承,继承的作用之一是代码复用,Java只支持单继承,不能多继承
- super与this:常用于调用构造方法
8.2 方法的重写
- 重载与重写的区别:
一、定义上的区别:
1、重载是指不同的函数使用相同的函数名,但是函数的参数个数或类型不同。调用的时候根据函数的参数来区别不同的函数。
2、覆盖(也叫重写)是指在派生类中重新对基类中的虚函数(注意是虚函数)重新实现。即函数名和参数都一样,只是函数的实现体不一样。
二、规则上的不同:
1、重载的规则:
①必须具有不同的参数列表。
②可以有不同的访问修饰符。
③可以抛出不同的异常。
2、重写方法的规则:
①参数列表必须完全与被重写的方法相同,否则不能称其为重写而是重载。
②返bai的类型必须一直与被重写的方法的返du类型相同,否则不能称其为重写而是重载。
③访问修饰符的限制一定要大于被重写方法的访问修饰符。
④重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常。
三、类的关系上的区别:
重写是子类和父类之间的关系,是垂直关系;重载是同一个类中方法之间的关系,是水平关系。
子类中的方法与父类一样是重写,可以用@Override从语法上保证
8.3 类层次
-
类层次中公共特性放父类中
-
Object类是所有类的父类,“万类之祖”
-
abstract 与抽象类:抽象类表达抽象概念,不能用new实例化
-
抽象类的子类:实现父类的抽象方法变成具体类,不实现父类抽象方法仍要用abstract修饰
8.4 可见性
8.5 设计继承
final 禁止继承
第九章 简要内容
9.1 后绑定
- 多态引用在不同的时候可以指向不同类型的对象
- 多态引用运行时才将方法调用与它的定义绑定在一起
9.2 通过继承实现多态
- 引用变量可以指向声明继承于它的任意类的任何对象
9.3 接口
- interface,implements 等价于class,extends
- 接口是一组抽象方法,与抽象类一样不能被实例化
- 接口层次:接口可以继承接口;类可以实现接口,但不能继承接口。
- Comparable接口:compareTo()
- Iterator接口:hasNext()、nextZ()
9.4 通过接口实现多态
- 和class一样,接口可以用来声明对象引用变量
- 接口引用可以指向实现这个接口的任意类的作何对象
- 方法的参数可以是多态的
第十章 简要内容
10.1 异常处理
- 错误和异常代表不常见的或不正确处理的对象
- 错误(Error)不用捕获
- 处理异常:在异常发生的地方处理;在程序的其他地方处理
10.2 不捕获异常
- 程序中出现异常不捕获异常,程序会崩溃
- 调用栈跟踪:第一行给出原因,异常类型;栈的第一行给出产生异常的代码(这个般就是产生异常的原因)
10.3 try-catch 语句(IDEA可以自主设定,十分方便)
- Java中把正常流程放try块中,错误(异常)处理放catch块中
- 每个catch 子句处理try块中可能抛出的一种特定类型的异常
- 注意多个catch一定把父类放后面处理
- finally:总会执行,用于资源管理
10.4 异常传播
- 如果没有在异常发生处捕获及处理,异常会被传播给调用的方法
- catch or throw?:throws:自己无法处理,用在方法声明;
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
第十二章 简要内容
12.1 算法效率
计算机系统中最重要的资源之一是CPU时间,完成具体任务的算法效率是决定程序执行速度的一个主要因素。
12.2 增长函数和大O符号
12.3 比较增长函数
第十三章 简要内容
13.1 查找
- 线性查找:可以设置哨兵提高查找效率。
- 二分查找:从中间开始,要求表是有序的,每次比较后可以减少查找池中的一半元素。
13.2 排序
- 选择排序:分别将每个值放在排好序的最终位置,从而完成一组值的排序。
- 插入排序:将一个具体的值插入到表中已有序的子系列中,从而完成一组值的排序。
- 冒泡排序:重复地比较表中的相邻元素,如果它们不符合要求则交换他们。
- 快速排序:根据一个任意选定的划分元素来对表进行划分,然后再递归地对划分元素两边的字段进行排序,从而完成对表的排序。
- 归并排序:递归地对分表,知道每个子表只含有一个元素时为止,然后再将子表按序合并,从而完成对表的排序。
13.3 分析查找和排序算法
- 考虑当问题大小增大时算法的渐进复杂度。
- 考虑每个算法的最优情形和最差情形。
第十四章 简要内容
14.1 集合的介绍
- 集合是收集并组织其他对象的对象,它定义了访问及管理成为集合元素的其他对象的而一种具体方式。
- 集合中元素之间的组织方式通常由它们加入集合的次序和元素之间的某些固有的关系决定。
14.2 栈集合
- 后进先出
- push将元素添加到栈顶
- pop删除栈顶元素
- peek查看栈顶元素
- isEmpty判断栈是否为空
- size判断栈中元素的个数
14.4 栈的ADT
栈接口定义为Stack,是对泛型T进行操作的。
14.5 使用栈:计算后缀表达式
计算机容易识别后缀表达式。
可用栈操作,1.从左到右扫描表达式,2.操作数入栈,3.遇到操作符则pop两个数计算后再push。
14.6 异常
后缀表达式计算中潜在的异常情况:
- 入栈时如果栈满
- 出栈时如果栈空
- 扫描完表达式时栈中的值多于1个
14.8 ArrayStack类
定义ArrayStack类来表示基于数组实现的、可保存泛型T对象的栈集合。
14.10 管理链表
- 访问元素
- 插入结点
- 删除结点
- 哨兵结点
14.11 没有链的元素
- 定义一个独立的结点类,用来将元素连在一起。
- 双向链表。
14.12 使用链实现栈
链表实现栈
- 插入/删除都在栈顶
- Top指向栈顶元素
- 数组可以随机存取,随时取得某个数,但是链表必须从头开始
- 需要遍历链表while(head != null){操作};
14.14 包
第十五章 简要内容
15.1 队列ADT
队列是一个线性集合,它在一端添加元素,在另一端删除元素————先进先出。
接口中一般有以下功能:
- enqueue:将元素插入到队尾。
- dequeue:从队头删除元素。
- first:检测队头的元素。
- isEmpty:判定队列是否为空。
- size:断定队列中的元素个数。
15.2 使用队列:编码K值
Caesar密码是一个简单的加法密码,它将信息中的每个字符按字典序移动k位。
15.3 使用队列:模拟票务柜台
考虑在食堂吃饭排队的场景。
- 提出假设
- 模拟实现
15.4 实现队列:使用链表
使用LinearNode对象的链表实现队列,所不同的是必须在链表的两段进行操作。所以,除了有一个指向链表第一个元素的引用(front),还必须使用第二个引用(rear)指向表的最后一个元素。此外还用一个整型变量count记录队列中的元素个数。
15.5 实现队列:使用数组
为了完善此方法,要使用一个循环数组来实现队列,定义类Circular-ArrayQueue。将数组当做一个环来使用,第一个下标接在最后一个下标的后面。
第十六章 简要内容
16.1 树
数(tree)由一组节点(node)和一组边(edge)构成。
- 子节点
- 兄弟结点
- 满二叉树
- 完全二叉树
16.2 树的遍历
- 先序遍历
- 中序遍历
- 后序遍历
- 层序遍历
16.3 树的实现策略
因为树是非线性结构,需要给予数组来实现。
16.4 二叉树的实现
写了好多好多代码,在实验八中已进行实际操作。
16.5 决策树
简单的决策树可用一棵二叉树来表示。检测时,从根节点的问题开始,根据答案选择适当的路径直至到达叶结点。
第十七章 简要内容
17.1 二叉查找树
查找类:
- getRoot()返回根节点
- getParent()返回父结点
- getChildCount返回孩子结点数
- getFirstChild()返回第一个孩子结点
- getNextChild()返回下一个兄弟结点
- isEmpty()判定树是否为空树
- depth()求树的深度
- traverse()遍历树
插入类:
- tree()构造函数,初始化置空数
- assign()给当前结点赋值
- insert()插入操作,可以是结点或子树
删除类:
- makeEmpty()将树清空
- Delete()删除操作,可以是节点或子树
第十八章 简要内容
18.1 堆
堆是一棵完全二叉树
- addElement(),向堆中添加一个新元素。
- removeMin(),删除最小值,并重构堆。
- removeMax(),删除最大值,并重构堆。
- findMin(),寻找最小值。
18.2 堆排序
可以使用数组形式,用顺序结构存储最为合适。
- 最小堆(小顶堆)
- 最大堆(大顶堆)
18.3优先队列
- 具有更高优先级的项排在前面
- 具有相同优先级的项按先进先出的规则排列。
第十九章 简要内容
19.1 无向图
图中表示边的顶点对是无序的图是无向图,意味着两点间的连接是双向的。
19.2 有向图
图中的边是顶点的有序对的图为有向图,意味着有向图的边是有方向的边。
19.3 带权图
图中每条边都对应一个权值的图成为带权图,有时也称为网络。
19.4 常用的图算法
- 广度优先遍历
- 深度优先遍历
- 无向图的最小生成树(Prim算法或Kruscal算法)
- 有向图的拓扑排序
- 有向图的最短路径求解(迪杰斯特拉算法)
19.5 图的实现策略
- 邻接表
- 邻接矩阵
二、作业内容总结
作业1:第一章第二章测试(云班课)
作业2:类和对象测试(云班课)
作业3:第四章和第五章测试(云班课)
作业4:第六章和第七章测试(云班课)
作业5:封装继承多态重写重载文件字符字节读写-测试(云班课)
作业7:第9/10/11章 继承多态异常(云班课)
作业8:实现自己的ArrayList
自己写的博客:https://www.cnblogs.com/jixiangrong/p/15432762.html
作业9:ArrayStack测试(云班课)
作业10:栈应用-进制转换(云班课)
作业11:安装Android Studio(用Genymotion)
作业12:栈\队列测试(云班课)
作业13:最小生成树测试(云班课)
作业14:树和图(云班课)
作业15:迪杰斯特拉算法测试(云班课)
作业16:快速排序测试(云班课)
三、实验报告链接汇总
实验1.https://www.cnblogs.com/jixiangrong/p/15320048.html
实验2.https://www.cnblogs.com/jixiangrong/p/15354457.html
实验3.https://www.cnblogs.com/jixiangrong/p/15396360.html
实验4.https://www.cnblogs.com/jixiangrong/p/15450354.html
实验5.6。https://www.cnblogs.com/jixiangrong/p/15522250.html
实验7.https://www.cnblogs.com/jixiangrong/p/15541215.html
实验8.https://www.cnblogs.com/jixiangrong/p/15609757.html
实验9.https://www.cnblogs.com/jixiangrong/p/15720891.html
四、代码托管链接
经统计,代码行数为:286+222+630+3155+999+981=6273行
五、课程收获与不足
该怎么说呢,感觉时间真的好快。不知不觉一个学期就过去了,总感觉一个学期还没有做什么,可事实是一个学期的课程和考试都已经结束,无论做得是否完美,不管你学到了多少东西,课程的结束已经成为了既定事实。现在回想这个学期的数据结构与Java课,我感触颇深。
当然,这种感触可能不太能是关于学习内容的感触,因为平心而论,我个人感觉自己对于一些知识点的掌握还是有所欠缺。前半段Java的学习就已经不易,后半段数据结构的进入更是雪上加霜。虽然上课的内容听懂是没有问题,但要说完全掌握,我想自己还是需要继续努力。
先说说一些小感受。上课的时候,自己还是很喜欢听超人讲课的。不过有一说一,在超人一声声“小吉”的呼唤中,每节课自己的注意力还是可以保持一个高水平哈哈哈哈哈哈哈哈哈哈哈哈。最重要的是,超人那我举例子让我理解起来也好上不少,多是一件美事啊。有时候上课的时候还会想着这星期的实验该怎么做,每星期的实验对我来说实在是困难。在这里也感谢班里的几位同学还有几位学长学姐给我的辅助,让我突破了实验中的很多难点。没有他们我的这门课搞不好真的要挂了哈哈哈哈哈哈哈哈哈哈哈哈。话说回来,把“挂了”挂嘴边这件事,恐怕大学生涯只有在超人的课上得以享受了哈哈哈哈哈哈哈哈哈哈哈哈。
其实对于Java的课程,自己还是觉得练习的还是不太够吧。有时候基本思路可以出来,但是在实现时问题很大。虽然把课本的代码敲了敲,但是真正掌握还是需要进一步训练的,也不知道今后还有没有机会……不过对于Java,我还是熟悉了它的结构还有基本用法。尤其是类与对象这些在C语言中没有涉及到的东西,自己还是理解到位的。而Java的便利性也让我印象深刻:当隔壁班的同学在为链表的引用发愁时,我们用一个包就可以解决,不得不说实在是太爽了!我想这也是Java在平常的应用中比C语言要多的一大原因吧。
那么现在来谈谈数据结构。不得不说,数据结构的学习的确让人非常困惑。还记得老师给我们看的那一张图,平静(gao xing)地对大家说:我们数据结构的学习就是这一张图!……然而学期结束了,我对于数据结构还是无法称得上精通。虽然“小吉”在栈、队列、树什么的讲解中贡献不少,但是现实的小吉却是一脸黑人问号。终于在课后弄懂了这些东西的结构,然后在实现的时候又是寸步难行。每每想到这里,一种悲戚伤感的情绪便在我的心头涌起,久久无法释怀。不过值得一提的是,我明白了我学上学期离散数学这门课的意义所在,尤其是在学习图论和树的时候,总有一种似曾相似之感,在理解上可是帮了我的大忙。
说说不足吧,我觉得还是编程能力亟待提升。有时自己明白应该做什么,但不知如何做,这也是这门课最让我痛苦的地方。不过这个学期终于是凭借自己的努力学完了这门课。编程能力的提升并非一朝一夕,我也会将此作为自己今后努力的点。希望与超人再续前缘时,自己不会因此而感到痛苦哈哈哈哈哈哈哈哈哈哈哈哈。
最后,感谢这一学期与我同甘共苦的同学们,还有超人的悉心授课!!!!!!
我们更高处见!!!!