20202314 实验五和六 《数据结构与面向对象程序设计》实验报告
# 20202314 2021-2022-1 《数据结构与面向对象程序设计》实验四报告
课程:《程序设计与数据结构》
班级: 2023
姓名: 王鑫垚
学号:20202314
实验教师:王志强
实验日期:2021年10月28日
必修/选修: 必修
一、实验内容
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)
二、实验过程及其结果
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. 并打印所有数字和元素的总数。 -
import java.util.Scanner; import java.io.*; public class test { public static void main(String[] args)throws Exception { Linked exam = new Linked(); System.out.println("请输入以下学号与当前时间(202110xxxxxxx)"); System.out.println("输入“99”停止"); Scanner scan = new Scanner(System.in); String at = scan.nextLine(); exam.addFirst(at); while (!at.equals("99")){ at=scan.nextLine(); if (at.equals("99")){ break; } exam.add(at, exam.getSize()); } System.out.println(exam); System.out.println("共有"+exam.getSize()+"个元素"); String path1 = "D:\\1.txt"; String path2 = "D:\\2.txt"; FileInputStream fileInputStream1 = new FileInputStream(path1); BufferedReader bufferedReader1 = new BufferedReader(new InputStreamReader(fileInputStream1)); FileInputStream fileInputStream2 = new FileInputStream(path2); BufferedReader bufferedReader2 = new BufferedReader(new InputStreamReader(fileInputStream2)); String a; String b; a=bufferedReader1.readLine(); b=bufferedReader2.readLine(); /*从文件中读入数字1, 插入到链表第 5 位,并打印所有数字,和元素的总数。 保留这个链表,继续下面的操作。*/ /*从文件中读入数字2, 插入到链表第 0 位,并打印所有数字,和元素的总数。 保留这个链表,并继续下面的操作。*/ /*从链表中删除刚才的数字1. 并打印所有数字和元素的总数。*/ exam.add(a,4); System.out.println(exam); System.out.println("共有"+exam.getSize()+"个元素"); exam.addFirst(b); System.out.println(exam); System.out.println("共有"+exam.getSize()+"个元素"); exam.remove(a); System.out.println(exam); System.out.println("共有"+exam.getSize()+"个元素"); /* exam.paixu(); System.out.println("从大到小输出链表为:"); System.out.println(exam);*/ } }
以上为第二次测试的代码。
-
两个文件如上。
-
以上为测试结果,符合预期(感动.jpg)
3.链表练习,要求实现下列功能:
- 使用冒泡排序法或者选择排序法根据数值大小对链表进行排序;
如果你学号是单数, 选择冒泡排序, 否则选择选择排序。
在排序的每一个轮次中, 打印元素的总数,和目前链表的所有元素。
在(2)得到的程序中继续扩展, 用同一个程序文件,写不同的函数来实现这个功能。 仍然用 nZhangSan (你的名字)来表示元素的总数。1 import java.util.Scanner; 2 3 public class test { 4 public static void main(String[] args) { 5 Linked exam = new Linked(); 6 System.out.println("请输入以下学号与当前时间(202110xxxxxxx)"); 7 System.out.println("输入“99”停止"); 8 Scanner scan = new Scanner(System.in); 9 String at = scan.nextLine(); 10 exam.addFirst(at); 11 while (!at.equals("99")){ 12 at=scan.nextLine(); 13 if (at.equals("99")){ 14 break; 15 } 16 exam.add(at, exam.getSize()); 17 } 18 System.out.println(exam); 19 System.out.println("共有"+exam.getSize()+"个元素"); 20 exam.paixu(); 21 System.out.println("从大到小输出链表为:"); 22 System.out.println(exam); 23 } 24 }
以上为测试代码
-
1 public class Linked <T>{ 2 3 public class Node{ 4 public T t; 5 public Node next; 6 public Node(T t,Node next){ 7 this.t = t; 8 this.next = next; 9 } 10 public Node(T t){ 11 this(t,null); 12 } 13 } 14 private Node head; //头结点 15 private int nWangxinyao; //链表元素个数 16 //构造函数 17 public Linked(){ 18 this.head = null; 19 this.nWangxinyao = 0; 20 } 21 //获取链表元素的个数 22 public int getSize(){ 23 return this.nWangxinyao; 24 } 25 //判断链表是否为空 26 public boolean isEmpty(){ 27 return this.nWangxinyao == 0; 28 } 29 //链表头部添加元素 30 public void addFirst(T t){ 31 Node node = new Node(t); //节点对象 32 node.next = this.head; 33 this.head = node; 34 //this.head = new Node(e,head);等价上述代码 35 this.nWangxinyao++; 36 } 37 //向链表尾部插入元素 38 public void addLast(T t){ 39 this.add(t, this.nWangxinyao); 40 } 41 //向链表中间插入元素 42 public void add(T t,int index){ 43 if (index <0 || index >nWangxinyao){ 44 throw new IllegalArgumentException("index is error"); 45 } 46 if (index == 0){ 47 this.addFirst(t); 48 return; 49 } 50 Node preNode = this.head; 51 //找到要插入节点的前一个节点 52 for(int i = 0; i < index-1; i++){ 53 preNode = preNode.next; 54 } 55 Node node = new Node(t); 56 //要插入的节点的下一个节点指向preNode节点的下一个节点 57 node.next = preNode.next; 58 //preNode的下一个节点指向要插入节点node 59 preNode.next = node; 60 this.nWangxinyao++; 61 } 62 //删除链表元素 63 public void remove(T t){ 64 if(head == null){ 65 System.out.println("无元素可删除"); 66 return; 67 } 68 //要删除的元素与头结点的元素相同 69 while(head != null && head.t.equals(t)){ 70 head = head.next; 71 this.nWangxinyao--; 72 } 73 /* 74 * 上面已经对头节点判别是否要进行删除 75 * 所以要对头结点的下一个结点进行判别 76 */ 77 Node cur = this.head; 78 while(cur != null && cur.next != null){ 79 if(cur.next.t.equals(t)){ 80 this.nWangxinyao--; 81 cur.next = cur.next.next; 82 } 83 else cur = cur.next; 84 } 85 } 86 //删除链表第一个元素 87 public T removeFirst(){ 88 if(this.head == null){ 89 System.out.println("无元素可删除"); 90 return null; 91 } 92 Node delNode = this.head; 93 this.head = this.head.next; 94 delNode.next=null; 95 this.nWangxinyao--; 96 return delNode.t; 97 } 98 //删除链表的最后一个元素 99 public T removeLast(){ 100 if(this.head == null){ 101 System.out.println("无元素可删除"); 102 return null; 103 } 104 //只有一个元素 105 if(this.getSize() == 1){ 106 return this.removeFirst(); 107 } 108 Node cur = this.head; //记录当前结点 109 Node pre = this.head; //记录要删除结点的前一个结点 110 while(cur.next != null){ 111 pre = cur; 112 cur = cur.next; 113 } 114 pre.next = cur.next; 115 this.nWangxinyao--; 116 return cur.t; 117 } 118 //链表中是否包含某个元素 119 public boolean contains(T t){ 120 Node cur = this.head; 121 while(cur != null){ 122 if(cur.t.equals(t)){ 123 return true; 124 } 125 else cur = cur.next; 126 } 127 return false; 128 } 129 public boolean compare(T t,T m){ 130 String a = ""+t; 131 String b = ""+m; 132 if (a.compareTo(b)<0){ 133 return true; 134 } 135 else 136 return false; 137 } 138 public void paixu() { 139 int cap=this.getSize(); 140 Node cur ; 141 Node a; 142 Node b; 143 int i; 144 int ct=1; 145 do { 146 cur = this.head; 147 a = this.head; 148 b = this.head.next; 149 i = 0; 150 ct=1; 151 if (compare(a.t, b.t)) { 152 remove(b.t); 153 addFirst(b.t); 154 i++; 155 ct=0; 156 } else { 157 cur = cur.next; 158 i++; 159 ct++; 160 } 161 while (cur.next.next != null) { 162 a = cur; 163 b = cur.next; 164 if (compare(a.t, b.t)) { 165 remove(a.t); 166 remove(b.t); 167 add(b.t, i); 168 add(a.t, i + 1); 169 i++; 170 cur = cur.next; 171 ct=0; 172 } else { 173 i++; 174 cur = cur.next; 175 ct++; 176 } 177 } 178 a = cur; 179 b = cur.next; 180 if (compare(a.t, b.t)) { 181 removeLast(); 182 add(b.t, i); 183 ct=0; 184 } else { 185 ct++; 186 } 187 }while (ct!=cap); 188 } 189 @Override 190 public String toString() { 191 StringBuffer sss = new StringBuffer(); 192 Node cur = this.head; 193 while(cur != null){ 194 sss.append(cur.t+"->"); 195 cur = cur.next; 196 } 197 sss.append("NULL"); 198 return sss.toString(); 199 } 200 201 }
以上为最终的!完全的!链表以及节点代码,以及链表内部的方法。
-
以上为测试结果。!!!!!!!太感动了
4.在android上实现实验(1)和(2)
5.在android平台上实现实验(3)
三. 实验过程中遇到的问题和解决过程
- 问题1:链表Linked编译通过,测试结果有误,无法正确的实现目的。
- 问题解决方案: 通过给定特定的数据,来测试设定的链表在不同情况下是否能够正确的输出结果,从而找到源代码中是哪一部分出现了问题。
- 问题2:在链表中自定义的变量类型无法使用“>”等以及equals、compareTo等方法来实现比较大小
- 问题解决方案: 通过在方法内部使用String a = “”+t(自定义变量)来实现将自定义的变量转换为String类型,
值得注意的是,在String类型中,2“>”11,所以应当在输入时设定变量类型即为String并输入“02”,即可正常的比较大小!
其他(感悟、思考等)
当程序产生问题时,运用“分部”与“分步”的方法(先划分部分,再将程序分为多个步骤,类似于逻辑图),既能够理清自己写程序的逻辑思路,又便于发现程序中的问题。
java妙啊妙啊妙啊喵喵喵,链表妙啊妙啊妙啊喵喵喵
## 参考资料
- [《Java程序设计与数据结构教程(第二版)》](https://book.douban.com/subject/26851579/)
- [《Java程序设计与数据结构教程(第二版)》学习指导](http://www.cnblogs.com/rocedu/p/5182332.html)
- ...