第一次的算法实验老师留了这么一道题
一眼看过去,不就是对一组数进行快排和二分查找吗,有什么难的。但由于自己对java语言的一些接口还不是很熟悉,导致自己陷入了一个难题——怎样将对象传入快排方法并按照其某一属性进行排列呢。这时我发现Java的泛型可以帮上很大的忙,通过对快排方法以及类的重写,最后实现了快排与二分查找。
Java代码
类定义
package lab_1;
public class Person implements Comparable<Person>{
public String subject;
public int Student_id;
public String name;
public int number_tree;
public Person(String subject, int student_id, String name, int number_tree) {
this.subject = subject;
Student_id = student_id;
this.name = name;
this.number_tree = number_tree;
}
public String getSubject() {
return subject;
}
public int getStudent_id() {
return Student_id;
}
public String getName() {
return name;
}
public int getNumber_tree() {
return number_tree;
}
public void setSubject(String subject) {
this.subject = subject;
}
public void setStudent_id(int student_id) {
Student_id = student_id;
}
public void setName(String name) {
this.name = name;
}
public void setNumber_tree(int number_tree) {
this.number_tree = number_tree;
}
@Override
public String toString() {
return "Person{" +
"subject='" + subject + '\'' +
", Student_id=" + Student_id +
", name='" + name + '\'' +
", number_tree=" + number_tree +
'}';
}
@Override
public int compareTo(Person o) {
return Integer.valueOf(this.getNumber_tree()).compareTo(o.getNumber_tree());
}
}
快排与二分查找
package lab_1;
import java.util.List;
import java.util.ArrayList;
public class QuickSort {
public static void main(String[] args) {
List<Person> list = new ArrayList<>();
Person s1 = new Person("计算机专业",101, "张一", 5);
Person s2 = new Person("软件专业",102, "李二", 7);
Person s3 = new Person("计算机专业",103, "王三", 10);
Person s4 = new Person("软件专业",104, "赵四", 20);
Person s5 = new Person("计算机专业",105, "孙五", 8);
list.add(s1);
list.add(s2);
list.add(s3);
list.add(s4);
list.add(s5);
System.out.println("排序前");
for (Person person : list) {
System.out.println(person);
}
System.out.println("\n");
int start = 0;
int end = list.size() - 1;
//调用sort方法,排序
sort(list, start, end);
//循环输出排序后的list内容,看是否正确
System.out.println("排序后");
for (Person person : list) {
System.out.println(person);
}
int tree = 5;
int v = find(list, tree, 0, list.size() - 1);
if (tree == list.get(v).getNumber_tree())
System.out.println("\n查找成功:\n"+list.get(v));
else
System.out.println("查找失败");
}
public static void sort(List<Person> list, int low, int high) {
//start是list的第一位,end是list的最后一位,start和end都是list的坐标;
int start = low;
int end = high;
//value作为参考值,取未排序的list第一位value的首字母作为参考
//下方的算法大体思路,就是拿list的第一位和value比较,排序,
//value值前都比value小,value值后都比value大
int value = list.get(low).getNumber_tree();
//char valueStart = list.get(start).codePointAt()(0);
//char valueEnd = list.get(end).codePointAt()(0);
while (end > start) {
//从后往前比较
//list.get(end).codePointAt()(0)是list最后一个值的首字母
while (end > start && list.get(end).getNumber_tree() >= value) {
end--;
}
if (list.get(end).getNumber_tree() <= value) {
//此时list第一位和最后一位需要调换位置,先将list第一位的值保存起来
Person keyStarts = list.get(start);
//此处调换位置,使用list的set方法,由于第一位放入了最后一个值,
//所以最后一位需要放入之前的第一位的值
list.set(start, list.get(end));
list.set(end, keyStarts);
}
//从前往后比较
while (end > start && list.get(start).getNumber_tree() <= value) start++;
if (list.get(start).getNumber_tree() >= value) {
// 同理从后往前比较,需要将第一位的值先保存,方便调换
Person keyStarts = list.get(start);
list.set(start, list.get(end));
list.set(end, keyStarts);
}
if (start > low) sort(list, low, start - 1);
if (end < high) sort(list, end + 1, high);
}
}
public static int find(List<Person> list, int key, int lo, int hi) {
if (hi < lo)
return lo;
int mid = lo + (hi - lo) / 2;
int cmp = Integer.compare(key, list.get(mid).getNumber_tree());
//自己写的是int cmp = Integer.valueOf(key).compareTo(list.get(mid).getNumber_tree());,现在呈现的是ide自己改进的
//此处应用到Integer
if (cmp < 0)
return find(list, key, lo, mid - 1);
else if (cmp > 0)
return find(list, key, mid + 1, hi);
else
return mid;
}
}