学习笔记:Java中的基础排序算法
一、计算机如何实现排序
对于一组要进行排序的数据,人可以通览全局,立刻就可以找到最高的一个。计算机不能像人一样,它只能在同一时间内对两个数据比较。所以计算机中排序的基本步骤是:
- 比较两个数据项
- 交换两个数据项,或复制其中的一项
二、冒泡排序
基本步骤:
- 比较两个数据项
- 如果左边的数据大,就交换位置
- 向右移动位置,比较后面两个数据项
沿着这样的顺序,直到最右端,就可以把最大的数据项排到最右端。然后重回最左端进行第二次排序,再一次从左到右,两两比较,适当的交换位置,只需要比较到右端第二的位置,就可以把第二大的数据排到右端第二的位置。
不断的执行这个过程,直到最后一次排序操作时比较左端第一个数据和左端第二个数据,这样就可以得到整个有序的数组。
public class Sort {
public static void bubbleSort(int[] array) {
for (int j = array.length - 1; j > 0; j--) { //控制排序范围
int temp;
for (int i = 0; i < j; i++) { //从左到右,依次比较
if (array[i] > array[i + 1]) { //左边的数大,就交换位置
temp = array[i + 1];
array[i + 1] = array[i];
array[i] = temp;
}
}
}
}
}
测试代码:
@Test
public void test1() {
int[] array = {30,26,78,97,12,6};
Sort.bubbleSort(array);
}
}
在bubbleSort()
方法中添加一个遍历数组代码后输出结果:
6 12 26 30 78 97
冒泡排序在整个排序过程中都保持排序范围右边的所有数据项为有序。效率是O(N2),比较和交换次数都是N2级。
三、选择排序
选择排序改进了冒泡排序,交换次数从O(N^2)降到了O(N)级。
基本步骤:
- 选定一个数据项
- 从左到右扫描和选定的数据项比较,选出最小的数据项和最左端交换
沿着这个过程,直到最后右端第二个和第一个数据项的比较。
public static void selectSort(int[] array) {
for (int j = 0; j < array.length - 1; j++) { //确定扫描范围
int temp;
for (int i = j + 1; i < array.length; i++) { //从左向右依次扫描
if (array[j] > array[i]) { //有比选定数据项小的,就交换它们的位置
temp = array[i];
array[i] =array[j];
array[j] = temp;
}
}
}
}
}
测试代码:
@Test
public void test2() {
int[] array = {30,26,78,97,12,6};
Sort.selectSort(array);
}
在selectSort
中加入遍历数组数据项的代码后,测试结果是:
6 12 26 30 78 97
选择排序在排序过程中,扫描范围左边的所有的数据项都是有序的。选择排序和冒泡排序一样,比较的次数都是O(N*N)级,但是交换次数只有O(N)级,效率比冒泡排序高.
三、插入排序
插入排序算法时间复杂度和冒泡排序一样,但是效率比冒泡排序和选择排序好一些。
基本步骤:
- 标记一个未排序的数据项
- 将标记的数据项和它左边有序的数据项比较,移动有序数组中比标记数据项大的数据
- 直到有序数组中的数不比标记数据项大
循环这个过程,从数组中的数据项从左向右标记数据项,就得到整个有序的数组
public static void insertSort(int[] array) {
int j;
for (j = 1; j < array.length; j++) { //从左向右的标记范围
int temp = array[j];
int in = j;
while (in > 0 && array[in -1] > temp) { //大于就移动数据项
array[in] = array[in - 1];
in--;
}
array[in] = temp; // 直到小于前面的数
}
}
}
测试代码:
@Test
public void test3() {
int[] array = {30,26,78,97,12,6};
Sort.insertSort(array);
}
输出结果:
6 12 26 30 78 97
相比于冒泡排序,插入排序的平均比较次数和交换次数小一般,效率高一些,都是O(N*N)。对于基本有序的数据排序,良好情况下时间复杂度是O(N),不需要在while中移动数据项。
排序的稳定性,具有相同关键字的数据项,经过排序它们的顺序保持不变,这样的排序就是稳定的,上面的三种排序算法都是稳定的。