比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
针对所有的元素重复以上的步骤,除了最后一个,即需要进行length-1次。
第一次是对n个数进行n-1次比较,进行到最后第n个的一个是最大的;
第二次是对n-1个数进行n-2次比较,进行到最后第n-1个的一个是最大的;
…
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
示例代码:
public class Bubble_sort {
public static void main(String[] args) {
//冒泡排序算法
int[] num=new int[]{
10,21,8,16,7,23,12};
//需进行length-1次冒泡
for(int i = 0; i < num.length-1;i++){
for(int j=0;j<num.length-1-i;j++){
if(num[j]>num[j+1]) {
int temp=num[j];
num[j]=num[j+1];
num[j+1]=temp;
}
}
}
System.out.println("从小到大排序后的结果是:");
for(int i=0;i<num.length;i++)
System.out.print(num[i]+" ");
}
}
代码结果:
从小到大排序后的结果是:
7 8 10 12 16 21 23
选择排序原理即是,遍历元素找到一个最小(或最大)的元素,把它放在第一个位置,然后再在剩余元素中找到最小(或最大)的元素,把它放在第二个位置,依次下去,完成排序。
选择排序的时间复杂度为 O(n^2)。
第一次需要检查n个元素,但随后检查的元素数依次为n - 1, n – 2, …, 2和1。平均每次检查的元素数为1/2 * n, 因此运行时间为 n * 1/2 * n,简单地写作 O(n^2)。
示例代码:
public class SelectionSort {
public static void main(String[] args) {
int[] num = new int[] {
5, 3, 6, 2, 10, 18, 1 };
selectSort(num);
System.out.println("从小到大排序的结果为: "+ Arrays.toString(num));
}
public static void selectSort(int[] num) {
for (int i = 0; i < num.length - 1; i++) {
int minIndex = i; // 用来记录最小值的索引位置,默认值为i
for (int j = i + 1; j < num.length; j++) {
if (num[j] < num[minIndex]) {
minIndex = j; // 遍历 i+1~length 的值,找到其中最小值的位置
}
}
// 交换当前索引 i 和最小值索引 minIndex 两处的值
if (i != minIndex) {
int temp = num[i];
num[i] = num[minIndex];
num[minIndex] = temp;
}
// 执行完一次循环,当前索引 i 处的值为最小值,直到循环结束即可完成排序
}
}
}
执行结果:
从小到大排序的结果为: [1, 2, 3, 5, 6, 10, 18]
插入排序(英语:Insertion Sort)是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
示例代码:
public class InsertionSort {
public static void main(String[] args){
int[] num1 = {
2,3,5,1,23,6,78,34};
int[] num2 = sort(num1);
System.out.println("从小到大排序的结果为: "+ Arrays.toString(num2));
}
public static int[] sort(int[] num1){
for(int i=1; i<num1.length; i++){
for(int j=i; j>0; j--){
if(num1[j]<num1[j-1]){
int temp = num1[j-1];
num1[j-1] = num1[j];
num1[j] = temp;
}
}
}
return num1;
}
}
输出结果:
从小到大排序的结果为: [1, 2, 3, 5, 6, 23, 34, 78]
希尔排序也成为“缩小增量排序”,其基本原理是,现将待排序的数组元素分成多个子序列,使得每个子序列的元素个数相对较少,然后对各个子序列分别进行直接插入排序,待整个待排序列“基本有序”后,最后在对所有元素进行一次直接插入排序。因此,我们要采用跳跃分割的策略:将相距某个“增量”的记录组成一个子序列,这样才能保证在子序列内分别进行直接插入排序后得到的结果是基本有序而不是局部有序。希尔排序是对直接插入排序算法的优化和升级。
所谓的基本有序,就是小的关键字基本在前面,大的基本在后面,不大不小的基本在中间,例如{2,1,3,6,4,7,5,8,9,}就可以称为基本有序了。但像{1,5,9,3,7,8,2,4,6}这样,9在第三位,2在倒数第三位就谈不上基本有序。
希尔排序的关键并不是随便分组后各自排序,而是将相隔某个“增量”的记录组成一个子序列,实现跳跃式移动,使得排序的效率提高。需要注意的是,增量序列的最后一个增量值必须等于1才行。另外,由于记录是跳跃式的移动,希尔排序并不是一种稳定的排序算法。
希尔排序最好时间复杂度和平均时间复杂度都是O(nlogn),最坏时间复杂度为 O(n^2)。
示例代码
public class ShellSort {
public static void main(String[] args) {
int[] arr = new int[] {
26, 53, 67, 48, 57, 13, 48, 32, 60, 50 };
shellSortSmallToBig(arr);
System.out.println("从小到大排序的结果为: "+Arrays.toString(arr));
}
public static void shellSortSmallToBig(int[] arr) {
int j = 0;
int temp = 0;
for (int increment = arr.length / 2; increment >