20202301贾奕琦 2020-2021-2《数据结构与面向对象程序设计》课程总结
Java和数据结构课程总结
一、课程内容总结
Java
一、第一周和第二周上课我们用Linux写代码,javac进行编译,Java运行代码。
学习了以下一系列Linux命令:
1:文件管理
ls命令 显示指定工作目录下的内容及属性信息
cp命令 – 复制文件或目录
mkdir命令 – 创建目录
mv命令 – 移动或改名文件
pwd命令 – 显示当前路径
2:文档编辑
cat命令 – 在终端设备上显示文件内容
echo命令 – 输出字符串或提取Shell变量的值
rm命令 – 移除文件或目录
tail命令 – 查看文件尾部内容
grep命令 – 强大的文本搜索工具
3:系统管理
find命令 – 查找和搜索文件
startx命令 – 初始化X-windows
uname命令 – 显示系统信息
4:备份压缩
zip命令 – 压缩文件
unzip命令 – 解压缩zip文件
gzip命令 – 压缩和解压文件
zipinfo命令 – 查看压缩文件信息
gunzip命令 – 解压文件
5:其他命令
hash命令 – 显示与清除命令运行时查询的哈希表
wait命令 – 等待指令
bc命令 – 浮点运算
history命令 – 显示与操纵历史命令
rmmod命令 – 删除模块
以及一系列vim命令:
1、插入命令
i 在当前位置之前插入
I 在当前行首插入
a 在当前位置后插入
A 在当前行尾插入
o 在当前行之后插入一行
O 在当前行之前插入一行
1、移动命令
h 左移一个字符
l 右移一个字符,这个命令一般用w代替。
k 上移一个字符
j 下移一个字符
以上四个命令可以配合数字使用,比如20j就是向下移动20行,5h就是向左移动5个字符。
在Vim中,很多命令都可以配合数字使用,比如删除10个字符用“10x”,在当前位置后插入3个“!”用“3a!”。
w 向前移动一个单词(光标停在单词首部),如果已到行尾,则转至下一行行首。此命令快,可以代替l命令。
b 向后移动一个单词 2b 向后移动2个单词
^ 移动到本行第一个非空白字符上。
0 移动到本行第一个字符上,
f(find)命令也可以用于移动,fx将找到光标后第一个为x的字符,3fd将找到第三个为d的字符。
F 同f,反向查找。
跳到指定行,冒号+行号,回车,比如跳到240行就是 :240+回车。另一个方法是行号+G,比如230G跳到230行。
2、删除命令
nx 删除当前光标开始向后n个字符
X 删除当前字符的前一个字符。
dl 删除当前字符
dh 删除前一个字符
dd 删除当前行
dj 删除上一行
dk 删除下一行
nd 删除当前行开始的n行。
D 删除当前字符至行尾。
4、拷贝和粘贴
yy 拷贝当前行
nyy 拷贝当前后开始的n行,比如2yy拷贝当前行及其下一行。
p 在当前光标后粘贴,如果之前使用了yy命令来复制一行,那么就在当前行的下一行粘贴。
shift+p 在当前行前粘贴
ddp交换当前行和其下一行
xp交换当前字符和其后一个字符
5、剪切命令
ndd 剪切当前行之后的n行。利用p命令可以对剪切的内容进行粘贴
6、退出命令
:wq 保存并退出
ZZ 保存并退出
:q! 强制退出并忽略所有更改
:e! 放弃所有修改,并打开原来文件
二、第三周我们学习了数据和表达式
1、字符串与输出:
字符串用String定义
System.out.println换行输出
System.out.print同行输出
2、Scanner类:获取用户的输入
创建 Scanner 对象的基本语法:Scanner s = new Scanner(System.in);
next() 与 nextLine() 方法获取输入的字符串
3、程序调试
编写程序
使用javac -g -d bin src/名字.java对程序进行编译
对jdb进行初始化
调试程序先要学会设置断点,这样才能让程序停在你感觉有问题的代码处进行排查。学习调试我们要学会设置四种断点:
(1)方法断点
(2)行断点
(3)条件断点
(4)临时断点
通过运行stop in HelloJDB.main命令在main方法开始处设置断点,输入run命令来运行HellJDB.class,程序会在main()的开始处停下
三、第四周我们学习了面向对象设计,有听起来很简单,但是实现起来有点困难的接口(不能实例化;实现必须用implements保留字,必须实现接口中的所有方法)
四、我临时还能想起来的最后一条——传说中记不住会挂科的“封装、继承、多态”还有重写、重载。
1、封装:一个让我们能把(类与方法)和调用分开来完成,能帮助我们更好地解决某些bug的能力。
public/protected(包内)/private
不写默认public
2、继承:extends。
类继承、抽象继承、接口继承(implements)(使用同extends)
类、抽象类(abstract声明、可有可无抽象方法)、接口(interface、abstract可有可无、抽象方法必须有且方法全部为抽象方法!)
将父类和子类分开进行,在进行子类时可以将某些共同特征都写入父类,就可以少些几次特征代码咯,嘻嘻
2、多态:是一个让同一个接口在用不同的实例时执行不同的行为的功能
4、重写Override:让子类改写父类行为的功能
5、重载Overload:可以用同一个名字的不同类型,参数不同。
关于Java的基本知识我暂且先介绍到这里。Java的知识自然不止这些,但就让我硬生生的回忆,有些许困难[cry]
接下来我们进行关于数据结构的知识回忆,在此我们结合某本黑色的书——《Java软件结构与数据结构》和某张非常重要的图
1、线性表:传说中的Linkedlist,元素可以随时添加,一般用数组实现元素的更改。
2、栈:LIFO,只允许在表尾插入和删除的线性表
应用:进行数制的转换和表达式求值(前缀式,中缀式,后缀式)
前缀表示法:运算符在运算两方前面
中缀表达式:正常表达
后缀表达法:运算符在运输两方后面
3、队:FIFO——链式存储(链表)
4、数组:传说中的Array
5、排序:
插入排序:<1>直接插入排序: 从序列第一个元素开始,该元素可以认为已经被排序。取出下一个元素,设为待插入元素,在已经排序的元素序列中从后向前扫描,如果该元素(已排序)大于待插入元素,将该元素移到下一位置。重复步骤2,直到找到已排序的元素小于或者等于待排序元素的位置,插入元素。 重复2,3步骤,完成排序。
<2>折半插入排序:将原序列分成有序区和无序区。a[0…i-1]为有序区,a[i…n] 为无序区。(i从1开始) 从无序区中取出第一个元素,即a[i],使用二分查找算法在有序区中查找要插入的位置索引j。将a[j]到a[i-1]的元素后移,并将a[i]赋值给a[j]。 重复步骤2~3,直到无序区元素为0。
<3>二路插入排序:将原数组第一个元素赋值给A[0],作为标志元素;按顺序依次插入剩下的原数组的元素;将带插入元素与第一个进行比较,偌大于A[0],则插入A[0]前面的有序序列,否则插入后面的有序序列;对前面的有序序列或后面的有序序列进行折半查找;查找到插入位置后进行记录的移动,分别往first方向前移和往final方向移动;插入记录;将排序好的A数组的数据从first到final,按次序赋值回原数组。
<4>希尔排序 dl=n/2:将整个有 n 个元素的数组序列分割分成 gap (gap = n/2) 个子序列,第 1 个数据和第 n/2+1 个数据为一组;一次循环中,在每一个子序列中分别采用直接插入排序;然后缩小间隔 gap,将 gap = gap/2, 然后变为 n/gap 个子序列,重复上述的子序列划分和排序工作;不断重复上述过程,随着序列减少最后变为一个,也就完成了整个排序
交换排序:<1>冒泡排序(默认升序):从尾部开始比较相邻的两个元素,如果尾部的元素比前面的大,就交换两个元素的位置;往前对每个相邻的元素都做这样的比较、交换操作,这样到数组头部时,第 1 个元素会成为最大的元素;重新从尾部开始第 1、2 步的操作,除了在这之前头部已经排好的元素;继续对越来越少的数据进行比较、交换操作,直到没有可比较的数据为止,排序完成。
<2>快速排序:从数列中挑出一个元素,称为 “基准”(pivot);重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
6、树:完全二叉树、满二叉树、二叉排序树、平衡二叉树、最优二叉树
完全二叉树:一棵二叉树中,只有最下面两层结点的度可以小于2,并且最下一层的叶结点集中在靠左的若干位置上。这样的二叉树称为完全二叉树。
特点:叶子结点只能出现在最下层和次下层,且最下层的叶子结点集中在树的左部。显然,一棵满二叉树必定是一棵完全二叉树,而完全二叉树未必是满二叉树。
满二叉树:高度为h,并且由2{h} –1个结点的二叉树
先序遍历、中序遍历、后序遍历:所谓顺序是根的位置
在已知某些遍历的序列求二叉树时:定根先后序,中序分左右
二叉排序树:
特点:左子树小于根节点,右子树大于等于根节点——中序遍历
实现:遍历查找——对根节点与已知节点进行比较,后对左子树或右子树进行比较,直至根节点为所寻节点为止(递归:子函数判断内多次套用子函数;非递归:循环代替套用)
叶子节点的删除:直接删除(eg:p->lchilld=null)
度数为1的节点的删除:指向被删除的左子树或右子树
(eg:p1->rchild=p2->lchild)
度数为2的节点的删除:用后一个或前一个节点(eg:删除2,用1或3替换2的位置)换其位置
平衡二叉树
特点:二叉树节点的左右子树的深度差的绝对值不超过1
节点的左子树深度-右子树深度->平衡因子
堆:完全二叉树插入需重排序(数组实现即可)
堆的任何操作后,都需要重新进行调整
堆排序:(减少关键字的比较次数)
小顶堆:左孩子与右孩子均大于父母节点的值
堆排序:堆删除从根开始删除,将最后一个叶子取代根的位置后重排序,最终可得到升序序列
大顶堆:同小顶堆相反,用顺序存储结构(ArrayList)更合适——便于查找左右孩子与父母
堆调整:从最后一个非终端节点开始筛选,后向左;
任意字符的编码都不是其他字符编码的前缀—变长编码的使用缘由。
最优二叉树/哈夫曼树——带权路径长度:叶子节点的带权路径长度之和最小的树(权值越大的结点离根越近)
输出哈夫曼编码的实现:从叶节点出发,用栈,最后逆序输出
7、图
集合表示:有序偶<V,E>表示,记为G=<V,E>
无方向的用(),有方向的用<>
图的遍历:网络爬虫的搜索问题(树有序,图无序)
广度优先抓取顺序
以距中心节点(自选)的范围看结果:由近到远(队列)——子节点不多,解答树层次不深
深度优先抓取顺序
随机选取中心节点的一条分支顺序遍历,直至走到尽头,再换一条分支(栈存储)
最小生成树:
Prim算法:(加点)选取一个节点v,找到与之相连的最小权值,将节点u加入,后看与<v,u>集合相连最小的权值,将v’加入,后看与<v,u,v’>集合相连最小的权值,重复上述操作(过程中不可形成回路)
<替换:对所有边与权值进行罗列,对高权值且不影响联通的路径进行删除或取代
Kruskal算法:(加边)从边出发,找出权值最小的边进行连接
以集合表示一个连通分量,若联通时判断过非同一联通集合,则做并集,否则换线
Java:设定一个标记值flag,置0则表示尚未联通,置1则表示已联通
判断权重min,判断是否属于同一联通集合,若属于则会构成连通分量,否则则直接连接,将集合修改为相同
最短路径问题
单源最短路径——Dijkstra算法(编程实现)
类比prim算法
多源最短路径
有向无环图
拓扑排序:(AOV网,顶点表示活动,弧表示活动间的优先关系的有向图)
将AOV网中入度为0的顶点依次删除并输出
拓扑序列结果不唯一,且一定不存在环
选择入度为零的结点入栈,进行p.next查看下一位,对入度关系减一,对此时入度为零的点直接入栈,全部完成后,弹栈,重复上述操作,直到全部为空
图的存储:
<1>邻接矩阵:建立一个顶点表(记录各个顶点信息)和一个邻接矩阵(表示各个顶点之间关系)。图的邻接矩阵是一个二位数组A.arcs[n][n]
在有向图的邻接矩阵中,
第i行:以结点vi为尾的弧(即出度边);
第i列:以结点vi为头的弧(即入度边)。
有向图的邻接矩阵可能是不对称的;
顶点的出度 = 第 i 行元素之和
顶点的入度 = 第 i 列元素之和
顶点的度 = 第 i 行元素之和 + 第 i 列元素之和
(无向图类似,只是没有弧的头尾的区别;有权图某行某列写入的不是0、1,而是权或∞)
<2>邻接表:通过链表或者利用数组模拟链表的方式将图的相连接关系表示
加个图更明显地表示它的特点吧!嘻嘻
<3>十字链表:邻接表和逆邻接表的结合。不仅表示头→尾,而且还有尾→头的表示,同样加个图表示一下吧!嘻嘻
<4>临界多重表:无向图的存储方式
便于进行图的边的操作,如:标记或删除
好了!知识的回忆到这里就差不多该告一段落咯!
二、总结做过的作业和博客园链接
作业一:
实验内容
基于命令行进行简单的Java程序编辑、编译、运行和调试。
练习Linux基本命令。
学习Java程序的JDB调试技能:
https://www.cnblogs.com/rocedu/p/6371262.html。
编写简单的Java程序。
20202301 2021-2022-1 《数据结构与面向对象程序设计》实验一报告 - 20202301贾奕琦 - 博客园 (cnblogs.com)
作业二:
实验内容
(1) 编写简单的计算器,完成加减乘除模运算。
(2) 要求从键盘输入两个数,使用判定语句选择一种操作,计算结果后输出,然后使用判定和循环语句选择继续计算还是退出。
(3) 编写测试代码,测试验证。(https://www.cnblogs.com/rocedu/p/4472842.html)
20202301 贾奕琦 实验二 《数据结构与面向对象程序设计》实验报告 - 20202301贾奕琦 - 博客园 (cnblogs.com)
作业三:
实验内容
1. 初步掌握单元测试和TDD
2. 理解并掌握面向对象三要素:封装、继承、多态
3. 初步掌握UML建模
20202301 2021-2022-1 《数据结构与面向对象程序设计》实验三报告 - 20202301贾奕琦 - 博客园 (cnblogs.com)
作业四:
实验内容
(一)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码云。
20202301 《数据结构与面向对象程序设计》实验四报告 - 20202301贾奕琦 - 博客园 (cnblogs.com)
作业五:
实验内容
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)
# 20202301 2021-2022-1 《数据结构与面向对象程序设计》实验五和六报告 - 20202301贾奕琦 - 博客园 (cnblogs.com)
作业六:
实验内容
定义一个Searching和Sorting类,并在类中实现linearSearch,SelectionSort方法,最后完成测试。
要求不少于10个测试用例,提交测试用例设计情况(正常,异常,边界,正序,逆序),用例数据中要包含自己学号的后四位
提交运行结果图。
重构你的代码
把Sorting.java Searching.java放入 cn.edu.besti.cs2023.(姓名首字母+四位学号) 包中(例如:cn.edu.besti.cs1823.G2301)
把测试代码放test包中
重新编译,运行代码,提交编译,运行的截图(IDEA,命令行两种)
参考http://www.cnblogs.com/maybe2030/p/4715035.html ,学习各种查找算法并在Searching中补充查找算法并测试
提交运行结果截图
实现排序方法等(至少3个)
测试实现的算法(正常,异常,边界)
提交运行结果截图(如果编写多个排序算法,即使其中三个排序程序有瑕疵,也可以酌情得满分)
20202301 贾奕琦 2021-2022-1 《数据结构与面向对象程序设计》实验七报告 - 20202301贾奕琦 - 博客园 (cnblogs.com)
作业七:
实验内容
参考教材PP16.1,完成链树LinkedBinaryTree的实现(getRight,contains,toString,preorder,postorder)
用JUnit或自己编写驱动类对自己实现的LinkedBinaryTree进行测试,提交测试代码运行截图,要全屏,包含自己的学号信息
课下把代码推送到代码托管平台
基于LinkedBinaryTree,实现基于(中序,先序)序列构造唯一一棵二㕚树的功能,比如给出中序HDIBEMJNAFCKGL和后序ABDHIEJMNCFGKL,构造出附图中的树
用JUnit或自己编写驱动类对自己实现的功能进行测试,提交测试代码运行截图,要全屏,包含自己的学号信息
课下把代码推送到代码托管平台
自己设计并实现一颗决策树
提交测试代码运行截图,要全屏,包含自己的学号信息
课下把代码推送到代码托管平台
输入中缀表达式,使用树将中缀表达式转换为后缀表达式,并输出后缀表达式和计算结果(如果没有用树,正常评分。如果用到了树,即使有小的问题,也酌情给满分)
提交测试代码运行截图,要全屏,包含自己的学号信息
20202301 2021-2022-1 《数据结构与面向对象程序设计》实验八报告 - 20202301贾奕琦 - 博客园 (cnblogs.com)
作业八:
(1) 初始化:根据屏幕提示(例如:输入1为无向图,输入2为有向图)初始化无向图和有向图(可用邻接矩阵,也可用邻接表),图需要自己定义(顶点个数、边个数,建议先在草稿纸上画出图,然后再输入顶点和边数)(2分)
(2) 图的遍历:完成有向图和无向图的遍历(深度和广度优先遍历)(4分)
(3) 完成有向图的拓扑排序,并输出拓扑排序序列或者输出该图存在环(3分)
(4) 完成无向图的最小生成树(Prim算法或Kruscal算法均可),并输出(3分)
(5) 完成有向图的单源最短路径求解(迪杰斯特拉算法)(3分)
20202301 2021-2022-1 《数据结构与面向对象程序设计》实验九报告 - 20202301贾奕琦 - 博客园 (cnblogs.com)
三、代码托管链接:
我努力了一下午还是没能配置好我的git和IDEA的联系[sad]
所以我去网上百度了直接统计IDEA的代码的方法[sad]
但是即使如此,由于我换了三次IDEA,两次电脑,所以我代码还是损失了好多[再次sad]
我突然想起来,还有一部分代码在码云上,这里附上码云链接:https://gitee.com/jia-yiqi-20202301/jia.git
辛苦老师结合一下了[sad]
四、课程收获与不足
自己的收获(投入,效率,效果等):
在我经历了三次IDEA的替换和两次电脑的替换后,我学会了淡定。救大命啊!我就学个Java和数据结构,到底为啥这么多灾多难啊[sad]!
投入:我觉得我的投入其实并不够,虽然现在已经结课,但我觉得我还有很大的进步空间。
效率:说个真实但是不可行的事实,我在每次作业提交的最后几天效率最高了。嘤嘤嘤~我真的好想改掉我的拖延症啊!
效果:我有很大的进步空间,但我觉得我的进步也有一些的。知识上的进步在上文已经列举出来了,我就在这说一些我的性格上的吧。首先,几次灾难让我学会了要淡定,在经历很多事情时,不要焦躁;再者,在很多难题面前,要学会换个方向和不要过分纠结;最后,要乐观,像超人一样。
自己需要改进的地方:
首先,我还不够淡定;其次,我还是有很严重的拖延症,总觉得期末能挽回自己
平时的短板。
最后一篇报告马上就要结束了。在这一学期能遇到王老师是我的福气,不管在学习还是生活,王老师都教会了我很多东西。未来愿安。