对于一组要进行排序的数据,人可以通览全局,立刻就可以找到最高的一个。计算机不能像人一样,它只能在同一时间内对两个数据比较。所以计算机中排序的基本步骤是:
基本步骤:
沿着这样的顺序,直到最右端,就可以把最大的数据项排到最右端。然后重回最左端进行第二次排序,再一次从左到右,两两比较,适当的交换位置,只需要比较到右端第二的位置,就可以把第二大的数据排到右端第二的位置。
不断的执行这个过程,直到最后一次排序操作时比较左端第一个数据和左端第二个数据,这样就可以得到整个有序的数组。
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中移动数据项。
排序的稳定性,具有相同关键字的数据项,经过排序它们的顺序保持不变,这样的排序就是稳定的,上面的三种排序算法都是稳定的。