20202311 2021-2022-1《数据结构与面向对象程序设计》课程总结
- 课程内容总结
- 第一章 绪论
1.在程序中适当增加注释有利于人们理解(使用“//”或者“/*”和“*/”);
2.java是大小写敏感的;
3.标识符不能以数字开头;
4.开发程序时遇到的三种错误:编译错误,运行错误,逻辑错误;
5.三种代码:伪代码,产品代码,测试代码;
6.所有java程序都要用类来定义,类是对象的蓝图;
7.面向对象三要素:封装、继承、多态。
-
- 第二章 数据和表达式
1.区别print和println,println输出后光标转到下一行,print不会,我感觉这些主要作用是用于排版;
2.当字符串过长时,可使用‘+’进行连接,每部分字符用“”进行引用;
3.转义字符:用于表示特殊的字符,例如\t表示制表符、\n表示换行、\r表示回车;
4.变量是在内存中用来保存一个特定类型数据值的位置的名称;
5.赋值时,在java语句中不允许类型不一致的赋值;
6.当在声明前使用了final定义说明该标识符为常量,不可改变;
7.基本数据类型分为:整型和浮点型(byte,short,int,long,float,double)、字符类型(char)、布尔类型(boolen);;
8.运算符优先级:相同优先级满足从左到右的结合律;
9.自增、自减运算:i++、i--、++i、--i;
10.基本类型之间的转换分为加宽转换和缩窄转化,要避免缩窄转换,可能会丢失信息;
11.读输入数据:Scanner类(next();nextInt();nextFloat()等),它提供了从不同数据源读入不同类型数据的方法;
12.java使用scanner需加头文件 import java.util.Scanner。
-
- 第三章 类与对象
1.new:返回指向新建对象的引用;
2.多个引用变量可以指向同一个对象;
3.String类的对象不可变,方法有String (String str)、char charAt (int index)、int compareTo (String str)等;
4.包,Java标准类库中的类按包来组织,每个类都属于一个具体的包,8种基本数据类型+void;
5.Random类,伪随机数生成器;
6.Math类,属于静态类,可直接调用方法;
7.格式化输出(NumberFormat,DecimalFormat,printf)
8.枚举类型,将可供选择的数据放在组合里,可以保证不适用非法值;
9.包装类,能够按对象的方式处理基本类型。
-
- 第四章 条件和循环
1.if和if-else语句(可以说是足够熟悉了,啥都要用);
2.浮点数的比较:计算两个差值的绝对值,再与公差进行比较;
3.字符比较:利用Unicode字符集的顺序,数字要联系ASCII表中的编码;
4.对象比较(String类):equals(返回布尔类型)、compareTo(返回一个整型量);
5.switch语句:
switch(x)
{
case :
break;
default:
}
6.while语句:重复执行,直至条件为假,因此要注意不要出现无限循环;
7.使用break可以跳出循环,与continue类似;
8.迭代器:以按需一项项地处理每一个元素,
9.do-while语句(一定会执行一次):
do{
}while()
10.for语句,用于知道确定执行次数。
-
- 第五章 类
1.类:属性(变量/常量)+方法(函数);
2.类是对象的蓝图,对象是类的实例化;
3.UML类图,工具:StarUml、RollingDice;
4.封装:类外部的代码难于访问和修改类内部的变量,可见性修饰符:Public、private、protected(可在继承类中访问);
5.方法的分析:可选的修饰符、返回值类型、指定方法名的标识符、参数列表和方法体;
6.构造方法:与类名相同,无返回值;
7.静态类:
(1)静态变量(static):有时也称类变量,它由类的所有实例共享,在一个对象中修改静态变量的值,就等于修改了其他所有对象中该静态变量的值;
(2)静态方法:不需要为了调用方法而实例化类的一个对象,只能访问静态变量或局部变量;
8.类关系:依赖(类A的方法需要使用类B的方法(-,-Tester))、聚合(has-a关系,聚合关系是依赖关系的特殊形式,this引用);
9.重载根据参数类型与数量确定初始化方法;
10.重写:重新编写父类方法;
11.测试;
12.调试:打印调试、设置断点。
-
- 第六章 圆形用户界面
无
-
- 第七章 数组
1.数组索引从0开始;
2.数组是一个对象,必须要进行实例化;
3.用new实例化,指定大小,之后数组大小不能改变;
4.数组中下标边界自动进行边界检查,确保在有效范围内;
5.第一次声明数组可以使用初值表代替new实例化数组;
6.对象数组的实例化,只是分配了保存引用的空间,每个元素中保存的对象还必须分别实例化;
7.args[0]的值是类名,args是字符串数组;
8.变长参数必须放在形参表的最后;
9.存在二维甚至多维数组,根据需要选择。
-
- 第八章 继承
1.使用extends 继承(提高方法的重用性)父类/子类 super/this;
2.object类是万类之主;
3.java只支持单重继承;
4.重载:根据参数类型与数量确定初始化方法;
5.重写:重新编写父类方法;
6.抽象类=属性(变量/常量/对象)+方法(abstract/disabstract/也可以没有)
-
-
- 抽象类必须使用abstract明确声明
- 如果有,抽象类里的方法必须使用abstract声明
- 也可以没有
- 实现抽象方法使用extends关键字
- 抽象类不能实例化instantiated
-
7.抽象类的子类:实现父类的抽象方法变成具体类,不实现父类抽象方法仍要用abstract修饰。
-
- 第九章 多态
1.多态:多种形态,父类的对象指向子类的对象,调用子类的方法(类继承、接口);
2.多态引用在不同的时候可以指向不同类型的对象;
3.多态引用运行时才将方法调用与它的定义绑定在一起;
4.引用变量可以指向声明继承于它的任意类的任何对象;
5.接口是一组抽象方法,不能被实例化
接口(Comparable,Iterator)
-
-
- 接口类=属性(常量)+方法(抽象【可省略】方法)
- 关键字:implements 必须实现所有的方法
-
6.接口层次:接口可以继承接口;类可以实现接口,但不能继承接口;
7.和class一样,接口可以用来声明对象引用变量;
8.接口引用可以指向实现这个接口的任意类的作何对象;
9.方法的参数可以是多态的。
-
-
- 第十章 异常
-
1.错误和异常代表不常见的或不正确处理的对象;
2.错误(Error)不用捕获;
3.处理异常:在异常发生的地方处理,在程序的其他地方处理;
4.程序中出现异常不捕获异常,程序会崩溃;
5.try-catch 语句: Java中把正常流程放try块中,错误(异常)处理放catch块中,每个catch 子句处理try块中可能抛出的一种特定类型的异常,注意多个catch一定把父类放后面处理;
6.finally语句一定会被执行;
7.如果没有在异常发生处捕获及处理,异常会被传播给调用的方法;
8.throw:方法中抛出Checked Exception,方法声明中必须有throws;
9.Java异常处理是要处理Exception类及其子类;
10.产生RuntimeException的问题在调用代码;
11.I/O异常: 几乎所有的IO API都可能抛出异常(除0、数组越界、找不到类、找不到方法……)。
-
-
- 第十一章 递归
-
1.递归使方法自己调用自己;
2.关键在于用递归的思想考虑问题;
3.数学问题和公式常用递归;
4.递归可以减少代码行数,使思路更清晰,提高效率。
-
-
- 第十二章 算法分析
-
1.渐进复杂度:随着n增加,增长函数中增长最快的项,称之为阶次,用大O表示;
2.循环运行的时间复杂度分析:首先确定阶次再乘以n;
3.大O相同增长函数不一定相同;
4.内外层复杂度均为O(n)则总复杂度为O(n^2)。
-
-
- 第十三章 查找与排序
-
-
- 查找
1.线性查找:设置哨兵在数组开头或结尾,以便提高查找效率;
2.二分查找:从中间开始,要求表是有序的,每次比较后可以减少查找池中的一半元素;
3.分块查找:先二分查找,再线性查找;
4.哈希查找:直接通过关键字找到存储地址,构造哈希函数,可用于加密。
-
- 排序
1.选择排序:分别将每个值放在排好序的最终位置,从而完成一组值的排序;
2.插入排序:将一个具体的值插入到表中已有序的子系列中,从而完成一组值的排序;
3.冒泡排序:重复地比较表中的相邻元素,如果它们不符合要求则交换他们;
4.快速排序:根据一个任意选定的划分元素来对表进行划分,然后再递归地对划分元素两边的字段进行排序,从而完成对表的排序;
5.归并排序:递归地对分表,知道每个子表只含有一个元素时为止,然后再将子表按序合并,从而完成对表的排序,归并趟数为[log2n] O(n*logn)稳定;
6.基数排序:个位、十位、百位......分别比较分组排序。
-
-
- 第十四章 栈
-
1.集合是收集并组织其他对象的对象,它定义了访问及管理成为集合元素的其他对象的而一种具体方式;
2.集合中元素之间的组织方式通常由它们加入集合的次序和元素之间的某些固有的关系决定;
3.栈是一种特殊的线性表,FILO(先进后出)
-
-
- Public void push(T element) //入栈
- Public T pop() //出栈
- Public T peek() //读取栈顶的元素
- Public Boolean isEmpty() //判断栈是否为空
- Public int size() //栈有多少个元素
-
4.栈接口定义为Stack,是对泛型T进行操作的;
5.使用栈计算后缀表达式:从左到右扫描表达式,数入栈,遇到操作符则pop两个数,计算后再push;
6.后缀表达式计算中潜在的异常情况:
-
-
- 入栈时栈满
- 出栈时栈空
- 扫描完表达式时栈中的值多于1个
-
7.定义ArrayStack类来表示基于数组实现的、可保存泛型T对象的栈集合;
8.与有固定大小的数组不一样,链表没有容量上限,被看成是一个动态结构,它的大小总随着所保存的元素个数在变大或变小;
9.链表实现栈:
-
-
- 插入/删除都在栈顶
- Top指向栈顶元素
- 数组可以随机存取,随时取得某个数,但是链表必须从头开始
- 需要遍历链表while(head != null){操作}
-
-
-
- 第十五章 队列
-
1.队列是一个线性集合,它在一端添加元素,在另一端删除元素————先进先出;
2.常用功能:
-
-
- enqueue:将元素插入到队尾
- dequeue:从队头删除元素
- first:检测队头的元素
- isEmpty:判定队列是否为空
- size:断定队列中的元素个数
-
-
-
- 第十六章 树
-
1.树:节点+边;
2.树的度数是指结点的最大度数;
3.基本操作:
-
-
- 查找类
-
getRoot();返回根结点
isEmpty 判断是否为空
depth()
traverse()遍历树(每个元素一次)
-
-
- 插入类
-
tree() 初始化置空树
assign()给当前的结点赋值
insert()插入操作:节点或子树
-
-
- 删除类
-
makeEmpty()将树清空
Delete()删除,节点或子树
4.完全二叉树(满二叉树去掉最下层右边若干结点);
5.树的遍历:
-
-
- 先序遍历
- 中序遍历
- 后序遍历(求深度)
- 层序遍历 :(队列)访问该结点→如果该元素有左孩子,左孩子入队→如果该元素有右孩子,则右孩子入队【循环】
-
6.决策树:用二叉树来表示。
-
-
- 第十七章 二叉查找树
-
1.功能:
-
-
- 查找类:
-
getRoot() 返回根节点
getParent() 返回父结点
getChildCount 返回孩子结点数
getFirstChild() 返回第一个孩子结点
getNextChild() 返回下一个兄弟结点
isEmpty() 判定树是否为空树
depth() 求树的深度
traverse() 遍历树
-
-
- 插入类:
-
tree() 构造函数,初始化置空数
assign() 给当前结点赋值
insert() 插入操作,可以是结点或子树
-
-
- 删除类:
-
makeEmpty() 将树清空
Delete() 删除操作,可以是节点或子树
2.二叉查找树的实现;
3.平衡二叉查找树。
-
-
- 第十八章 堆
-
1.堆是一棵完全二叉树;
2.功能实现:
-
-
- addElement() 向堆中添加一个新元素
- removeMin() 删除最小值,并重构堆
- removeMax() 删除最大值,并重构堆
- findMin() 寻找最小值
-
3.堆排序:可以使用数组形式,最好用顺序结构存储,可分为大顶堆和小顶堆;
4.优先队列:具有更高优先级的项排在前面,具有相同优先级的项按先进先出的规则排列。
-
-
- 第十九章 图
-
-
- 无向图:图中表示边的顶点对是无序的图是无向图,意味着两点间的连接是双向的;
- 有向图:图中的边是顶点的有序对的图为有向图,意味着有向图的边是有方向的边;
- 带权图:图中每条边都对应一个权值的图成为带权图,有时也称为网络;
- 图遍历:广度优先遍历、 深度优先遍历;
- 无向图的最小生成树(Prim算法、Kruscal算法);
- 有向图的拓扑排序;
- 有向图的最短路径求解(迪杰斯特拉算法);
- 图的实现策略:邻接表邻接矩阵。
- 总结所做过的作业
作业1:虚拟机安装
当时装这个可积极了,老早就装完了,但是不知道怎么回事上课那天打不开了,貌似是自己移动了文件,结果自己都找不到了......然后就装了好几个,整得电脑上一堆一样的文件,幸好后来能用了哈哈哈哈good
作业2:第一第二章知识测试
记得不太清楚了,就记得这好像是唯一一次中文题目测试,后边都是英文了
作业3:类和对象测试
貌似答得不太好,有几个概念没有弄懂
作业4:第四和第五章测试
作业5:第六和第七章测试
作业6:实验三的主要内容
主要是理解封装、继承、多态,最终写测试,测试代码的逻辑准确性
作业7:封装继承多态重写重载文件字符字节读写-测试
包含的知识点还是挺多的,好像是一边请教一边写完的代码,感谢善良的uu们
作业8:实验四的主要内容
感觉这次作业超级有趣,感觉密码和远程传输真的是很神奇的东西
作业9:第9/10/11章 继承多态异常
作业10:实现自己的Arraylist
这个作业做的应该是不太好的,主要一开始没有弄懂题目的意思,后来时间要到了,好像就有点应付划水了
作业11:ArrayStack测试
当时不太会写,现在我可以!
作业12:栈应用-进制转换
还挺简单的哈哈哈
作业13、14、15/16:最小生成树,树图测试,Dijkstra算法
这几章听得老认真了,easyeasy【doge】
- 实验报告链接汇总
1.实验一
- 基于命令行和IDE(Intellj IDEA 简易教程](http://www.cnblogs.com/rocedu/p/4421202.html)进行简单的Java程序编辑、编译、运行和调试。(本次实验主要使用命令行的方式)
- 练习Linux基本命令;
- 学习Java程序的JDB调试技能:https://www.cnblogs.com/rocedu/p/6371262.html
- 编写简单的Java程序。
2.实验二
- 编写简单的计算器,完成加减乘除模运算。
- 要求从键盘输入两个数,使用判定语句选择一种操作,计算结果后输出,然后使用判定和循环语句选择继续计算还是退出。
- 编写测试代码,测试验证。
3.实验三
下载安装并使用IDEA,完成下面实验(https://www.cnblogs.com/rocedu/p/6371315.html)。
1. 初步掌握单元测试和TDD
2. 理解并掌握面向对象三要素:封装、继承、多态
3. 初步掌握UML建模
4. 完成蓝墨云上 (1)-(5)实验。
4.实验四
(一)Java Socket编程
1.学习蓝墨云上教材《Java和Android编程》“第16章 输入/输出 ”和“第22章 网络”,学习JavaSocket编程
2.结对编程。结对伙伴A编写客户端SocketClient.java,结对伙伴B编写服务器端。
3.截图加学号水印上传蓝墨云,代码push到码云,并撰写实验报告。
(二)Java和密码学
参考 http://www.cnblogs.com/rocedu/p/6683948.html
以结对的方式完成Java密码学相关内容的学习(帖子中所有代码和相关知识点需要学习)。提交学习成果码云链接和代表性成果截图,要有学号水印。
(三)编写有理数/复数计算器
结对编程,结对伙伴A编写有理数计算器。结对伙伴B编写复数计算器。截图加水印上传蓝墨云,代码push码云。
(四)远程有理数计算器
结对编程,结对伙伴A编程实现客户端,结果伙伴B实现服务器端。
客户端通过键盘输入一个有理数计算的公式(例如:1/4 + 1/6 = ),并把该公式以字符串的形式发送给伙伴B(服务器端),服务器端根据字符串计算出结果为5/12,并把结果返回给客户端A,A收到结果后输出结果。截图加水印上传蓝墨云,代码push码云。
(五)远程复数计算器
结对编程,结对伙伴B编程实现客户端,结果伙伴A实现服务器端。
客户端通过键盘输入一个有理数计算的公式(例如:1/4 + 1/6 = ),并把该公式以字符串的形式发送给伙伴A(服务器端),服务器端根据字符串计算出结果为5/12,并把结果返回给客户端B,B收到结果后输出结果。截图加水印上传蓝墨云,代码push码云。
注意实验四(4)和实验四(5),一个人不能仅实现客户端,必须实现一个客户端和服务器,否则两个实验均不得分!!!
(六)实验报告
在规定时间前发表博客,标题“学号 实验四 《数据结构与面向对象程序设计》实验报告”
5.实验五和六
1.链表练习,要求实现下列功能:
- 通过键盘输入一些整数,建立一个链表;
这些数是你学号中依次取出的两位数。 再加上今天的时间。
例如你的学号是 20172301
今天时间是 2018/10/1, 16:23:49秒
数字就是
20, 17,23,1, 20, 18,10,1,16,23,49
打印所有链表元素, 并输出元素的总数。
在你的程序中,请用一个特殊变量名来纪录元素的总数,变量名就是你的名字。 例如你叫 张三, 那么这个变量名就是
int nZhangSan = 0; //初始化为 0.
做完这一步,把你的程序签入源代码控制(git push)。
2.链表练习,要求实现下列功能:
- 实现节点插入、删除、输出操作;
继续你上一个程序, 扩展它的功能,每做完一个新功能,或者写了超过10行新代码,就签入代码,提交到源代码服务器;
从磁盘读取一个文件, 这个文件有两个数字。
从文件中读入数字1, 插入到链表第 5 位,并打印所有数字,和元素的总数。 保留这个链表,继续下面的操作。
从文件中读入数字2, 插入到链表第 0 位,并打印所有数字,和元素的总数。 保留这个链表,并继续下面的操作。
从链表中删除刚才的数字1. 并打印所有数字和元素的总数。
3.链表练习,要求实现下列功能:
- 使用冒泡排序法或者选择排序法根据数值大小对链表进行排序;
如果你学号是单数, 选择冒泡排序, 否则选择选择排序。
在排序的每一个轮次中, 打印元素的总数,和目前链表的所有元素。
在(2)得到的程序中继续扩展, 用同一个程序文件,写不同的函数来实现这个功能。 仍然用 nZhangSan (你的名字)来表示元素的总数。
4.在android上实现实验(1)和(2)
5.在android平台上实现实验(3)
6.实验七
1.定义一个Searching和Sorting类,并在类中实现linearSearch,SelectionSort方法,最后完成测试。
要求不少于10个测试用例,提交测试用例设计情况(正常,异常,边界,正序,逆序),用例数据中要包含自己学号的后四位,提交运行结果图。
2.重构你的代码。
把Sorting.java Searching.java放入 cn.edu.besti.cs2023.(姓名首字母+四位学号) 包中(例如:cn.edu.besti.cs1823.G2301)
把测试代码放test包中
重新编译,运行代码,提交编译,运行的截图(IDEA,命令行两种)
3.参考http://www.cnblogs.com/maybe2030/p/4715035.html ,学习各种查找算法并在Searching中补充查找算法并测试
提交运行结果截图
4.实现排序方法等(至少3个)
测试实现的算法(正常,异常,边界)
提交运行结果截图(如果编写多个排序算法,即使其中三个排序程序有瑕疵,也可以酌情得满分)
5.编写Android程序对实现各种查找与排序算法进行测试
提交运行结果截图
推送代码到码云(选做,额外加分)
7.实验八
- 参考教材PP16.1,完成链树LinkedBinaryTree的实现(getRight,contains,toString,preorder,postorder)用JUnit或自己编写驱动类对自己实现的LinkedBinaryTree进行测试,提交测试代码运行截图,要全屏,包含自己的学号信息,课下把代码推送到代码托管平台
- 基于LinkedBinaryTree,实现基于(中序,先序)序列构造唯一一棵二㕚树的功能,比如给出中序HDIBEMJNAFCKGL和后序ABDHIEJMNCFGKL,构造出附图中的,用JUnit或自己编写驱动类对自己实现的功能进行测试,提交测试代码运行截图,要全屏,包含自己的学号信息,课下把代码推送到代码托管平台
- 自己设计并实现一颗决策树,提交测试代码运行截图,要全屏,包含自己的学号信息,课下把代码推送到代码托管平台
- 输入中缀表达式,使用树将中缀表达式转换为后缀表达式,并输出后缀表达式和计算结果(如果没有用树,正常评分。如果用到了树,即使有小的问题,也酌情给满分),提交测试代码运行截图,要全屏,包含自己的学号信息
8.实验九
(1) 初始化:根据屏幕提示(例如:输入1为无向图,输入2为有向图)初始化无向图和有向图(可用邻接矩阵,也可用邻接表),图需要自己定义(顶点个数、边个数,建议先在草稿纸上画出图,然后再输入顶点和边数)(2分)
(2) 图的遍历:完成有向图和无向图的遍历(深度和广度优先遍历)(4分)
(3) 完成有向图的拓扑排序,并输出拓扑排序序列或者输出该图存在环(3分)
(4) 完成无向图的最小生成树(Prim算法或Kruscal算法均可),并输出(3分)
(5) 完成有向图的单源最短路径求解(迪杰斯特拉算法)(3分)
- 代码托管链接:
给出statistic.sh的运行结果,统计本学期的代码量
- 课程收获与不足
- 自己的收获
当然最大的收获就是新学了一门计算机语言(虽然自己掌握的不是特别好),同时算是对程序开发初窥门径吧,计算机语言真是一个神奇但是很难的东西。一个学期下来,编程思维有那么一稍稍提高,还是要不断学习,积极敲代码呀。希望有一天能玩上自己做的小程序嘿嘿
- 自己需要改进的地方
自己需要改进的地方可太多了
首先,没有做到积极敲代码吧,课上的理论知识听得倒是挺懂,就是转化成代码和计算机沟通太困难了,尤其是入门的时候,感觉自己啥也不会,代码一个不会敲,脾气倒是见长。后来情况就好一些了哈哈哈
再然后就是没有做到刨根问底吧,就碰到一些不太理解的东西,一开始会收集资料看看,还是学不会那就会选择放弃了,不够持之以恒。
最后一点就是还需要提高自己的学习效率,这学期课业加上一些事务,有点缓不过来,可还是有点“忙里偷闲”,对学习花的时间和专注度不够,这点一定要改进!
最后的最后,感谢王老师的辛勤付出,王老师真是温柔善良宽容大度的超人!
新年快乐