20202316 饶坤《数据结构与面向对象程序设计》课程内容总结
一、课程内容总结
第一章 绪论
本章介绍了Java程序设计语言和基本的程序开发过程。介绍了面向对象的开发方法,包括相关的概念和术语。
了解Java程序设计语言,了解程序编译运行的步骤,理解问题求解的一般方法,了解软件开发的一般过程,了解面向对象技术相关概念,面向对象的程序设计,类是对象的蓝图,虚拟机介绍与安装,IDEA介绍与安装。
- java是一种面对对象的编程语言。
- java编程语言中,程序是由一个及以上的类所组成,类中包含一个及以上个方法。
我们学习到了标识符和保留字
- 常见的标识符有:class、public、static、void、main、String、args、System、out、println等。
- 常见的保留字有:package、this、do、if、throw、boolean、double、protected、else、import等。
我们在程序中可以自己命名程序中的标识符(类啥的)的名字,可以由多个字母,数字,下划线啥的组成,但是要注意不能用数字开头哦!!!!!!!
还有就是Java中的大小写一定要十分的注意,比如abc和ABC是不一样的。你以为你调用的是你写的abc,其实你调用的是你没有写的ABC,恭喜!!报错了,飘红了,全是红色的感叹号。
养成一个良好的习惯——注释代码的含义:“//”或“/* */”或“/** */”,这样你就不会在改代码的时候不知道这一行的代码到底是干嘛的。
//单行注释 /*多行注释*/
嘿嘿嘿 ,学习Java就此开篇。对了 还有虚拟机这个东西真是个好东西,我还记得我往命令行界面塞进去一个鹿的图形。
第二章 数据和表达式
介绍了Java中使用的基本数据类型及执行计算时表达式的使用。
作为Java的开头课,我学到了许多的东西
首先是用的最多的 System.out.print/println(""),其实这个东西吧,基本上十几行代码我就写一个,主要是为了确定下我写的那段代码输出的啥。
然后来到数据类型,大概分为数值型(byte、int、float、double等)、字符型(char)、还有一个叫布尔型(Boolean)的。
加减乘除(+、-、*、/)当然也少不了,在Java中可是有数据的转换的,一定记得先看看等号前后的数据是不是一个类型哦哦哦,不一样的话请适当的转换,不然就等着飘红吧
一些有意思的干货——转义字符:\b:回退键 \t:制表符 \n;换行 \r:回车 \ ":双引号 \ ':单引号 \ \:反斜杠
表达式 运算符优先级:相同优先级满足从左到右的结合律。(这是我之前上课的时候在网上搜的保存下来的图)
还有自增自减运算符,赋值运算符。
还有一个Scanner类方法:next();nextInt();nextFloat();useDelimiter()等,如果Sacnner(System.in)的话,我们就可以到时候在键盘输入我们要的值。
第三章:类与对象
首先是创建一个对象,我们可以用String来创建一个新的对象
String me =new String("饶坤");
其中的new:返回指向新建对象的引用。(一定不能丢掉你的new 对象哦,不然对象就不对了)
知识点:
- 多个引用变量可以指向同一个对象
- String类方法:compareTo (String str);equals(); length()等。
- Random类:伪随机数生成器执行复杂的计算产生随机数。
- Math类:都是静态的方法,我们可以直接的去调用它们。
- 格式化输出——NumberFormat类:有两个方法getCurencyInstance和getPercentInstance返回用于格式化数值的对象。getCurencyInstance返回货币格式对象,getPercentInstance返回百分比格式对象。 DecimalFormat类:按惯例使用new运算符来实例化对象。(都说了new很重要吧)
- 枚举型(enumerad type)如 enum Grade{A,B,C,D,E},虽然我很少用,但是还是十分的实用的。
- 包装器类(wrapper)有Integer.parselnt( ) Integer.toHexString( )等等。定义了一些十分有用的静态常量如Integer类中的MIN_VALUE和MAX_VALUE代表了int的最小值和最大值
第四章:OO设计
这一章来到了封装、继承、多态。
这下面是我之前的实验报告的总结,还是蛮有意思的。
(1)什么是封装?
封装可以隐藏实现细节,使得代码模块化;在面向对象编程上可理解为:把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。
(2)封装的意义?
1封装的意义在于保护或者防止代码(数据)被我们无意中破坏。在面向对象程序设计中数据被看作是一个中心的元素并且和使用它的函数结合的很密切,从而保护它不被其它的函数意外的修改。
2保护数据成员,不让类以外的程序直接访问或修改,只能通过提供的公共的接口访问==>数据封装 。
3方法的细节对用户是隐藏的,只要接口不变,内容的修改不会影响到外部的调用者==> 方法封装。
4当对象含有完整的属性和与之对应的方法时称为封装。
5从对象外面不能直接访问对象的属性,只能通过和该属性对应的方法访问。
6对象的方法可以接收对象外面的消息。
下面是我在网上所看到的一个封装student的程序,别人无法修改(private表示最小访问权)
什么是继承?
继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。其继承的过程,就是从一般到特殊的过程。
通过继承创建的新类称为“子类”或“派生类”。被继承的类称为“基类”、“父类”或“超类”。要实现继承,可以通过“继承”(Inheritance)和“组合”(Composition)来实现。在某些 OOP 语言中,一个子类可以继承多个基类。但是一般情况下,一个子类只能有一个基类,要实现多重继承,可以通过多级继承来实现。
特点:1.复用性的提高 2.子类可以应用分类属性 3.设计程序简单了。子类继承父类属性和方法也可以覆盖父类方法。
什么是多态?
多态是同一个行为具有多个不同表现形式或形态的能力,在同一个接口下,能够使用不同的实例而执行不同操作
特点:1.灵活性2.可扩充性.3.可替换性.
第五章:线性表
我们到这就开始接触栈和队列了,这两个知识点都到很后面的Java程序中都要用到。
首先是队列定义:队列是一种特殊的 线性表,“先进先出(FIFO, First-In-First-Out)”是它的原则,在具体应用中通常用链表或者数组来实现。
队列只允许在后端(称为rear)进行插入操作,在前端(称为front)进行删除操作,Java中定义了java.util.Queue
接口用来表示队列。Java中的Queue
与List
、Set
属于同一个级别接口,它们都是继承于Collection
接口。
队列存储结构的实现有以下两种方式:
- 顺序队列:在顺序表的基础上实现的队列结构;
- 链队列:在链表的基础上实现的队列结构;
两者的区别仅是顺序表和链表的区别,即在实际的物理空间中,数据集中存储的队列是顺序队列,分散存储的队列是链队列。
队列中有其的类,结点类型队列定义为:LinearNode<T>;链队列类型队列定义为:LinkedQueue<T>。(你可以自己写一个类,也可以用系统类T)
队列的实现:
1.阻塞队列
2.非阻塞队列
ArrayList的一些常用的方法:
- add 增加一个元索
- size() 返回队列的大小
- remove 移除并返回队列头部的元素
- element 返回队列头部的元素
- offer 添加一个元素并返回true
- poll 移除并返问队列头部的元素
- peek 返回队列头部的元素
- put 添加一个元素
- take 移除并返回队列头部的元素
队列还是十分基本的逻辑结构,Java中用到它还是比较多,所以我还专门去自己学了好久,但是真正自己完完全全写出一大段代码还是难啊啊啊
第六章:栈
栈是一种线性集合,其元素的添加和删除都是在同一侧进行了,特性是先进后出,后进先出(LIFO)的原则,即只允许在尾巴初插入和删除的线性表。
允许插入和删除的一段叫做栈顶(top),而将另一端称为栈底(bottom)。插入和删除只能从上端先进行
这一节课我们还学了前、中、后缀表示法,我们平常用的最多的是中缀表达法,我在这里举一个例子:(3 + 4) × 5 - 6 (中缀)
这是前缀表达式: - × + 3 4 5 6
这是后缀表达式: 3 4 + 5 × 6 -
这个咋说呢,感觉平常用不到,但是Java中有时候也得用,一般都是用栈来实现。
以下是我上课记+的一些栈的基本的指令
(1)Initstack(a):置a为空栈
(2)Push(b,a):元素b进栈a
(3)Pop(a):删除栈a的顶元素.
(5)Empty(a):判断a是否为空栈
若a为空栈,则Empty(a)为true;否则返回false
栈我算是我学的最好的一章了,虽然还是不熟练,但至少能写出能用的栈。
第七章:查找与排序
查找与排序这一章可是让我的脑袋无限痛苦,天天想天天写天天改。
下面是我在写实验的过程中自己结合课上和网上知识所总结的查找与排序的方法
一、查找
查找算法分类:
1)静态查找和动态查找;
注:静态或者动态都是针对查找表而言的。动态表指查找表中有删除和插入操作的表。
2)无序查找和有序查找。
无序查找:被查找数列有序无序均可;
有序查找:被查找数列必须为有序数列。
七大查找算法总结:
(1)顺序查找 :适合于存储结构为顺序存储或链接存储的线性表。从一端开始,一个一个扫描,依次将扫描到的结点关键字与自己给的值k比较,如果相等则表示查找成功;如果全部都扫描了一边还是没有找到,那就说明出错了。
(2)折半查找/二分查找 用给定值k(关键字)先与中间结点的关键字比较,若相等则查找成功;若不相等,中间节点会将序列分为两个子表,根据k与该中间结点关键字的比较结果确定下一步查找哪个子表,这样递归进行,直到查找到或查找结束发现表中没有这样的结点。注意:元素必须是有序的,如果是无序的则要先进行排序操作
(3)分块查找 这个简单来说哦,就是大块的化小块的-,但是小块的相互之间的有序才行
(4)斐波那契查找
(5)树表查找
(6)哈希查找
(7)插值查找
排序算法总结:
(1)冒泡排序:冒泡排序是一种简单的排序算法。它重复地走访过要排序的数列,每次比较前后两个元素,如果它们的顺序错误就把它们交换过来,最后按一定大小顺序排列。
(2)选择排序:首先在排序序列中找到最大或最小的数,将其放在序列的开头初,然后再次对序列中剩下的数进行相互的比较,选出最大或最小的数,放在刚刚的数的后面,重复至全部排序完成。(这种算法听老师说是十分的稳定的)
(3)插入排序:通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入(这个排序我不是很会,虽然练过但是还是。。)
(4)快速排序:简单来说就是把序列根分为两部分,一部分比另一部分小,然后两边分别排序,最后达到整个排序的结果
(5)堆排序 感觉就是用二叉树来对它的节点的大小进行排序(这个代码太长了,我就没从我的idea中拿出来了)
https://gitee.com/besti-cs/untitled.git
这几个是我曾经写过的排序方法,我感觉我在编写程序上有比较大的进步,还有一些算法我没写过,但是我是之前写实验时查到的,如基数排序、桶排序、计数排序,归并排序 等等
在学这个的时候,我们还学了大O计算法(O(n)),用来计算排序算法的时间复杂度,这个我好像还是没弄懂,欸
第七章:树与二叉树
树(Tree)是n(n>=0)个结点的有限集,当然也有可能时空树(n=0)
对于所有非空树来说,会具有以下的性质
- 有且仅有一个称之为根的结点;
- 除根结点以外的其余结点可分为m(m>0)个互不相交的有限集T1,T2,...,Tm,其中每一个集合本身又是一棵树,并且称为根的子树(SubTree)。
一些有关树的术语:
- 结点:树中的一个独立单元。包含一个数据元素及若干指向其子树的分支。
- 结点的度:结点拥有的子树数。
- 树的度:树的度是树内各结点度的最大值。
- 叶子:度为0的结点称为叶子或终端结点。
- 树的深度:树中结点的最大层次称为树的深度或高度。
- 非终端结点:度不为0的结点称为非终端结点或分支结点。除根结点之外,非终端结点也称为内部结点。
- 双亲和孩子:结点的子树的根称为该结点的孩子,相应地,该结点称为孩子的双亲。
- 兄弟:同一个双亲的孩子之间互称兄弟。
- 堂兄弟:双亲在同一层的结点。
- 祖先:从根到该结点所经分支上的所有结点。
- 子孙:以某结点为根的子树中的任一结点都称为该结点的子孙。
- 层次:结点的层次从根开始定义起,根为第一层,根的孩子为第二层。树中任一结点的层次等于其双亲结点的层次加1。
- 有序树和无序树:如果将树中结点的各子树看成从左至右是有次序的(即不能互换),则称该树为有序树,否则称为无序树。在有序树中最左边的子树的根称为第一个孩子,最右边的称为最后一个孩子。
上课之前时真不知道这些玩意是啥,感觉奇奇怪怪的名词。
还有一些上课讲的树的性质
- 结点数=总度数+1
- 度为m的树或m叉树,第i层至多有m^(i-1)个结点(i>=1)
- 高度为h的m叉树至多有m^h-1/m-1个结点
- 高度为h,度为m的树至少有h+m-1个结点(在中必须有一结点的度为m)
- 二叉树父节点n的左孩子是2n,右孩子是2n+1.
二叉树
二叉树是每个结点最多有两个子树的一种树结构。有左孩子和右孩子哦
二叉树的种类包括(1)完全二叉树 满二叉树最后一行没有满的二叉树,比满二叉树最后一行缺一两个节点。
(2)满二叉树 每一个非终端节点后面都连着两个子节点
(3)平衡二叉树。
最优二叉树(哈夫曼树):这棵树的带权路径长度最小——哈夫曼编码。
第八章:图
图(Graph)是一种复杂的非线性结构,在图结构中,每个元素都可以有零个或多个前驱,也可以有零个或多个后继,也就是说,元素之间的关系是任意的。
下面是上课老师讲的一些内容概况
无向图:图中所有边都是无向边。(没有箭头的边,单纯的连着两个点)
有向图:图中所有边都是有向边。(带着箭头的边)
边的权:图的边带有与边相关的数据。(类似于两点之间的距离数据啥的,也可能表示的是别的意思)
入度以及出度(这要注意是有向图还是无向图哦)
连通图——非连通图、强连通图,弱连通
图的遍历:shangm
广度优先遍历:从一个顶点开始,优先遍历周围区域。
深度优先遍历:从一个顶点开始,优先遍历源节点拓展出的可达结点。
图的表示法:十字链表、邻接矩阵、边集数组、邻接表、邻接多重表 //十字链表好难啊
最小生成树问题(最短的路径):prime算法、Kruska算法、Dijkstra算法(迪杰斯特拉)
拓扑排序(AOV网才行,就连通图里面没有环)
作业总结
这我根据云班课S上面的作业来汇总
作业1:安装虚拟机
作业2:第一章第二章测试
作业3:类和对象测试
作业4:第四章和第五章测试
作业5:第六章和第七章测试
作业6:封装继承多态重写重载文件字符字节读写-测试
作业7:第9/10/11章 继承多态异常
作业8:尾插法
作业9:实现自己的ArrayList
作业10:ArrayStack测试
作业11:栈应用-进制转换
作业12:安装Android Studio
栈\队列测试
最小生成树测试
树和图
迪杰斯特拉算法测试
快速排序测试
实验报告链接汇总
实验一:Linux命令行和编写简单的Java程序
1、基于命令行进行简单的Java程序编辑、编译、运行和调试
2、练习Linux基本命令;
3、学习Java程序的JDB调试技能:https://www.cnblogs.com/rocedu/p/6371262.html
4、编写简单的Java程序。
博客链接:https://www.cnblogs.com/raokun/p/15321882.html
实验二:编写简单的计算器
1.实验内
(1) 编写简单的计算器,完成加减乘除模运算。
(2) 要求从键盘输入两个数,使用判定语句选择一种操作,计算结果后输出,然后使用判定和循环语句选择继续计算还是退出。
(3) 编写测试代码,测试验证。(https://www.cnblogs.com/rocedu/p/4472842.html)
博客链接:https://www.cnblogs.com/raokun/p/15353985.html
实验三:面向对象程序设计
- 初步掌握单元测试和TDD
- 理解并掌握面向对象三要素:封装、继承、多态
- 初步掌握UML建
博客链接:https://www.cnblogs.com/raokun/p/15395963.html
实验四:Java Socket编写
1.实验内容
(一)Java Socket编程
1.学习蓝墨云上教材《Java和Android编程》“第16章 输入/输出 ”和“第22章 网络”,学习JavaSocket编程
2.结对编程。结对伙伴A编写客户端SocketClient.java,结对伙伴B编写服务器端。
3.截图加学号水印上传蓝墨云,代码push到码云,并撰写实验报告。
(二)Java和密码学
参考
以结对的方式完成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),一个人不能仅实现客户端,必须实现一个客户端和服务器,否则两个实验均不得分!!!
(六)实验报告
在规定时间前发表博客,标题“学号 实验四 《数据结构与面向对象程序设计》实验报告”
博客链接:https://www.cnblogs.com/raokun/p/15453590.html
实验五和六:线性结构及链表
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 (你的名字)来表示元素的总数。
博客链接:https://www.cnblogs.com/raokun/p/15514832.html
实验七:查找与排序
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程序对实现各种查找与排序算法进行测试提交运行结果截图推送代码到码云(选做,额外加分)
博客链接:https://www.cnblogs.com/raokun/p/15553003.html
实验八:树
1.参考教材PP16.1,完成链树LinkedBinaryTree的实现(getRight,contains,toString,preorder,postorder)
用JUnit或自己编写驱动类对自己实现的LinkedBinaryTree进行测试,提交测试代码运行截图,要全屏,包含自己的学号信息
课下把代码推送到代码托管平台
2.基于LinkedBinaryTree,实现基于(中序,先序)序列构造唯一一棵二㕚树的功能,比如给出中序HDIBEMJNAFCKGL和后序ABDHIEJMNCFGKL,构造出附图中的树
用JUnit或自己编写驱动类对自己实现的功能进行测试,提交测试代码运行截图,要全屏,包含自己的学号信息
课下把代码推送到代码托管平台
3.自己设计并实现一颗决策树
提交测试代码运行截图,要全屏,包含自己的学号信息
课下把代码推送到代码托管平台
4.输入中缀表达式,使用树将中缀表达式转换为后缀表达式,并输出后缀表达式和计算结果(如果没有用树,正常评分。如果用到了树,即使有小的问题,也酌情给满分)
提交测试代码运行截图,要全屏,包含自己的学号信息
博客链接:https://www.cnblogs.com/raokun/p/15616099.html
实验九:图
(1) 初始化:根据屏幕提示(例如:输入1为无向图,输入2为有向图)初始化无向图和有向图(可用邻接矩阵,也可用邻接表),图需要自己定义(顶点个数、边个数,建议先在草稿纸上画出图,然后再输入顶点和边数)
(2) 图的遍历:完成有向图和无向图的遍历(深度和广度优先遍历)
(3) 完成有向图的拓扑排序,并输出拓扑排序序列或者输出该图存在环
(4) 完成无向图的最小生成树(Prim算法或Kruscal算法均可),并输出
(5) 完成有向图的单源最短路径求解(迪杰斯特拉算法)
博客链接:https://www.cnblogs.com/raokun/p/15711696.html
四、代码托管
代码链接:https://gitee.com/besti-cs/untitled
这里显示我的代码数量有5129,我之前的idea坏掉了,重新弄了一遍,有一些代码没有算进去,虽然我觉得我写的代码应该也不是很多,但是我还是从Java的编写中学到了许多让我难忘的知识,我以后也会努力学习的。
课程收获与不足
java编程真是既让我快乐又让我痛苦,刚开始学习的时候,我还觉得Java十分的简单,可是后来我越深入学习我越感觉到了Java的海洋是真的深不见底啊,我还记得超人说过,如果想要完全教完Java要十年,我的天,这是真难学,但好在我们有敬业的王超人,他就经常从各个地方飞过来解决我们的难题,上课的方式也是十分的幽默有趣,让枯燥无味的课堂多一些活力的色彩,由于自己本身能力的不够,导致课后作业和一些知识点不会。理解不到位,我还去网上找了一些教java的课来看,还有要不就拿着云班课中的资源看啊看啊,直到我大概弄懂之后我再进行相应的代码的编写,怎么说呢,看的过程是痛苦的,敲代码的过程更痛苦,由于学艺不精和粗心大意导致我的代码漏洞百出,总是这里红一块,那里红一块,真是闹心死了,还好idea上面有相应的提示,一些我实在不会的问题也在我问了超人之后得到了完美的解决。我觉得我的Java水平还是有着飞一般的提高,一个学期的Java学习已经过去了,也该和超人说再见,以后得日子我大概可能应该会抽出时间来学Java的,超人放心吧,哈哈哈哈哈。哈。我会不断加强自己的自学能力和编程能力,让自己的Java课没有白上,让超人的努力教学没有白费。还有一点,我觉得我的拖延症的毛病应该改改了,每一次的作业我总是喜欢拖到最后再写,这就导致了我编写程序的时间不充足,编写的代码不够完善完美,有着或多或少的毛病,我一定会努力改变的,加油奥里给!!!!!