有关数组的排序有冒泡排序、插入排序、选择排序、快速排序、希尔排序、堆排序等。
冒泡排序
冒泡排序思想:
将数组中的元素两两进行比较,第一轮比较后,最大的元素放在数组的最大索引处。
冒泡排序原理:
- 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
- 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
- 针对所有的元素重复以上的步骤,除了最后一个。
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
冒泡排序举例1:
分析:
代码:
public class Demo5 {
public static void main(String[] args) {
int[] arr = {24, 65, 84, 53, 16};
System.out.println("未排序的数组" + Arrays.toString(arr));
// 数组按从小到大的顺序排列
arraySort(arr);
System.out.println("经过冒泡排序之后的数组" + Arrays.toString(arr));
}
private static void arraySort(int[] arr) {
for (int j = 1; j <= arr.length - 1; j++) {
for (int i = 0; i < arr.length - j; i++) {
if (arr[i] > arr[i + 1]) {
int t = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = t;
}
}
}
}
}
冒泡排序举例2:
public class Demo5 {
public static void main(String[] args) {
int[] arr = {24, 65, 84, 53, 16};
System.out.println("未排序的数组" + Arrays.toString(arr));
// 数组按从小到大的顺序排列
arraySort(arr);
System.out.println("经过冒泡排序之后的数组" + Arrays.toString(arr));
}
private static void arraySort(int[] arr) {
for (int j = 0; j < arr.length - 1; j++) {
for (int i = 0; i < arr.length - j - 1; i++) {
if (arr[i] > arr[i + 1]) {
int t = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = t;
}
}
}
}
}
结果:
未排序的数组[24, 65, 84, 53, 16]
经过冒泡排序之后的数组[16, 24, 53, 65, 84]
选择排序
选择排序思想:
从0索引开始,依次和后面元素比较,小的往前放,第一次比较完毕,最小值出现在了最小索引处。
选择排序是不稳定的排序。
选择排序举例:
分析:
代码:
public class Demo6 {
public static void main(String[] args) {
int[] arr = {24, 65, 84, 53, 16};
System.out.println("未排序的数组为:" + Arrays.toString(arr));
// 数组按从小到大的顺序排列
arraySort(arr);
System.out.println("经过选择排序之后的数组为:" + Arrays.toString(arr));
}
private static void arraySort(int[] arr) {
for (int j = 0; j < arr.length - 1; j++) {
for (int i = j + 1; i < arr.length; i++) {
if (arr[j] > arr[i]) {
int t = arr[j];
arr[j] = arr[i];
arr[i] = t;
}
}
}
}
}
结果:
未排序的数组为:[24, 65, 84, 53, 16]
经过选择排序之后的数组为:[16, 24, 53, 65, 84]
插入排序
插入排序思想:每次将后面一个元素,插入到之前得一个有序序列中,使之仍保持有序.
将数组索引0处的元素看成是一个有序列表,数组索引1开始的元素每一个与有序列表的元素进行比较,将该元素插入有序列表的某个位置,新列表仍然保持有序。
举例:
分析:
代码:
public class Demo7 {
public static void main(String[] args) {
int[] arr = {24, 65, 84, 53, 16};
System.out.println("未排序的数组为:" + Arrays.toString(arr));
// 数组按从小到大的顺序排列
arraySort(arr);
System.out.println("经过插入排序之后的数组为:" + Arrays.toString(arr));
}
private static void arraySort(int[] arr) {
for (int i = 1; i <= arr.length-1; i++) {
int j=i;
while(j>0&&arr[j]<arr[j-1]){
int t=arr[j];
arr[j]=arr[j-1];
arr[j-1]=t;
j--;
}
}
}
}
结果:
未排序的数组为:[24, 65, 84, 53, 16]
经过插入排序之后的数组为:[16, 24, 53, 65, 84]
快速排序
快速排序的思想:
分治法,比大小,再分区。
- 从数组中取出一个数,作为基准数。
- 分区:将比这个数大或等于的数全放到他的右边,小于他的数全放到他的左边。
- 再对左右区间重复第二步,直到各区间只有一个数。
举例:
代码:
快排工具类
public class QuickSortUtils {
private QuickSortUtils() {
}
public static void quickSort(int[] arr, int start, int end) {
// 递归排序
if (start < end) {
//找索引
int index = getIndex(arr, start, end);
//左区递归快排
quickSort(arr, start, index - 1);
//右区递归快排
quickSort(arr, index + 1, end);
}
}
private static int getIndex(int[] arr, int start, int end) {
int i = start, j = end;
// 找基准数
int num = arr[i];
// 采用挖坑填数法。
while (i < j) {
// 从后向前找比基准数小的数
while (i < j && num < arr[j]) {
j--;
}
if (i < j) {
arr[i] = arr[j];
i++;
}
// 从前向后找比基准数大的数
while (i < j && num > arr[i]) {
i++;
}
if (i < j) {
arr[j] = arr[i];
j--;
}
}
arr[i] = num;
return i;
}
}
测试类:
public class Demo8 {
public static void main(String[] args) {
int[] arr = {24, 65, 84, 53, 16};
System.out.println("未排序的数组为:" + Arrays.toString(arr));
// 数组按从小到大的顺序排列
QuickSortUtils.quickSort(arr, 0, arr.length-1);
System.out.println("经过快速排序之后的数组为:" + Arrays.toString(arr));
}
}
结果:
未排序的数组为:[24, 65, 84, 53, 16]
经过快速排序之后的数组为:[16, 24, 53, 65, 84]