前言:



排序算法有很多种,如选择排序、插入排序、冒泡排序、桶排序、快速排序等等。这里介绍的是简化版桶排序、冒泡排序和插入排序。



推荐一本算法入门书——《啊哈!算法》



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),另外选择排序也是。插入排序和冒泡排序的思想其实是相似的,通过将大小不同的两个值对调索引来实现排序,不过插入排序相对于冒泡排序而言所用时间应该更少一点。