20172329 2018-2019-2 《程序设计与数据结构》实验一报告
课程:《程序设计与数据结构》
班级: 1723
姓名: 王文彬
学号:20172329
实验教师:王志强
实验日期:2018年9月30日
必修/选修: 必修
一.实验内容
一、第一个实验要求
- 链表练习,要求实现下列功能:
(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 (你的名字)来表示元素的总数。
四、第四个实验要求
- 数组练习,要求实现下列功能:
(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 (你的名字)来表示元素的总数。
二、实验过程及结果
第一个实验
- 过程:首先这个实验在之前的第四章的时候可以用队列实现,因为本身我们自己队列就是由链表实现的,所以就直接调用了当时自己写的那个类,在里面自己写了各种各样的插入方法。其中为了解决想要把一段需要键入的数字给写进队列,就不得不使用尾插法用一个for循环将其写进循环,同时也要使得题目里所要求的nwangwenbin那个变量可以发挥出它应该有的作用,所以就使用了这样一个循环。
for (int i =0;i<c.length;i++)
{
a.enqueue(c[i]);
}
然后用size()方法把队列的元素个数给输出。
- 代码结果截图:
第二个实验
-
过程:因为需要用链表实现插入,删除,输出等方法,所以在实现这个实验期间,需要解决头插法的实现,因为当时老师讲的头插法我可能用了错误的方式进行了实现,虽然可以进行头插法的实现,但是并没有实际的插入到队列中,所以这是一个待解决的问题,其次,在进行这个实验中,我参考了我同样参考了之前我自己写过的一个类,因为之前自己写的方法都将其定义为了静态,所以每一个方法都是相互独立的,所以为了将nwangwenbin成功发挥出它的作用,我将这些静态方法都做出了适当改变,以便可以成功计数,从而使得size方法写的比较完整。
-
具体代码实现:
(1)插入方法的实现:
public void Firstinsert(Number Head, Number node) {//头插
node.next = Head;
Head = node;
nWangwenbin++;
System.out.print(Head.number+" ");
}
public void insert(Number Head, Number node1, Number node2, Number node) {//中间插
Number point = Head;
while ((point.number != node1.number) && point != null)
{
point = point.next;
}
if (point.number == node1.number) {
node.next = node2;
point.next = node;
}
nWangwenbin++;
}
public void add(Number Head, Number node) {//尾插
Number temp = Head;
while (temp.next != null) {
temp = temp.next;
}
temp.next = node;
nWangwenbin++;
}
(2)删除方法的实现:
public void delet(Number Head, Number node) {
Number p = Head, Curr = Head;
while (Curr != null) {
if (Curr.number != node.number) {
p = Curr;
Curr = Curr.next;
} else {
break;
}
}
p.next = Curr.next;
nWangwenbin--;
}
(3)输出方法实现:
public void print(Number Head) {
Number node = Head;
while (node != null) {
System.out.print(node.number+",");
node = node.next;
}
}
(4)计数方法实现:
public int size(){
return nWangwenbin+1;
}
- 实现结果截图:
第三个实验
-
过程:本实验主要考察我们对于排序法的编写以及理解,能够自己变出一个算法的前提就是要搞清楚这个算法到底是如何进行的,而不是凭空想象或者更随便的从网上抄一段代码来,相信大家都不想让自己做那个吃别人剩下的,因为假如将来我们要从事的是计算机行业,而进入一个企业的一些考验往往就是这些最基础的算法。
-
首先,先来带大家了解一下什么是冒泡排序。
-
(1)原理:比较两个相邻的元素,将值大的元素交换至右端。
-
(2)思路:依次比较相邻的两个数,将小数放在前面,大数放在后面。即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。重复第一趟步骤,直至全部排序完成。
第一趟比较完成后,最后一个数一定是数组中最大的一个数,所以第二趟比较的时候最后一个数不参与比较;
第二趟比较完成后,倒数第二个数也一定是数组中第二大的数,所以第三趟比较的时候最后两个数不参与比较;
依次类推,每一趟比较次数-1; -
形象展示
-
具体代码实现
public Number bubbleSort(Number head){
if(head == null || head.next == null)
return head;
Number cur = null, tail = null;
cur = head;
while(cur.next != tail){
while(cur.next != tail){
if(cur.number > cur.next.number){
int tmp = cur.number;
cur.number = cur.next.number;
cur.next.number = tmp;
}
cur = cur.next;
}
Number node = head;
while (node != null) {
System.out.print(node.number+" ");
node = node.next;
}
System.out.println("该一轮的元素数量为:"+(nWangwenbin-1));
tail = cur;
cur = head;
}
return null;
}
- 实验结果截图
第四个实验
-
过程:第四个实现,旨在让我们用数组实现第一、二个实验所需要的功能,其中我们需要实现的是不仅仅只有插入,删除的方法,还要就这个题目结合自己的代码进行其他方法的处理与编写,以使得自己的代码可以完成其应当有的功能。
-
关键代码显示
public void add(int array[],int a){
if (array[0]==0){
array[0]=a;
}
else {
int i =0;
while (array[i]!=0){
i++;
}
array[i]=a;
}
nwangwenbin++;
}
public int size(){
return nwangwenbin;
}
public void delete(int array[] ) {
System.out.println("请输入想要删除的数字的位置:");
Scanner scan = new Scanner(System.in);
int mes = scan.nextInt();
int pos=mes;
// int pos1=mes;
for (int i = 0; i < size(); i++) {
temp[i] = array[mes];
mes++;
}
for (int i =0;i<size();i++){
array[pos-1]=temp[i];
pos++;
}
nwangwenbin--;
}
public boolean iEmpty(){
if (array[0]==0){
return true;
}
else {
return false;
}
}
public String print(int array[]){
String result="";
for (int i =0;i<size();i++){
result+=array[i]+" ";
}
return result;
}
- 代码结果截图
第五个实验
-
过程:第五个实验旨在用数组实现选择排序,因为之前就已经了解过选择排序,在这里不做详细的讲解。
-
具体代码实现
public void selectsorting(int[] array){
for(int i = 0; i < size() - 1; i++) {
int k = i;
for(int j = k + 1; j < size(); j++){
if(array[j] < array[k]){
k = j;
}
}
if(i != k){
int temp = array[i];
array[i] = array[k];
array[k] = temp;
}
System.out.print("第" + (i + 1) + "轮排序后:");
for (int ii = 0; ii < size(); ii++) {
System.out.print(array[ii] + " ");
}
System.out.println("当前数字串的总数为:"+nwangwenbin);
System.out.print("
");
}
- 具体实现截图
3. 实验过程中遇到的问题和解决过程
-
问题1:在Java文件读出的时候,为什么与扫出来的数字不同?
-
问题1解决方法:
(1)因为从文件读出的属于字节流,读出来的是字节型的,所以我们需要用Stringvalueof
语句将其进行转义为字符串格式,再根据其我们所需要的格式进行改写。 -
问题2:在实现排序过程中每一次要输出该轮的队列或者数组的全部,在实现这一阶段的时候,我发现我知道在哪里输出,但是在第一次进行输出的时候要么只会输出一轮,要么在输出的时候就直接成为了一次死循环。
-
问题2解决方案:在进行选择输出每一轮过后的那个队列或者数组的全部内容的时候,在外循环的内部进行类似于输出方法(print方法)的一个过程,如下关键代码:
while (node != null) {
System.out.print(node.number+" ");
node = node.next;
}
System.out.println("该一轮的元素数量为:"+(nWangwenbin-1));
通过这样一段输出,就可以将其在每一轮进行输出。
- 问题3:在进行实验三的代码编写的过程中,因为本身就要涉及到用数组进行排序,所以我一开始的想法就是直接将键入的一段字符串用空格进行分割再将其分为一个字符串数组,但是在这个过程中,我发现一个问题,因为假如仅仅通过这样的方式将字符串就保存在这一个数组中,其实我们要求中需必须的nwangwenbin的那个变量的作用也就没有了,简单来讲,就是其实每一个数字并不是真正的进入数组,所以,我就不得不另外想一种方法使得它进入数组,使得nwangwenbin进行累加,(ps:这个nwangwenbin变量的大小还涉及着很多方面的因素,因为在输出之类的一些方法中,就是靠size方法进行的,所以这个变量非常重要)
- 问题3解决方法:言归正传,所以,我就仿照链表的做法,继续写了一个尾插的方法,用一个循环将一开始用
split
语句分开的数组进行真正意义上的进入。如下代码:
public void add(int array[],int a){
if (array[0]==0){
array[0]=a;
}
else {
int i =0;
while (array[i]!=0){
i++;
}
array[i]=a;
}
nwangwenbin++;
}
通过这样一段,就可以再用下面的这段扫进实现nwangwenbin的累加:
for (int i =0;i<c.length;i++){
a.add(b,Integer.parseInt(c[i]));
}
通过这样的一段就可以解决我们的问题。
4.感想
做这个实验的时候,因为自己在之前就已经有编写相关代码的过程,所以在编写这五个代码的过程中,自己的自主性得到了提升,不再想上学期一样,一旦不会就去看别人的代码,我觉得自己与上学期相比,有所进步。