选择排序
- 两层循环数组,从第二层数组中找到最小的一个元素与第一层数组中的第一个元素交换;
- 接下来第一个元素外,从剩下未排序的数组序列中找到最小值,再与数组第二个元素交换;
- 总共N-1趟,每趟都从第二层数组中找到未排序的最小值,放到第一层已排序的数组序列后面。
代码实现
public static void selectSort1(int[] arr){
// 遍历数组
for (int i = 0; i < arr.length; i++) {
// 双层遍历,拿到数组中最小值的下标索引
// 拿到最小的下标索引
int minIndex = i;
for (int j = i; j < arr.length; j++) {
if (arr[j] < arr[minIndex]){
minIndex = j;
}
}
// 拿到最小索引下标,交换排序
int value = arr[i];
// 把拿到的最小的值赋值给数据中的首个元素
arr[i] = arr[minIndex];
// 然后把值交换
arr[minIndex] = value;
}
for (int i = 0; i < arr.length; i++) {
System.out.print( arr[i] + " ");
}
}
使用泛型
/**
* 使用泛型
*/
public static <E extends Comparable<E>> void selectSort2(E[] arr){
// 遍历数组
for (int i = 0; i < arr.length; i++) {
// 双层遍历,拿到数组中最小值的下标索引
// 拿到最小的下标索引
int minIndex = i;
for (int j = i; j < arr.length; j++) {
if (arr[j].compareTo(arr[minIndex]) > 0){
minIndex = j;
}
}
// 拿到最小索引下标,交换排序
E value = arr[i];
// 把拿到的最小的值赋值给数据中的首个元素
arr[i] = arr[minIndex];
// 然后把值交换
arr[minIndex] = value;
}
for (int i = 0; i < arr.length; i++) {
System.out.print( arr[i] + " ");
}
}
运行结果
public static void main(String[] args) {
Random random = new Random();
int[] arr = new int[10];
for (int i = 0; i < arr.length; i++) {
arr[i] = random.nextInt(1000);
}
// 输出:193 280 476 504 710 739 883 900 916 976
SelectSort.selectSort1(arr);
// 换行
System.out.println();
// 使用泛型
Student[] students = {new Student("张三",91),
new Student("李四",92),
new Student("王五",93),
new Student("赵六",90)};
SelectSort.selectSort2(students);
}
实体类 Student
package com.entity;
import java.util.Objects;
public class Student implements Comparable<Student> {
public String name;
public int number;
public Student(String name,int number){
this.name = name;
this.number = number;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return number == student.number && Objects.equals(name, student.name);
}
@Override
public int compareTo(Student student) {
if (this.number > student.number){
return -1;
} else if (this.number == student.number){
return 0;
}
return 1;
// return this.number - student.number;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", number=" + number +
'}';
}
}
为什么要实现Comparable接口
实现Comparable接口,并实现其唯一的方法:compareTo(T o),在该方法中定义自己的排序规则:
当调用Arrays.sort(Object[] a)方法时则回调compareTo()方法,并按照自己的规则对对象数组进行排序。
返回值及比较规则:
1、比较者大于被比较者(也就是compareTo方法里面的对象),那么返回正整数
2、比较者等于被比较者,那么返回0
3、比较者小于被比较者,那么返回负整数
插入算法
public static int[] insertionSort(int[] arr) {
for (int i = 1; i < arr.length; i++) {
/**
* @title 第一种写法
*
* 第二层下标索引j
* j从第一个元素开始,如果大于等于0,并且数组中j小于j-1个元素,即第二个元素小于第一个
* 则进行元素的交换
*/
// for (int j = i ; j - 1 >= 0 && arr[j] < arr[j - 1]; j--) {
// int t = arr[j];
// arr[j] = arr[j-1];
// arr[j-1] = t;
// }
/**
* @title 第二种写法
*
* 插入算法优化写法
* 好处:1、在数据量比较大的时候,时间优化较第一种写法优化很多
* 2、使用赋值的方式,减少了交换寻址的次数
*/
// 暂存要交换的元素
int t2 = arr[i];
int j2;
for (j2 = i; j2 - 1 >=0 && t2 < arr[j2-1]; j2--) {
arr[j2] = arr[j2-1];
}
arr[j2] = t2;
}
/**
* 测试集合:int[] arr = {4,5,7,2,3,8,10,9};
* 输出结果:2 3 4 5 7 8 9 10
*/
return arr;
}