前言:
排序算法有很多种,如选择排序、插入排序、冒泡排序、桶排序、快速排序等等。这里介绍的是简化版桶排序、冒泡排序和插入排序。
推荐一本算法入门书——《啊哈!算法》
1. 桶排序[简化版]:
原理:新建一个book数组用来标记原数组每一个数字出现的个数。
public static int[] bottomSort(int[] nums) {
int[] res = new int[nums.length];
int temp = nums[0];
for (int lang : nums)
temp = Math.max(temp, lang);
int[] book = new int[temp + 1];
for (int i = 0; i < nums.length; i++) {
book[nums[i]]++;
}
int z = 0;
for (int i = 0; i <= book.length - 1; i++) { //由小到大排序。
for (int j = 1; j <= book[i]; j++) {
res[z] = i;
z++;
}
}
return res;
}
桶排序的优缺点:
优点:
时间复杂度为O(M+N),运行非常快速。
缺点:
1.由于book数组的大小由原数组中最大值决定,因此非常地浪费空间。
2.只能处理int型数组,不能处理float/double型数组。
2.冒泡排序
冒泡排序所用代码最少,易于理解和记忆,所以使用最是频繁。
冒泡排序的基本思想是:每次比较两个相邻的元素,如果它们的顺序错误就把它们交换过来.冒泡排序的核心部分是双重嵌套循环。
public static void bubbleSort(int[] nums) {
for (int i = 0; i < nums.length; i++) {
for (int j = 0; j < nums.length; j++) {
if (nums[i] < nums[j] && i > j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
}
}
冒泡排序优缺点:
优点:
代码量少,易于使用。
缺点:
冒泡排序的时间复杂度是O(N^2)。这是一个非常高的时间复杂度。
假如我们的计算机每秒钟可以运行10亿次,那么对1亿个数进行排序,桶排序只需要0.1秒,而冒泡排序则需要1千万秒(引用自《啊哈!算法》)
3. 插入排序:
插入排序基本思想:
插入算法把要排序的数组分成两部分:第一部分包含了这个数组的所有元素,但将最后一个元素除外(让数组多一个空间才有插入的位置),而第二部分就只包含这一个元素(即待插入元素)。在第一部分排序完成后,再将这个最后元素插入到已排好序的第一部分中。插入排序的基本思想是:每步将一个待排序的纪录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。
public static int[] InsertSort(int[] arr) {
int i, j;
int insertNote;// 要插入的数据
int[] array = arr;
// 从数组的第二个元素开始循环将数组中的元素插入
for (i = 1; i < array.length; i++) {
// 设置数组中的第2个元素为第一次循环要插入的数据
insertNote = array[i];
j = i - 1;
while (j >= 0 && insertNote < array[j]) {
// 如果要插入的元素小于第j个元素,就将第j个元素向后移动
array[j + 1] = array[j];
j--;
}
// 直到要插入的元素不小于第j个元素,将insertNote插入到数组中
array[j + 1] = insertNote;
}
return array;
}
插入排序的时间复杂度也是O(n^2),另外选择排序也是。插入排序和冒泡排序的思想其实是相似的,通过将大小不同的两个值对调索引来实现排序,不过插入排序相对于冒泡排序而言所用时间应该更少一点。