一、冒泡排序
1.简介
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
针对所有的元素重复以上的步骤,除了最后一个,即需要进行length-1次。
第一次是对n个数进行n-1次比较,进行到最后第n个的一个是最大的;
第二次是对n-1个数进行n-2次比较,进行到最后第n-1个的一个是最大的;
......
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
动态图:
二、代码案例
package com.sort;
import java.util.Arrays;
public class BubbleSort {
public static void main(String[] args) {
int[] arr = new int[] { 5, 2, 1, 7, 9, 3, 6, 8, 4 };
sort(arr);
System.out.println(Arrays.toString(arr));
}
public static void sort(int[] arr) {
for (int j = 0; j < arr.length; j++) {
for (int i = 0; i + 1 < arr.length; i++) {
if (arr[i] > arr[i + 1]) {
int temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
}
}
}
}
输出结果:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
二、插入排序
1、简介
插入排序是在一个有序的排列中插入一个元素,默认认为第一个是有序,从后面的元素中比较和前面已经排好序的元素挨个比较,插入合适的位置;因此需要一个循环(外层循环)用来控制元素个数;还需另外一个循环(里层循环)用来控制当前第几个元素后面的元素挨个与前面的有序元素比较,得出插入的合适位置。
二、代码案例
package com.sort;
import java.util.Arrays;
public class InsertSortPlus {
public static void main(String[] args) {
int[] num = { 3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48 };
int j;
// i=1;从1开始,没必要和自己比
for (int i = 1; i < num.length; i++) {
// 记录要插入的值,这时就有了一个长度为i+1的数组可以进行移动
int temp = num[i];
System.out.print("第" + i + "次移动的位置:");
// 在已排序的数组中找到比记录值(temp)要小的值,位置往后移动(记住此时的数组长度(i+1))
// 要明白为什么往后移动。
// j >= 0&&num[j] > temp要满足这两个条件,j才会j--;
for (j = i - 1; j >= 0 && num[j] > temp; j--) {
System.out.print(j + " ");
// 符合条件的往后移动一位
num[j + 1] = num[j];
}
System.out.println("\n第" + i + "次移动后的数组:" + Arrays.toString(num) + ",此时j+1的位置为:" + (j + 1));
// 归位,此时符合条件的都全部移动了一位,此时的j+1就是记录值要插入的位置
num[j + 1] = temp;
System.out.println("第" + i + "次交换后的结果:" + Arrays.toString(num));
}
System.out.println("最终的排序结果:" + Arrays.toString(num));
}
}
输出结果:
第1次移动的位置:
第1次移动后的数组:[3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48],此时j+1的位置为:1
第1次交换后的结果:[3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]
第2次移动的位置:1
第2次移动后的数组:[3, 44, 44, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48],此时j+1的位置为:1
第2次交换后的结果:[3, 38, 44, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]
第3次移动的位置:2 1
第3次移动后的数组:[3, 38, 38, 44, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48],此时j+1的位置为:1
第3次交换后的结果:[3, 5, 38, 44, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]
第4次移动的位置:
第4次移动后的数组:[3, 5, 38, 44, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48],此时j+1的位置为:4
第4次交换后的结果:[3, 5, 38, 44, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]
第5次移动的位置:4 3 2
第5次移动后的数组:[3, 5, 38, 38, 44, 47, 36, 26, 27, 2, 46, 4, 19, 50, 48],此时j+1的位置为:2
第5次交换后的结果:[3, 5, 15, 38, 44, 47, 36, 26, 27, 2, 46, 4, 19, 50, 48]
第6次移动的位置:5 4 3
第6次移动后的数组:[3, 5, 15, 38, 38, 44, 47, 26, 27, 2, 46, 4, 19, 50, 48],此时j+1的位置为:3
第6次交换后的结果:[3, 5, 15, 36, 38, 44, 47, 26, 27, 2, 46, 4, 19, 50, 48]
第7次移动的位置:6 5 4 3
第7次移动后的数组:[3, 5, 15, 36, 36, 38, 44, 47, 27, 2, 46, 4, 19, 50, 48],此时j+1的位置为:3
第7次交换后的结果:[3, 5, 15, 26, 36, 38, 44, 47, 27, 2, 46, 4, 19, 50, 48]
第8次移动的位置:7 6 5 4
第8次移动后的数组:[3, 5, 15, 26, 36, 36, 38, 44, 47, 2, 46, 4, 19, 50, 48],此时j+1的位置为:4
第8次交换后的结果:[3, 5, 15, 26, 27, 36, 38, 44, 47, 2, 46, 4, 19, 50, 48]
第9次移动的位置:8 7 6 5 4 3 2 1 0
第9次移动后的数组:[3, 3, 5, 15, 26, 27, 36, 38, 44, 47, 46, 4, 19, 50, 48],此时j+1的位置为:0
第9次交换后的结果:[2, 3, 5, 15, 26, 27, 36, 38, 44, 47, 46, 4, 19, 50, 48]
第10次移动的位置:9
第10次移动后的数组:[2, 3, 5, 15, 26, 27, 36, 38, 44, 47, 47, 4, 19, 50, 48],此时j+1的位置为:9
第10次交换后的结果:[2, 3, 5, 15, 26, 27, 36, 38, 44, 46, 47, 4, 19, 50, 48]
第11次移动的位置:10 9 8 7 6 5 4 3 2
第11次移动后的数组:[2, 3, 5, 5, 15, 26, 27, 36, 38, 44, 46, 47, 19, 50, 48],此时j+1的位置为:2
第11次交换后的结果:[2, 3, 4, 5, 15, 26, 27, 36, 38, 44, 46, 47, 19, 50, 48]
第12次移动的位置:11 10 9 8 7 6 5
第12次移动后的数组:[2, 3, 4, 5, 15, 26, 26, 27, 36, 38, 44, 46, 47, 50, 48],此时j+1的位置为:5
第12次交换后的结果:[2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 50, 48]
第13次移动的位置:
第13次移动后的数组:[2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 50, 48],此时j+1的位置为:13
第13次交换后的结果:[2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 50, 48]
第14次移动的位置:13
第14次移动后的数组:[2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 50, 50],此时j+1的位置为:13
第14次交换后的结果:[2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50]
最终的排序结果:[2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50]
三、快速排序
1、简介
快速排序就是每次找一个基点(第一个元素),然后两个哨兵,一个从最前面往后走,一个从最后面往前面走,如果后面那个哨兵找到了一个比基点大的数停下来,前面那个哨兵找到比基点大的数停下来,然后交换两个哨兵找到的数,如果找不到最后两个哨兵就会碰到一起就结束,最后交换基点和哨兵相遇的地方的元素,然后就将一个序列分为比基点小的一部分和比基点大的一部分,然后递归左半部分和右半部分,最后的结果就是有序的了。
二、代码案例
public class QuickSort {
public static void quickSort(int[] arr,int low,int high){
int i,j,temp,t;
if(low>high){
return;
}
i=low;
j=high;
//temp就是基准位
temp = arr[low];
while (i<j) {
//先看右边,依次往左递减
while (temp<=arr[j]&&i<j) {
j--;
}
//再看左边,依次往右递增
while (temp>=arr[i]&&i<j) {
i++;
}
//如果满足条件则交换
if (i<j) {
t = arr[j];
arr[j] = arr[i];
arr[i] = t;
}
}
//最后将基准为与i和j相等位置的数字交换
arr[low] = arr[i];
arr[i] = temp;
//递归调用左半数组
quickSort(arr, low, j-1);
//递归调用右半数组
quickSort(arr, j+1, high);
}
public static void main(String[] args){
int[] arr = {10,7,2,4,7,62,3,4,2,1,8,9,19};
quickSort(arr, 0, arr.length-1);
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
输出:
1 2 2 3 4 4 7 7 8 9 10 19 62
四、选择排序
1、 简介
每一趟从待排序的数据元素中选择最小(或最大)的一个元素作为首元素,直到所有元素排完为止,简单选择排序是不稳定排序。
二、代码案例
package com.sort;
public class SelectSort {
public static void main(String[] args) {
// 模拟数据
int[] array = { 52, 63, 14, 59, 68, 35, 8, 67, 45, 99 };
System.out.println("原数组:");
for (int i : array) {
System.out.print(i + " ");
}
System.out.println();
selectSort(array);
System.out.println("排序后:");
for (int i : array) {
System.out.print(i + " ");
}
}
public static void selectSort(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
int min = i;
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[min]) {
min = j;
}
}
if (min != i) {
swap(arr, i, min);
}
}
}
// 完成数组两元素间交换
public static void swap(int[] arr, int a, int b) {
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
}
输出:
原数组:
52 63 14 59 68 35 8 67 45 99
排序后:
8 14 35 45 52 59 63 67 68 99
五、基数排序
1、简介
基数排序就是把数按位考虑,让后我们一位数只能是[0,9],就是我们在考虑某位(个位、百位· · ·)的时候就只看这个位的数,放到在[0,9]相应的位置,然后顺序取出,最后再按其它位这样操作(上面说了要不从低位开始到高位,要不就是从高位到低位)
2、代码案例
package com.sort;
import java.util.Arrays;
public class RadixSort03 {
public static void main(String[] args) {
int[] arr = new int[] { 12, 98, 10, 123, 1, 15, 26, 30, 87, 96, 130, 97, 45, 68, 89 };
sort(arr);
System.out.println(Arrays.toString(arr));
}
public static void sort(int[] arr) {
// 定义桶
int[][] bucket = new int[10][arr.length];
// 定义桶记录器
int[] elementCounts = new int[10];
// 找到数组当中的最大值
int max = arr[0];
for (int i = 0; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
// 找到最大值的位数
int maxLength = (max + "").length();
int n = 1;
for (int h = 0; h < maxLength; h++) {
// 向桶内放数据
for (int i = 0; i < arr.length; i++) {
// 计算个位的值
int element = arr[i] / n % 10;// 放入到桶内
int count = elementCounts[element];
bucket[element][count] = arr[i];
elementCounts[element] = elementCounts[element] + 1;
}
int index = 0;
// 将桶内的数据取出
for (int k = 0; k < elementCounts.length; k++) {
if (elementCounts[k] != 0) {
for (int l = 0; l < elementCounts[k]; l++) {
arr[index] = bucket[k][l];
index++;
}
}
// 清空桶记录器
elementCounts[k] = 0;
}
n = n * 10;
}
}
}
输出:
[1, 10, 12, 15, 26, 30, 45, 68, 87, 89, 96, 97, 98, 123, 130]
六、希尔排序
1、简介
选定一个增长量h,按照增长量h作为数据分组的依据,对数据进行分组;对分好组的每一组数据完成插入排序;减小增长量,最小减为1,重复第二步操作
2、代码案例
package com.sort;
import java.util.Arrays;
public class ShellSortPlus {
public static void main(String[] args) {
int[] arr={49,38,65,97,76,13,27,49,78,34};
shell(arr);
}
public static void shell(int[] arr){
int temp=0;
int count=0;
//步长
for (int gap= arr.length/2;gap>=1;gap=gap/2){
count++;
for (int i=gap;i< arr.length;i++){
//分组
for (int j=i-gap;j>=0;j=j-gap){
if (arr[j]>arr[j+gap]){
temp=arr[j];
arr[j]=arr[j+gap];
arr[j+gap]=temp;
}
}
}
System.out.println("第"+count+"轮排序后的数据:");
System.out.println(Arrays.toString(arr));
}
}
}
输出:
第1轮排序后的数据:
[13, 27, 49, 78, 34, 49, 38, 65, 97, 76]
第2轮排序后的数据:
[13, 27, 34, 49, 38, 65, 49, 76, 97, 78]
第3轮排序后的数据:
[13, 27, 34, 38, 49, 49, 65, 76, 78, 97]