Java学习+面试指南:https://javaxiaobear.cn
Comparable接口用于元素之间的比较
回顾:
Student类
public class Student implements Comparable<Student>{
public String name;
public int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("Student{");
sb.append("name='").append(name).append('\'');
sb.append(", age=").append(age);
sb.append('}');
return sb.toString();
}
@Override
public int compareTo(Student s){
return this.getAge() - s.getAge();
}
}
测试类
public class TestCompare {
public static void main(String[] args) {
Student s1 = new Student();
s1.setName("lwh");
s1.setAge(18);
Student s2 = new Student();
s1.setName("yhx");
s1.setAge(19);
Comparable comparable = compareMax(s1, s2);
System.out.println(comparable);
}
/**
* 比较大小
* @param c1
* @param c2
* @return
*/
public static Comparable compareMax(Comparable c1,Comparable c2){
int i = c1.compareTo(c2);
/**
* i > 0,c1 > c2
* i == 0,c1 == c2
* i < 0,c1 < c2
*/
if(i >= 0){
return c1;
}else {
return c2;
}
}
}
冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端。
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
针对所有的元素重复以上的步骤,除了最后一个。
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
/**
* 冒泡排序算法 比较并交换
* @param nums
* @return
*/
public int[] bubbleSort(int[] nums){
int n = nums.length;
for (int i = n - 1; i >= 0; i--) {
for (int j = 0; j < i; j++) {
//交换两个元素
if(nums[j] > nums[j+1]){
int temp = nums[j];
nums[j] = nums[j+1];
nums[j+1] = temp;
}
}
}
return nums;
}
冒泡排序使用了双层for循环,其中内层循环的循环体是真正完成排序的代码。
元素的比较次数:(N-1)+(N-2)+(N-3)+…+2+1=((N-1)+1)(N-1)/2 = N2/2-N/2;*
元素的交换次数:(N-1)+(N-2)+(N-3)+…+2+1=((N-1)+1)(N-1)/2 = N2/2-N/2;*
总的执行次数:N^N - N
按照大O推导法则,保留函数中的最高阶项那么最终冒泡排序的时间复杂度为O(N2).
选择排序是一种简单直观的排序算法,无论什么数据进去都是 O(n2) 的时间复杂度
首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
重复第二步,直到所有元素均排序完毕。
public int[] selectSort(int[] nums){
int n = nums.length;
//这里n-2是因为最后一次是跟自己比较
for (int i = 0; i <= n-2; i++) {
int index = i;
//每一次内层循环找到最小元素的下标,如果不与i相等,则交换元素
for (int j = i + 1; j < n; j++) {
if(nums[index] > nums[j]){
index = j;
}
}
//交换元素
if(i != index){
int temp = nums[i];
nums[i] = nums[index];
nums[index] = temp;
}
}
return nums;
}
选择排序使用了双层for循环,其中外层循环完成了数据交换,内层循环完成了数据比较
元素比较次数:(n-1)+(n-2)+……+1 =((n-1)+1)(n-1)/2 = n2/2 - n/2*
元素交换次数:(n-1)
总的执行次数: n2/2 - n/2 + (n-1) = n2/2 + n/2 -1
根据大O推导法则,保留最高阶项,去除常数因子,时间复杂度为O(n2)
插入排序:是一种最简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
插入排序和冒泡排序一样,也有一种优化算法,叫做拆半插入。
插入排序的代码实现虽然没有冒泡排序和选择排序那么简单粗暴,但它的原理应该是最容易理解的了,因为只要打过扑克牌的人都应该能够秒懂。
- 把所有的元素分为两组,已经排序的和未排序的;
- 找到未排序的组中的第一个元素,向已经排序的组中进行插入;
- 倒叙遍历已经排序的元素,依次和待插入的元素进行比较,直到找到一个元素小于等于待插入元素,那么就把待插入元素放到这个位置,其他的元素向后移动一位;
/**
* 插入排序
* @param nums
* @return
*/
public int[] insertSort(int[] nums){
int n = nums.length;
// 从下标为1的元素开始选择合适的位置插入,因为下标为0的只有一个元素,默认是有序的
for(int i=1;i < n;i++){
//当前元素为a[i],依次和i前面的元素比较,找到一个小于等于a[i]的元素
for (int j = i; j > 0; j--) {
//交换元素
if(nums[j] < nums[j-1]){
int temp = nums[j];
nums[j] = nums[ j-1];
nums[j-1] = temp;
}else {
break;
}
}
}
return nums;
}
插入排序使用了双层for循环,其中内层循环的循环体是真正完成排序的代码
最坏的情况:就是原数组倒叙排列
比较的次数:(n-1)+(n-2)+……+1 =((n-1)+1)(n-1)/2 = n2/2 - n/2*
交换的次数:(n-1)+(n-2)+……+1 =((n-1)+1)(n-1)/2 = n2/2 - n/2*
总执行次数:n2 - n
按照大O推导法则,保留函数中的最高阶项那么最终插入排序的时间复杂度为O(n2)