几种排序算法实现
一、冒泡排序
1.介绍
一种简单的排序算法,每次循环遍历都会找到极值。
2.过程
1)第一层循环 ,设变量 i : 从0 ~ 所有数数量-1。从前到后,找出极值不断放到后面。后面放好的极值是有序,不能再动
2)第二层循环,设变量j:从0~到所有数数量-1-i。注意,随着第一层循环的进行,第二层循环比较次数减少。
3.复杂度
1)时间复杂度
基本语句为最内层的交换处理,数量级为O(N^2)
2)空间复杂度
因为整个排序过程过程,只涉及两个数的交换,用到空间可以是两个数位置。所以空间复杂段为常数,O(1)
3)稳定性
稳定
4.实现
public class BubbleSort {
static int[] ints = new int[]{3,7,2,4,6,5};
public static void main(String[] args) {
//外循环比较次数为数组长度-1
for(int i = 0; i < ints.length - 1; i++){
//随着外循环次数增加,要比较的次数减少
//比较次数为数组长度-1-i
for(int j = 0; j < ints.length - 1 - i; j++ ){
if(ints[j] > ints[j + 1]){
exchange(j,j+1);
}
}
}
for (int anInt : ints) {
System.out.print(anInt);
}
}
private static void exchangeByLocatino(int a, int b) {
//使用临时空间,交换
// a = a ~ b;
int tmp = ints[a];
ints[a] = ints[b];
ints[b] = tmp;
}
private static void exchange(int a , int b){
ints[a] = ints[a] ^ ints[b];
ints[b] = ints[a] ^ ints[b];
ints[a] = ints[a] ^ ints[b];
}
}
二、插入排序
1.介绍
插入排序(Insertion sort)是一种简单直观且稳定的排序算法。如果有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这个时候就要用到一种新的排序方法——插入排序法
2.过程
默认第一个数为排好序的队列。后面的数,依此插入有序队列中,保持队列顺序。
需要循环三层,
1)第一层循环,查找要插入前面有序队列的数。设变量i:从1开始变量到队尾。当发现第i个位置上的[i]小于前一个数[i-1],触发第二层循环
2)第二层循环,查找要插入前面有序队列中的位置。设遍历j:从0开始变量到i前面位置。当发现第j个位置的数大于i位置数时,触发第三层循环
3)第三层循环,插入位置j和i位置之间的数后移(包含j,不包含i),留出位置j,插入i位置数。注意这里要提前抽取i位置的数。
3.复杂度
1)时间复杂度
如果目标是把n个元素的序列升序排列,那么采用插入排序存在最好情况和最坏情况。最好情况就是,序列已经是升序排列了,在这种情况下,需要进行的比较操作需(n-1)次即可。最坏情况就是,序列是降序排列,那么此时需要进行的比较共有n(n-1)/2次。插入排序的赋值操作是比较操作的次数加上 (n-1)次(因为 n-1次循环中,每一次循环的比较都比赋值多一个,多在最后那一次比较并不带来赋值)。平均来说插入排序算法的时间复杂度为O(n^2)。因而,插入排序不适合对于数据量比较大的排序应用。但是,如果需要排序的数据量很小,例如,量级小于千,那么插入排序还是一个不错的选择
2) 空间复杂度
整个过程,也是移动两个数的位置,需要的空间位置为常量,所以数量级为O(1)
3)稳定性
稳定
4.实现
public class InsertSort {
static int[] ints = new int[]{3,4,5,1,2,7};
public static void main(String[] args) {
//第一层循环,初始第一位有序,而后后面每一位跟前一位比较
//i : 1 ~ lens -1
for(int i = 1; i < ints.length -1; i++){
//条件是后面数小于前面,a[i] < a[i-1]进入第二层循环
//第二层循环是寻找a[i] 在前面的位置
if(ints[i] < ints[i - 1]){
for(int j = 0; j < i ; j++){
//j:从第一位开始遍历,一致遍历到i-1位置,如果碰到a[i] < a[j]就算找到,就要触发第三层,移动后面位置
if(ints[i] < ints[j]){
//移动位置 k: 从后向前,从i 开始 一直到 j.
//首先要提取出a[i],然后 依次 a[i] = a[i - 1], 一直到 a[j] = 提取出来的a[i]
int temp = ints[i];
for(int k = i; k > j; k--){
ints[k] = ints[k - 1];
}
ints[j] = temp;
//当找到插入位置后,后面的j就没必要进行下去了
break;
}
}
}
}
for(int i = 0; i < ints.length; i++){
System.out.print(ints[i]);
}
}
}