20202310肖衍豪 2020-2021-2《数据结构与面向对象程序设计》课程总结
一、课程内容总结
第一章 Java语言基础知识入门
首先学习Java语言要从配置环境开始说起,以下是学习Java的一些命令行操作:dir (directory):列出当前目录下的文件和文件夹及文件信息;
cd (change directory ) :进入指定目录,比如:cd 指定目录路径;
cd..:退回上一级目录;
cd\ (cd反斜线):直接退回到根目录;
md (make directory):创建新目录,比如md NN,结果就是在当前目录下创建名为NN的文件夹;
rd (remove directory):删除文件夹;
del(delete):删除文件;
exit:退出DOS命令行;
Help:想知道某个功能的用法时,输入命令 help 命令名 ,就会列出该功能的使用方法
除了Java的一些便捷操作外,还有Java的环境配置,安装虚拟机、下载安装并破解IDEA集成开发平台,安装运行JDK。以上作为入门Java的工具和基础使用。
第二章 数据与表达式
开始编写Java程序之后,了解其相关语法就是自然而然的事情,刚刚接触Java程序,我们要先学会做注释,注释可理解成为代码程序进行解释说明,提高程序的可读性.且注释不影响程序的执行结果,编译器会忽略注释,但是注释也有规范:注释不能随意的插在一个标识符或关键字之中,要保证程序中最基本元素的完整性,所以注释最好在程序段的空白处插入 。以下是注释的三种形式:
// 在一行内的注释 -----> 一般用于对声明的变量、一行程序的作用做解释说明
/* 一行或多行的注释 */ -----> 多用于说明方法的功能、设计逻辑、基本思想
/** 文档注释 */
接下来还要讲的是标识符,标识符是由字母、数字、下划线(_)、或美元符($)组成的字符串,其中数字不能作表示符的开头。且标识符要区分大小写。标识符可用作变量名、方法名、接口名、类名。(PS: Username username UserName 根据标识符区分大小写的原则可以得出此三种标识符为不同的标识符)以下是对于各类名的命名规则:
1.类名或接口名:多为名词,每个单词的首字母都要大写: UserName;
2.方法名:多为动词,含有大小写,首字母小写,其后的各单词首字母大写: setName;
3.常量名:每个单词所有字母全部大写,并且两个单词之间要用 _ 分隔开: MIX_AGE;
4.变量名:首字母小写,后单词首字母大写.
还有我们的八大数据类型:byte、short、int、long、float、double、char、boolean,知道了它们的字节数、表示范围、类型。接下来还有转义字符:\b \n \r \t,知道了布尔类型只有两种状态
表达式,声明变量有两处:
1、在方法或语句块内 ---- 局部变量 (生命周期---从声明到方法或语句块执行完毕);
2、在类中----->成员变量 / 实例变量 (生命周期---永远伴随着类,从类加载到卸载);
运算符:算术运算符、关系运算符、逻辑运算符、条件运算符、强制类型转化、位运算符
第三章 类与对象
首先是面向对象,有以下三大特征:
(1)封装:保护内部的操作不被破坏;
(2)继承:在原本的基础之上继续进行扩充;
(3)多态:在一个指定的范围之内进行概念的转换。
接下来强调类与对象的基本概念:类是对象的模板,对象是类的实例。类只有通过对象才可以使用,而在开发之中应该先产生类,之后再产生对象。类不能直接使用,对象是可以直接使用的。在Java中定义类,使用关键字class完成,对象.属性是表示调用类之中的属性;
对象.方法是表示调用类之中的方法。再从内存的角度分析,堆内存是保存对象的属性内容。堆内存需要用new关键字来分配空间;栈内存是保存的是堆内存的地址;然后在任何情况下,只要看见关键字new,都表示要分配新的堆内存空间,一旦堆内存空间分配了,里面就会有类中定义的属性,并且属性内容都是其对应数据类型的默认值。最后,引用传递的精髓是同一块堆内存空间,可以同时被多个栈内存所指向,不同的栈可以修改同一块堆内存的内容。
第四章 封装、继承、多态
封装:隐藏对象内部的复杂性,只对外公开简单的接口,便于外界使用,从而提高系统的扩展性、可维护性。
继承:继承是对某一批类的抽象,从而实现对现实世界更好的建模提高代码的复用性。
多态:多态性是指允许不同软件元素对同一消息作出响应,把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。赋值之后,父类型的引用就可以根据当前赋值给它的子对象的特性以不同的方式运作。也就是说,父亲的行为像儿子,而不是儿子的行为像父亲。
第五章 线性表
一、顺序表:
顺序表中的数据元素存储是连续的,内存划分的区域也是连续的。ArrayList底层是数组实现的,底层元素在内存中是按顺序排列的,ArrayList是Java中顺序表的体现。
二、链表
1、单向链表
内存中的对象是随机分布的,对象不但存储了我们要求存储的数据,还持有一个next引用,指向下一个对象,来确定一组对象的逻辑顺序。
2、循环链表
和单向链表一样,只不过最后一个对象的next又指向了第一个对象。
3、双向链表
不但持有next引用,指向下一个对象,还持有一个prev引用,指向上一个对象。
三、两种比较特殊的线性表——栈和队列
1、栈
栈是一种操作受限制的线性表。其限制是仅允许在线性表的尾部进行添加和删除操作,这一端被称为栈顶,另一端称为栈底。向一个栈添加新元素叫压栈,删除元素又称为出栈。
2、队列
队列也是一种操作受限制的线性表。只能从头部删除(取出)元素,从队尾添加元素,进行删除操作的端称为队头,只能从队尾添加元素,队头取出(删除)元素。队列的链表实现是通过子类LinkedList来实现的,Queue接口收窄了LinkedList的访问权限,只提供从队尾,队头等的操作。
第六章 查找和排序
一、查找方法
1.顺序查找
按数组的顺序从前往后一直比较,直到找到目标值返回。
优点:对数组的结构没有特定的要求,算法简单。
缺点:当数组个数n较大时,效率低下。
时间复杂度:最大时间复杂度是O(n),最小时间复杂度是O(1),平均时间复杂度是O(n/2).
2.二分查找
从数组的中间开始查找,若找到目标值则返回;若目标值比中间数小则递归查找前半部分;若目标值比中间数大则递归查找后半部分。
优点:比较次数较少,效率比较高
缺点:只适用于不经常变动有序数组
时间复杂度:O(log(n))
二、排序方法
1.插入排序
将一个数据插入到已经排好序的有序数据中,在有序序列中选出合适的位置插入,从而得到一个新的、个数加一的有序数据。
优点:是稳定的排序方法。
缺点:算法适用于少量数据的排序
时间复杂度为O(n^2)。
2.冒泡排序
每次将相邻的两个数进行比较,如果想升序,则大数往后,反之亦然。
优点:算法简单,稳定算法
缺点:效率低下的排序方法,在数据规模很小时,可以采用;
时间复杂度:无序O(n^2),有序o(1)
3.归并排序
采用分治的思想,通过分割和合并,达到目的
优点:算法简单,稳定算法
平均时间复杂度:O(nlog2n)
空间复杂度:O(n) (用于存储有序子序列合并后有序序列)
4.快速排序
1.先从数列中取出一个数作为基准数。
2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
3.再对左右区间重复第二步,直到各区间只有一个数,是不稳定的算法
快速排序时间复杂度下界为O(nlgn),最坏情况为O(n^2)。在实际应用中,快速排序的平均时间复杂度为O(nlgn)
第七章 树的相关知识以及各种各样的二叉树
一、树
树(tree)是一种抽象数据类型(ADT),用来模拟具有树状结构性质的数据集合。它是由n(n>0)个有限节点通过连接它们的边组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。树的相关术语如下:
1、路径:顺着节点的边从一个节点走到另一个节点,所经过的节点的顺序排列就称为“路径”。
2、根:树顶端的节点称为根。一棵树只有一个根,如果要把一个节点和边的集合称为树,那么从根到其他任何一个节点都必须有且只有一条路径。
3、父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点
4、子节点:一个节点含有的子树的根节点称为该节点的子节点。
5、兄弟节点:具有相同父节点的节点互称为兄弟节点。
6、叶节点:没有子节点的节点称为叶节点,也叫叶子节点。
7、子树:每个节点都可以作为子树的根,它和它所有的子节点、子节点的子节点等都包含在子树中。
8、节点的层次:从根开始定义,根为第一层,根的子节点为第二层,以此类推。
9、深度:对于任意节点n,n的深度为从根到n的唯一路径长,根的深度为0;
10、高度:对于任意节点n,n的高度为从n到一片树叶的最长路径长,所有树叶的高度为0;
二、二叉树
1.定义
我们把每个节点最多有2个children、每个子节点都被标为一个左节点or右节点的标识、左子节点从排序上来说比右子节点更靠前的树称为二叉树。
2.性质
性质1:二叉树第i层上的结点数目最多为2i-1(i>=1)
性质2:深度为k的二叉树至多有2k-1个结点(k>=1)
性质3:包含n个结点的二叉树的高度至少为(log2n)+1
性质4:在任意一棵二叉树中,若终端结点的个数为n0,度为2的结点数为n2,则n0=n2+1
三、满二叉树、完全二叉树和二叉查找树
1.满二叉树
高度为h,并且由2h-1个结点组成的二叉树。
2.完全二叉树
定义:一棵二叉树中,只有最下面两层结点的度可以小于2,并且最下层的叶结点集中在靠左的若干位置上,这样的二叉树称为完全二叉树。
特点:叶子结点只能出现在最下层和次下层,且最下层的叶子结点集中在树的左部。显然,一棵满二叉树必定是一棵完全二叉树,而完全二叉树未必是满二叉树。
3.二叉查找树
定义:二叉查找树又被称为二叉搜索树。设x为二叉查找树中的一个结点,x结点包含关键字key,结点x的key值计为key[x]。如果y是x的左子树中的一个结点,则key[y]<=key[x];如果y是x的右子树的一个结点,则key[y]>=key[x]。
第八章 图
一、相关定义
图:图是由顶点的有穷非空集合和顶点之间边的集合组成。
顶点:图中的数据元素。线性表中我们把数据元素叫元素,树中将数据元素叫结点。
边:顶点之间的逻辑关系用边来表示,边集可以是空的。
无向边:若顶点之间的边没有方向,则称这条边为无向边。
无向图:图中任意两个顶点之间的边都是无向边。
有向边:若从两个顶点的边有方向,则称这条边为有向边,也称弧。
有向图:图中任意两个顶点之间的边都是有向边。
简单图:图中不存在顶点到其自身的边,且同一条边不重复出现。
无向完全图:无向图中,任意两个顶点之间都存在边。
有向完全图:有向图中,任意两个顶点之间都存在方向互为相反的两条弧。
权:与图的边或弧相关的数。
网:带权的图。
度:无向图中,与顶点相关联的边的数目。有向图中,入度表示指向自己的边的数目,出度表示指向其他边的数目,该顶点的度等于入度与出度的和。
路径的长度:一条路径上边或弧的数量。
连通图:图中任意两个顶点都是连通的。
连通分量:无向图中的极大连通子图。
强连通分量:有向图中的极大强连通子图。
生成树:无向图中连通且n个顶点n-1条边叫生成树。
有向树:有向图中一顶点入度为0其余顶点入度为1。
二、存储结构
1.邻接矩阵:用两个数组,一个数组保存顶点集,一个数组保存边集。
2.邻接表:数组与链表相结合的存储方法。
三、图的遍历
1.深度优先遍历:从图中某个顶点出发,访问此顶点,然后从顶点的未被访问的邻接点出发深度优先遍历图,直至图中所有和顶点有路径相通的顶点都被访问到。
2.广度优先遍历:类似于树的层次遍历。
四、最小生成树
1.普里姆(prime):将一个起点加入最小生成树,之后不断寻找与最小生成树相连的边权最小的边能通向的点,并将其加入最小生成树,直至所有顶点都在最小生成树中。
2.克鲁斯卡尔(kluskal):在剩下的所有未选取的边中,找最小边,如果和已选取的边构成回路,则放弃,选取次小边。
五、最短路径
1.迪杰斯特拉算法(Dijkstra):把图中的顶点集合分成两组,第一组为已求出最短路径的顶点集合,第二组是未确定最短路径的顶点集合。
2.弗洛伊德算法(Floyd):
(1)从任意一条单边路径开始。所有两点之间的距离是边的权,如果两点之间没有边相连,则权为无穷大。
(2)对于每一对顶点 u 和 v,看看是否存在一个顶点 w 使得从 u 到 w 再到 v 比已知的路径更短。如果是更新它。
二、作业总结
实验三 面向对象程序设计(1)
参考 http://www.cnblogs.com/rocedu/p/6371315.html#SECUNITTEST
参考http://www.cnblogs.com/rocedu/p/6736847.html
实验三 面向对象程序设计(2)
参考 积极主动敲代码,使用JUnit学习Java (http://www.cnblogs.com/rocedu/p/4837092.html)
参考http://www.cnblogs.com/rocedu/p/6736847.html
以 TDD的方式研究学习StringBuffer,提交你的单元测试用例和测试通过的截图,截图要加上学号水印。
实验三 面向对象程序设计(3)
实验三 Java面向对象程序设计(http://www.cnblogs.com/rocedu/p/4472842.html)
参考http://www.cnblogs.com/rocedu/p/6736847.html
对设计模式示例进行扩充,体会OCP原则和DIP原则的应用,初步理解设计模式
用自己的学号%6进行取余运算,根据结果进行代码扩充:
0:让系统支持Byte类,并在MyDoc类中添加测试代码表明添加正确,提交测试代码和运行结的截图,加上学号水印
1:让系统支持Short类,并在MyDoc类中添加测试代码表明添加正确,提交测试代码和运行结的截图,加上学号水印
2:让系统支持Boolean类,并在MyDoc类中添加测试代码表明添加正确,提交测试代码和运行结的截图,加上学号水印
3:让系统支持Long类,并在MyDoc类中添加测试代码表明添加正确,提交测试代码和运行结的截图,加上学号水印
4:让系统支持Float类,并在MyDoc类中添加测试代码表明添加正确,提交测试代码和运行结的截图,加上学号水印
5:让系统支持Double类,并在MyDoc类中添加测试代码表明添加正确,提交测试代码和运行结的截图,加上学号水印
实验三 面向对象程序设计(4)
提交:单元测试代码和运行成功截图及码云上代码链接,截图要加上学号水印
参考http://www.cnblogs.com/rocedu/p/6736847.html
任务:以TDD的方式开发一个复数类Complex,要求如下:
// 定义属性并生成getter,setter
double RealPart;
double ImagePart;
实验三 面向对象程序设计(5)
使用[WhiteStarUML](http://whitestaruml.sourceforge.net/)对实验二中的代码进行建模,发类图的截图,加上学号水印。
参考http://www.cnblogs.com/rocedu/p/6736847.html
类图中只少两个类。
编写一组程序,要体现一下知识点:
(1)继承
(2)多态
(3)重写
(4)重载
(5)目录创建
(6)文件创建
(7)字节流读写
(8)字符流读写
1.编写自己的ArrayList类
要求:实现增加、删除、修改、查找、判断是否为空、返回list长度等操作。
2.测试。
3.Java Socket编程
4.Java和密码学
5.编写有理数/复数计算器
6.远程有理数计算器
7.远程复数计算器
(1)撰写自己的类;
(2)提供StackADT,ArrayStack(框架),实现ArrayStack里面的剩余方法;
(3)编写测试类,测试所写的方法是否正确。
五、栈应用-进制转换
算法基于原理: N = (N div d)×d + N mod d
例如:(1348)10 = (2504)8 ,其运算过程如下:
N N div 8 N mod 8
1348 168 4
168 21 0
21 2 5
2 0 2
要求输入一个十进制数,转换成任意进制数并输出。
1.画出Prim算法的最小生成树的生成过程
2.画出Kruscal算法的最小生成树的生成过程
3.计算最小权值
评分
(1)Prim(2分)
(2)Kruscal(2分)
要求画出过程
七、最后一次测试
知识点和三道编程题
三、实验报告总结
实验一:linux基础与java开发环境
1、基于命令行进行简单的Java程序编辑、编译、运行和调试。
2、练习Linux基本命令;
3、学习Java程序的JDB调试技能:https://www.cnblogs.com/rocedu/p/6371262.html
4、编写简单的Java程序。
1、 编写简单的计算器,完成加减乘除模运算。
2、要求从键盘输入两个数,使用判定语句选择一种操作,计算结果后输出,然后使用判定和循环语句选择继续计算还是退出。
3、编写测试代码,测试验证。(https://www.cnblogs.com/rocedu/p/4472842.html)
实验三:数据结构与面对对象程序设计
1、 初步掌握单元测试和TDD
2、 理解并掌握面向对象三要素:封装、继承、多态
3、初步掌握UML建模
4.、完成蓝墨云上 (1)-(5)实验。
实验四:JavaSocket 编程
1、Java Socket编程
2、Java和密码学:参考 http://www.cnblogs.com/rocedu/p/6683948.html
3、编写有理数/复数计算器
4、远程有理数计算器
5、远程复数计算器
6、实验报告
实验五和六:线性结构与链表
1、链表练习,要求实现下列功能:通过键盘输入一些整数,建立一个链表;这些数是你学号中依次取出的两位数。 再加上今天的时间。打印所有链表元素, 并输出元素的总数。
2、链表练习,要求实现下列功能:实现节点插入、删除、输出操作;继续你上一个程序, 扩展它的功能;从磁盘读取一个文件,完成相关操作。
3、链表练习,要求实现下列功能:用冒泡排序法或者选择排序法根据数值大小对链表进行排序;
4、在android上实现实验(1)和(2)
5、在android平台上实现实验(3)
实验七:查找与排序
1、定义一个Searching和Sorting类,并在类中实现linearSearch,SelectionSort方法,最后完成测试。
2、重构你的代码
3、把Sorting.java Searching.java放入 cn.edu.besti.cs2023.(姓名首字母+四位学号) 包中(例如:cn.edu.besti.cs1823.G2301)重新编译,运行代码,提交编译,运行的截图(IDEA,命令行两种)
4、参考http://www.cnblogs.com/maybe2030/p/4715035.html ,学习各种查找算法并在Searching中补充查找算法并测试
5、实现排序方法等(至少3个)测试实现的算法(正常,异常,边界)
6、编写Android程序对实现各种查找与排序算法进行测试
实验八:树
1、参考教材PP16.1,完成链树LinkedBinaryTree的实现,自己编写驱动类对自己实现的LinkedBinaryTree进行测试。
2、基于LinkedBinaryTree,实现基于(中序,先序)序列构造唯一一棵二㕚树的功能
3、对自己实现的功能进行测试。
4、自己设计并实现一颗决策树提交测试代码运行截图,要全屏,包含自己的学号信息课下把代码推送到代码托管平台
5、输入中缀表达式,使用树将中缀表达式转换为后缀表达式,并输出后缀表达式和计算结果
实验九:图
1、初始化:根据屏幕提示(例如:输入1为无向图,输入2为有向图)初始化无向图和有向图(可用邻接矩阵,也可用邻接表),图需要自己定义(顶点个数、边个数,建议先在草稿纸上画出图,然后再输入顶点和边数)
2、图的遍历:完成有向图和无向图的遍历(深度和广度优先遍历)
3、 完成有向图的拓扑排序,并输出拓扑排序序列或者输出该图存在环
4、完成无向图的最小生成树(Prim算法或Kruscal算法均可),并输出
5、完成有向图的单源最短路径求解(迪杰斯特拉算法)
四、课程收获与不足
经过一学期的学习Java语言和数据结构的相关知识,我系统深入的形成了一套关于这门学科的体系,在学习过程中感受到了解决代码bug的快乐。在有了上学期的《C语言程序设计基础》这门课的引入之后,接触到更进一步的数据结构就变得容易得多,相比于C语言,我更喜欢Java的简洁、方便。感谢在学习Java这门重要课程的时间里遇到了王志强老师,那幽默风趣的上课风格挺符合我对于课堂的预期,不仅如此王老师还关心着同学们课后的生活,像一个循循善诱、和蔼可亲的大哥哥。但是,在本学期的学习中还存在着一些不足之处,就是遇到一些问题没有及时的解决,对于知识的系统性应用仍然不足,我想虽然这门课程结束了,但是我们在今后的学习中仍要运用上我们这学期打下的基础。最后,再次感谢王志强老师的辛勤培育!