冒泡排序 O(n2 )
它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成
排序过程
- 比较相邻的元素。如果第一个比第二个大,就交换它们两个
- 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在 最后的元素应该会是最大的数
- 针对所有的元素重复以上的步骤,除了最后一个
- 重复步骤1~3,直到排序完成
图解演示
JAVA代码实现
public static int[] bubbleSort(int[] array) {
int len = array.length;
for(int i = 0; i < len - 1; i++) {
for(int j = 0; j < len - 1 - i; j ++) {
if(array[j] > array[j+1]) {
int flag = array[j];
array[j] = array[j+1];
array[j+1] = flag;
}
}
}
return array;
}
选择排序 O(n2 )
选择排序算法的基本思路是为每一个位置选择当前最小/大的元素。选择排序的基本思想是,基于直接选择排序和堆排序这两种基本的简单排序方法。使用这种排序时,需要注意的是,在排序过程中可能导致原本相等数据位置顺序的交互。因此,我们说选择排序不是稳定的排序算法,它在计算过程中会破坏稳定性。(例如:图例中的58547升序排序,第一个5要排在第二个5后面)
public static int[] bubbleSort(int[] array) {
int len = array.length;
if (len == 0 || len == 1) return array;
for (int i = 0; i < len; i++) {
for (int j = i + 1; j < len; j++) {
if (array [i] > array[j]) {
int flag = array[i];
array[i] = array[j];
array[j] = flag;
}
}
}
return array;
}
排序过程
- 首先从第1个位置开始对全部元素进行选择,选出全部元素中最小/大的给该位置
- 再对第2个位置进行选择,在剩余元素中选择最小/大的给该位置即可
- 以此类推,重复进行“最小/大元素”的选择
图解演示
快速排序 O(nlgn)
通过一趟排序算法把需要排序的元素分割成两块,其中,一部分的元素都要小于或等于另外一部分的元素,然后仍根据该种方法对划分后的这两块序列的元素分别再次进行快速排序,排序实现的整个过程可以是递归的来进行调用,最终能够实现将所需排序的无序序列元素变为一个有序的序列。
排序过程
- 挑选一个分界值,通过该分界值将数组分成左右两部分
- 将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值
- 然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理
- 重复上述过程,通过递归将左侧部分排好序后,再递归排好右侧部分的顺序
图解演示
JAVA代码
public static void sort(int[] array, int left, int right) {
if(left > right) {
return;
}
// base中存放基准数
int base = array[left];
int i = left, j = right;
while(i != j) {
// 从右边开始往左找,直到找到比base值小的数
while(array[j] >= base && i < j) {
j--;
}
// 从左往右边找,直到找到比base值大的数
while(array[i] <= base && i < j) {
i++;
}
// 上面的循环结束表示已经找到了位置或i大于等于j,交换两个元素的位置
if(i < j) {
int tmp = array[i];
array[i] = array[j];
array[j] = tmp;
}
}
// 将基准数放到中间的位置(基准数归位)
array[left] = array[i];
array[i] = base;
// 对基准值左右两边的元素进行递归,排序
sort(array, left, i - 1);
sort(array, i + 1, right);
}