冒泡排序
主要思想:交换相邻的两个元素,将大的移到后面,每一趟选出最大的值。
思路分析:
- 对[0,n-1]排序,将最大的值放到 array[n],下一次对[0,n-2]排序。
- [0,n-1],对相邻的两个数比较,如果前面的数字比后面的大,则交换。
- 如果某一趟排序中没有发生交换,则说明数组已经是有序的。
代码实现:
public void sort(int[] array) {
// 对[0,n-1]排序,将最大的值放到 array[n],下一次对[0,n-2]排序
int temp;
boolean change = false;
for (int i = array.length - 1; i > 0; i--) {
for (int j = 0; j < i; j++) {
// 比较array[j]和array[j+1],如果array[j]大,则交换
if (array[j] > array[j + 1]) {
temp = array[j + 1];
array[j + 1] = array[j];
array[j] = temp;
change = true;
}
}
// 如果没有发生过交换,则说明数组是有序的了
if (!change) {
break;
} else {
change = false;
}
}
}
插入排序
主要思想:将array[0,n-1]分成有序[0,i]和无序[i+1,n-1]两部分,每次将 array[i+1]插入到有序表中,形成 array[0,i+1]有序和array[i+2,n-1]无序。
思路分析:
- 定义一个 要插入的坐标 temp,坐标是 i [i,n-1]。
- 将 array[i] 和 有序数组array[0,i-1]比较。
- 如果 array[i] 小于 array[i-1],则将 array[i] 后移,并将 i 前移,如i=3时, [1,3,4,2,0] => [1,3,4,4,0] => [1,3,3,4,0] => [1,2,3,4,0]
代码实现:
public void sort(int[] array) {
if (array.length == 0) {
return;
}
// 1.定义一个 要插入的坐标 temp,坐标是 i [i,n-1]
int temp;
int index;
for (int i = 1; i < array.length; i++) {
index = i - 1;
// 需要插入的值
temp = array[i];
// 2. 将 array[i] 和 有序数组array[0,i-1]比较
// 3. 如果 array[i] 小于 array[i-1],则将 array[i] 后移,并将 i 前移
// 如i=3时, [1,3,4,2,0] => [1,3,4,4,0] => [1,3,3,4,0] => [1,2,3,4,0]
while (index >= 0 && array[index] > temp) {
array[index + 1] = array[index];
index--;
}
// 插入
array[index + 1] = temp;
}
}
希尔排序
主要思想:希尔排序是确定步长先分组,再利用插入排序。
思路分析:
- 循环分组,每次 step = step/2。
- 对 array[step,n-1] 的值和其分组的前面的值进行直接插入排序。
代码实现:
public void sort(int[] array) {
// 步长 或者 组数
int step = array.length;
// 用于直接插入排序的 临时变量 和 下标
int temp;
int index;
while (step > 0) {
step = step / 2;
// 如果 step =2,则要对1组 array[0,2,4,6,8,10]进行直接插入排序
for (int i = step; i < array.length; i++) {
// 需要插入的值
temp = array[i];
// 需要比较的坐标
index = i - step;
while (index >= 0 && array[index] > temp) {
// 将index 的值后移
array[index + step] = array[index];
// index 迁移
index -= step;
}
// 插入数据
array[index + step] = temp;
}
}
}
选择排序
主要思想:从[i,n-1]选出最小的值放到 array[i]中。
思路分析:
- 对[i,n-1]进行排序,选出最小的值放到 array[i], i 的范围是 [0,n-1]。
- 定义一个指针 j ,范围是 [i+1,n-1]。
- 定义一个最小值的下标 min ,范围是[i,n-1] ,如果 array[j] 小于 array[min] ,则将最小值的下标 min 置为 j。
- 当 min > i时,则说明最小值不是 array[i],则交换。
代码实现:
public void sort(int[] array) {
int temp;
int min;
for (int i = 0; i < array.length; i++) {
min = i;
for (int j = i + 1; j < array.length; j++) {
if (array[j] < array[min]) {
// 跟 array[i]比较,如果 array[j]的值小,则将 [i,n-1]的最小值的下标置为 j
min = j;
}
}
// 如果 最小值的坐标大于 i,则交换
if (i < min) {
temp = array[min];
array[min] = array[i];
array[i] = temp;
}
}
}
快速排序
主要思想:确定一个中间值下标 left,将大于 array[left] 的值全部放到右边,小于 array[left] 的值全部放到左边,递归对左右两边进行相同的排序。
思路分析:
代码实现:
public void sort(int[] array) {
// 对 array 排序,基准值下标是 0
sort(array, 0, array.length - 1);
}
private void sort(int[] array, int left, int right) {
if (left >= right) {
return;
}
// 确定一个中间的坐标
int value = array[left];
// 根据中间值的大小移动左右两边的数
int l = left;
int r = right;
while (l < r) {
// 从右边找一个比value小的值, 赋值给 array[l]
while (l < r && array[r] >= value) {
r--;
}
array[l] = array[r];
// 从左边找一个比value大的值, 赋值给 array[r]
while (l < r && array[l] <= value) {
l++;
}
array[r] = array[l];
}
// 插入基准值
array[l] = value;
// 对两边的数进行排序
sort(array, left, l - 1);
sort(array, l + 1, right);
}