课下作业(第十周)
相关知识点的总结
链表
- 链表是由若干个称作结点的对象组成的一种数据结构。
- 单链表:每个结点含有一个数据和下一个结点的引用。
- 双链表:每个结点含有一个数据并含有上一个结点的引用和下一个结点的引用。
LinkedList泛型类
- java.util包中的LinkedList
泛型类创建的对象以链表结构存储数据,习惯上称LinkedList类创建的对象为链表对象。
LinkedList<String> mylist=new LinkedList<String>();
- 创建一个空双链表。使用LinkedList
泛型类声明创建链表时,必须要指定E的具体类型,然后链表就可以使用add(E obj)方法向链表依次增加结点。 - 结点是自动链接在一起的,不需要操作安排结点中所存放的下一个或上一个结点的引用。
常用方法
-
public void add(int index,E element)
向链表的指定位置添加一个新的结点,该结点中的数据是参数element指定的数据。 -
public E remove(int index)
删除指定位置上的结点。 -
public E get(int index)
得到链表中指定位置处结点中的数据。 -
public int size()
返回链表的长度,即结点的个数。 -
迭代器遍历集合的方法在找到集合中的一个对象的同时,也得到待遍历的后继对象的引用。
-
链表对象可以使用iterator()方法获取一个Iterator对象,该对象就是针对当前链表的迭代器。
排序与查找
-
public static sort(List<E> list)
该方法可以将list中的元素按升序排列。 -
int binarySearch(List<T>list,T key,CompareTo<T>c)
使用折半法查找list是否含有和参数key相等的元素,如果key与链表中某个元素相等,方法返回和key相等的元素在链表中的索引位置(链表的索引位置从0开始),否则返回-1。 -
Java提供的Collections类中的sort方法是面向Comparable接口设计的。
-
在数据结构和算法中,排序是很重要的操作,要让一个类可以进行排序,有两种方法:
- 有类的源代码,针对某一成员变量排序,让类实现Comparable接口,调用Collection.sort(List)
- 没有类的源代码,或者多种排序,新建一个类,实现Comparator接口,调用Collection.sort(List, Compatator)
不同之处:
1.排序规则实现的方法不同: Comparable接口的方法:compareTo(Object o) Comparator接口的方法:compare(To1, To2) 2.类设计前后不同: Comparable接口用于在类的设计中使用; Comparator接口用于类设计已经完成,还想排序(Arrays);
总结:用Comparable 简单,只要实现Comparable 接口的对象直接就成为一个可以比较的对象,但是需要修改源代码;用Comparator 的好处是不需要修改源代码,而是另外实现一个比较器,当某个自定义的对象需要作比较的时候,把比较器和对象一起传递过去就可以比大小了,并且在Comparator 里面用户可以自己实现复杂的可以通用的逻辑,使其可以匹配一些比较简单的对象,那样就可以节省很多重复劳动了。( 参考资料 )
课上内容的补做
(一)数据结构-排序
要求:针对下面的Student类,使用Comparator编程完成以下功能:
-
在测试类StudentTest中新建学生列表,包括自己和学号前后各两名学生,共5名学生,给出运行结果(排序前,排序后)
-
对这5名同学分别用学号和总成绩进行增序排序,提交两个Comparator的代码
class Student {
private String id;//表示学号
private String name;//表示姓名
private int age;//表示年龄
private double computer_score;//表示计算机课程的成绩
private double english_score;//表示英语课的成绩
private double maths_score;//表示数学课的成绩
private double total_score;// 表示总成绩
private double ave_score; //表示平均成绩
public Student(String id, String name){
this.id = id;
this.name = name;
}
public Student(String id, String name, char sex, int age){
this(id, name);
this.sex = sex;
this.age = age;
}
public String getId(){
return id;
}//获得当前对象的学号,
public double getComputer_score(){
return computer_score;
}//获得当前对象的计算机课程成绩,
public double getMaths_score(){
return maths_score;
}//获得当前对象的数学课程成绩,
public double getEnglish_score(){
return english_score;
}//获得当前对象的英语课程成绩,
public void setId(String id){
this.id=id;
}// 设置当前对象的id值,
public void setComputer_score(double computer_score){
this.computer_score=computer_score;
}//设置当前对象的Computer_score值,
public void setEnglish_score(double english_score){
this.english_score=english_score;
}//设置当前对象的English_score值,
public void setMaths_score(double maths_score){
this.maths_score=maths_score;
}//设置当前对象的Maths_score值,
public double getTotalScore(){
return computer_score+maths_score+english_score;
}// 计算Computer_score, Maths_score 和English_score 三门课的总成绩。
public double getAveScore(){
return getTotalScore()/3;
}// 计算Computer_score, Maths_score 和English_score 三门课的平均成绩。
}
class Undergraduate extends Student{
private String classID;
public Undergraduate(String id, String name, char sex, int age,String classID){
super(id,name,sex,age);
this.classID=classID;
}
public String getClassID(){
return classID;
}
public void setClassID(String classID){
this.classID=classID;
}
}
(二)数据结构-单链表
要求:参见附件,补充MyList.java的内容,提交运行结果截图(全屏)。
public class MyList {
public static void main(String [] args) {
//选用合适的构造方法,用你学号前后各两名同学的学号创建四个结点
//把上面四个节点连成一个没有头结点的单链表
//遍历单链表,打印每个结点的
//把你自己插入到合适的位置(学号升序)
//遍历单链表,打印每个结点的
//从链表中删除自己
//遍历单链表,打印每个结点的
}
}
public class Node<T> //单链表结点类,T指定结点的元素类型
{
public T data; //数据域,存储数据元素
public Node<T> next; //地址域,引用后继结点
public Node(T data, Node<T> next) //构造结点,data指定数据元素,next指定后继结点
{
this.data = data; //T对象引用赋值
this.next = next; //Node<T>对象引用赋值
}
public Node()
{
this(null, null);
}
public String toString() //返回结点数据域的描述字符串
{
return this.data.toString();
}
}
教材第十五章代码分析
public class Cone<E>{
double height;
E bottom; //用泛型类E声明对象bottom
public Cone(E b){
bottom=b;
}
}
import java.util.*;
public class E153 {
public static void main(String args[]) {
LinkedList mylist = new LinkedList();
mylist.add("你"); //链表中的第一个节点
mylist.add("好"); //链表中的第二个节点
int number = mylist.size(); //获取链表的长度
for (int i = 0; i < number; i++) {
String temp = (String) mylist.get(i); //必须强制转换取出的数据
System.out.println("第" + i + "节点中的数据:" + temp);
}
Iterator iter = mylist.iterator();
while (iter.hasNext()) {
String te = (String) iter.next(); //必须强制转换取出的数据
System.out.println(te);
}
}
}
public int compareTo(object b){
Student st=(Student)b;
if((this.english-st.English)==0)
return 1; //此时允许出现大小相等的两个结点
else
return (this.english-st.english);
}