排序算法 |
时间复杂度 |
是否基于比较 |
冒泡、插入、选择 |
O(n²) |
是 |
快排、归并 |
O(nlogn) |
是 |
桶、计数、基数 |
O(n) |
否 |
如果待排序的序列中存在值相等的元素,经过排序之后,相等元素之间原有的先后顺序不变,那么这种排序算法就是稳定的。
冒泡排序:顾名思义,就是将最大的数放在数组尾部,逐渐实现排序。最好情况时间复杂度是 O(n)。而最坏的情况是,要排序的数据刚好是倒序排列的,我们需要进行 n 次冒泡操作,所以最坏情况时间复杂度为 O(n2)。
Java代码实现方案:
public class BubboSort {
private static void sort(double[] nums){
for (int i=0; i<nums.length; i++) {
for(int j=0; j<nums.length-i-1; j++) {
if(nums[j] > nums[j+1]) {
double tmp = nums[j];
nums[j] = nums[j+1];
nums[j+1] = tmp;
}
}
}
}
public static void main(String[] args) {
double[] nums = {2,6,9,7,1,2,6,-52,24,8};
sort(nums);
for (int i=0; i<nums.length; i++){
System.out.println(nums[i]);
}
}
}
插入排序:我们将数组中的数据分为两个区间,已排序区间和未排序区间。初始已排序区间只有一个元素,就是数组的第一个元素。插入算法的核心思想是取未排序区间中的元素,在已排序区间中找到合适的插入位置将其插入,并保证已排序区间数据一直有序。重复这个过程,直到未排序区间中元素为空,算法结束
public class InsertSort {
private static void sort(double[] nums){
if(nums.length <2) {
return;
}
for(int i=1; i<nums.length; i++) {
double value = nums[i];
int j = i-1;
for (; j>=0; j--) {
if(value < nums[j]){
nums[j+1] = nums[j];
} else {
break;
}
}
nums[j+1] = value;
}
System.out.println(nums);
}
public static void main(String[] args) {
double[] nums = {1,6,5,89,1,2};
sort(nums);
for(int i=0; i<nums.length; i++) {
System.out.println(nums[i]);
}
}
}
选择排序:选择排序,从头至尾扫描序列,找出最小的一个元素,和第一个元素交换,接着从剩下的元素中继续这种选择和交换方式,最终得到一个有序序列。
public class SelectSort {
public static void main(String[] args) {
int [] arr = {49,38,65,97,76,13,27,49};
selectSort(arr,arr.length);
}
public static void selectSort(int [] arr,int n){
for (int i = 0; i < n - 1; i++) {
int index = i;
int j;
// 找出最小值得元素下标
for (j = i + 1; j < n; j++) {
if (arr[j] < arr[index]) {
index = j;
}
}
int tmp = arr[index];
arr[index] = arr[i];
arr[i] = tmp;
System.out.println(Arrays.toString(arr));
}
}
}
归并排序和快速排序时间复杂度未O(nlogn),适合大规模的数据排序,其实现都用到了分治思想分治算法一般都是用递归来实现的,分治是一种捷径问题的处理思想,递归是一种编程技巧。
归并排序:归并排序算法是一种在任何情况下时间复杂度都比较稳定的排序算法,这也使它存在致命的缺点,即归并排序不是原地排序算法,空间复杂度比较高,是 O(n)。正因为此,它也没有快排应用广泛。
转载:https://blog.csdn.net/haochajin/article/details/100934731