冒泡排序
- 图片讲解:
排序的话默认规则是从小到大排序
- 冒泡排序原理步骤:
- 比较相邻元素。如果6比3大,则交换它们的位置;
- 对每一轮的相邻元素做相同工作。n个数冒泡n-1轮,每一轮冒泡n-i次
- 代码实现
1、初步代码实现:
public void sort(Comparable[] a){
for (int i = a.length-1; i > 0; i--){
for (int j = 0; j < i; j++){
if(a[j] > a[j+1]){ //比较操作
Comparable temp = a[i]; //交换操作
a[i] = a[j];
a[j] = temp;
}
}
}
}
把比较操作和交换操作作为两个分开的方法,分别实现static静态调用
2、最终代码实现:
public class Bubble {
/**
* 对数组a内的元素进行从小到大冒泡排序:
* 我的理解:对每次冒泡的个数进行限定,对每一对冒泡的元素的循环次数进行限定;
*它的原理:(1)比较相邻元素,若前元素比后元素大,则交换位置,较大的数值往后移
* (2)对每一对相邻元素做相同工作,从开始的第一对到结尾的最后一对元素,最终实现 冒泡排序从小到大
* @param a
*/
public static void sort(Comparable[] a){
for (int i = a.length-1; i > 0 ; i--) { //循环轮数,n个数初始化循环n-1次轮。6个数初始化循环5次轮
boolean flag = true;
for (int j = 0; j < i; j++) { //每一对相邻元素 比大小排序。每一轮冒泡n-i次
if (greater(a[j],a[j+1])){
exch(a,j,j+1);
flag = false;
}
}
/**
* 【优化版本一】判断数列是否有序无序,利用布尔变量作为标记
* 元素有交换,则说明数列无序
* 如果元素没有交换,则说明数列有序,直接跳出大循环
*/
if (flag){
break;
}
}
}
/**
* 判断v 是否大于 w:
* 由于函数是布尔类型,在方法体中须返回boolean类型的值;
* 使用Comparable接口中自带的compareTo()方法比较
*/
private static boolean greater(Comparable v,Comparable w){
return v.compareTo(w)>0;
}
/**
* 交换数组a中索引i和索引j处的值:
* 交换两个变量的值方法:定义一个中间临时变量
*/
private static void exch(Comparable[] a,int i,int j){
Comparable temp;
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
-
时间复杂度:
冒泡排序是一种’稳定’的排序方法
平均时间复杂度:O(n^2)
最好时间复杂度:正序的情况下O(n),只需遍历一遍
最坏时间复杂度:O(n^2)
选择排序
- 选择排序原理思路:
-
每一次遍历过程中,开始默认’选择‘第一个索引处的元素值最小
-
再遍历,遍历的范围是除了第一个索引 以外的其他元素
-
然后比较大小
如果其他元素值 < 第一个索引 的元素值,则该俩数索引处的值
如果其他元素值 > 第一个索引 的元素值,则继续往后遍历,直至一个程序遍历完毕
- 图片分析:
- 代码实现
public class Selection {
/**
* 对数组内的元素进行 从小到大 排序
* @param a
*/
public static void sort(Comparable[] a){
for (int i = 0; i < a.length-1; i++) { //8个数比7次,7个数比6次
int minPos = i; //每比一次,默认设置为第一个元素 为最小值,minPos为最小索引
for (int j = i+1; j < a.length; j++) { //可以比到最后一个索引位置
if (greater(a[minPos],a[j])){ //选择排
minPos = j; //交换索引
}
}
exch(a,minPos,i); //交换索引处的值
}
}
/**
* 判断v是否大于w
*/
public static boolean greater(Comparable v,Comparable w){
return v.compareTo(w)>0;
}
/**
* 交换数组a中索引i和索引j出的值
*/
private static void exch(Comparable[] a,int i,int j){
Comparable temp ;
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
-
时间复杂度
选择排序在’数组’实现的方式是一种’不稳定’的排序方式
平均时间复杂度:O(n^2)
最好时间复杂度:O(n)
最坏时间复杂度:O(n^2)
插入排序
- 插入排序原理解释:
1、 排序前操作,将所有元素分为2组,已经排序好的和未排序的
2、默认将第一个元素作为已经排序好的一组,剩下的元素作为未排序的一组。每次遍历找到未排序组的第一个元素
3、然后倒序遍历已经排序好的组,依次和等待插入的元素进行比较,比较大小,交换位置
- 图片分析:
- 代码实现:
public class Selection {
/**
* 对数组内的元素进行 从小到大 排序
* @param a
*/
public static void sort(Comparable[] a){
for (int i = 0; i < a.length-1; i++) { //8个数比7次,7个数比6次
int minPos = i; //每比一次,默认设置为第一个元素为最小值,minPos为最小索引
for (int j = i+1; j < a.length; j++) { //可以比到最后一个索引位置
if (greater(a[minPos],a[j])){ //选择排
minPos = j; //交换索引
}
}
exch(a,minPos,i); //交换索引处的值
}
}
/**
* 判断v是否大于w
*/
public static boolean greater(Comparable v,Comparable w){
return v.compareTo(w)>0;
}
/**
* 交换数组a中索引i和索引j出的值
*/
private static void exch(Comparable[] a,int i,int j){
Comparable temp ;
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
- 时间复杂度分析:
插入排序是一种稳定的排序方式
平均时间复杂度:O(n^2)
最好时间复杂度:O(n)
最坏时间复杂度:O(n^2)