一.冒泡排序
冒泡排序是运行最慢点排序算法,但是确实最简单的。
下图可以理解为队员排队。
遵循的规则:
1. 比较两个队员。
2. 如果左边的队员高,则两队员位置交换。
3. 向右移动一个位置,比较下面的两个队员。
参照这样比较下去,虽然没有把所有队员位置排好,但是最高的队员已经在最右边的位置(如图d),此时,已经完成了第一趟排序,进行了N-1次比较。
现在重新回到队伍的最左端,开始第二趟排序,需要比较N-2次,完成后,第二高的队员已经在倒数第二的位置上。
不断执行这个过程,直到所有的队员都排定。
需要记住的2点:
1.相邻的两个数据比较。
2.一趟比较下来后,数组最右边的数据是有序的。
代码:主要代码逻辑
/**
*冒泡排序实现
*@param arr 传入数组
*/
public static void bubbleSort(int[] arr) { for (int i = arr.length-1; i > 0; i--) // 比较次数,第一趟排序比较N-1次,第二趟比较N-2次 { for (int j = 0; j < i; j++) // 执行比较 { if (arr[j] > arr[j + 1]) { // 交换 int temp = 0; temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } }
效率:
冒泡排序大约执行N2/2次比较,执行N2/4次交换,用大O表示法,时间复杂度为O(N2)。
选择排序比冒泡排序快,主要因为排序中交换只进行了一次。
思路:
1.排序从最左边的队员开始,在本子上记录最左端队员的身高,并且把标记该球员位置。
2.然后取下一个队员的身高与本子上的值比较。
(1)如果这个队员的身高更矮,则本子上划掉记录队员的身高数据,记录该队员的身高,并把标记移到该队员位置。
(2)如果这个队员更高,取下一个队员身高。
3.重复第2步,知道所有队员的身高都比较完成。此时,本子上记录的身高是矮的队员,标记记录这个队员所在的位置。
将这个队员与最左边的队员交换,这样,左边的队员身高是有序的(至少第一个队员是有序的)。
此时,总共进行了N-1次比较,1次交换。
需要记住的:
1.记录从最左端开始,记录未排序的第一个队员身高作为初始数据。
2.比较过程中,出现更矮的队员,刷新记录,并标记其位置。
3.交换只进行一次。
第二趟排序所做的事情是一模一样的,只不过忽略了第一个队员,从第二个队员开始(即初始本子上记录的是第二个队员的身高),
此时,总共进行N-2次比较,1次交换。
重复上述步骤,直到所有队员排序完成。
代码:
/** * 选择排序实现 * * @param arr 传入数组 */ public static void selectSort(int[] arr) { for (int i = 0; i < arr.length - 1; i++) // 比较次数,第一趟排序比较N-1次,第二趟比较N-2次 { // 标记队员身高的min位置,不记录值 int min = i; for (int j = i + 1; j < arr.length; j++) { // 如果发现有队员身高比记录的要矮,则队员位置赋值给min if (arr[j] < arr[min]) { min = j; } } // 左边数据与最小值数据交换 int temp = 0; temp = arr[min]; arr[min] = arr[i]; arr[i] = temp; } }
效率:
选择排序比较次数与冒泡排序一样,平均比较N2/2次,但是交换平均N/2次,但是如果N(数据量)很大,时间复杂度仍然为O(N2)。
插入排序是这三个排序算法中最好的一种,一般情况下,比冒泡排序快一倍,比选择排序还要快点。
插入排序的特点是:
1.局部有序
2.需要额外腾出个空位存储数据。
我们需要在已经排好序的队员中插入被标记的队员。此时
1.需要将标记队员位置“腾”出空位来。
2.从标记队员左边第一个队员开始,将左边队员身高与标记队员的身高比较。
(1)如果身高比标记的队员高,则将队员向右移动。
(2)如果身高比标记的队员矮,则停止移动。
3.重复步骤2,直到找到比标记队员矮的,或者没有队员比较为止,此时,就已经找到了标记队员应该处在的位置。
代码:
/** * 插入排序算法实现 * * @param arr 待排序数组 */ public static void insertSort(int[] arr) { for (int i = 1; i < arr.length; i++) // i从1开始,是因为认为arr[0]是已经排好序的 { // 腾出的空位存储临时队员的身高 int temp = arr[i]; // i为标记的队员位置 int j = i; // 遍历左边已经排好的数据,查找到合适的位置 while (j > 0 && arr[j - 1] >= temp) { // 将比标记的大的值右移 arr[j] = arr[j - 1]; --j; } //将临时存储的变量写入到数组中 arr[j] = temp; } }
效率:
插入排序算法中,平均比较了N*(N-1)/2次,交换了N次,所以时间复杂度为O(N2)。
简单排序需要用到步:
1.比较两个数据项;
2.交换两个数据项,或者复制其中一项;
简单排序中插入排序效果是最好的,但是在完成数据量排序的时候消耗的时间还是很长。
这三个排序方法很简单,对于一般小数据使用没问题,大数据量就需要高级排序方法了,比如希尔排序,快速排序,堆排序等。