交换排序-冒泡排序与快速排序
交换排序中最常用的是冒泡排序和快速排序。
1、冒泡排序
原理:通过比较两个相邻元素的大小,决定是否交换两个元素的位置,来进行排序。
对一个数组来说,每次从头或者尾进行比较,每执行一次循环,都会把一个最小的(相对于未排序的序列来说)放在最前面,或者把最大的放在最后面:这要取决于你的内层循环是从数组头还是尾开始的。
void maopao(int[] arr) { boolean b = true;//设置一个标志,用来判断在某次循环中是否进行了数据交换,若没有交换,则此数组已经是正确的顺序了 while (b) { for (int i = 0; i < arr.length; i++) {//外层循环控制排序的趟数 b = false; for (int j = 0; j < arr.length - 1 - i; j++) {//内层循环控制每趟中元素的比较, //j<arr.length-1-i此处-i是表示此时后面的序列已经是排好的了,没必要再进行比较 if (arr[j] > arr[j + 1]) { int temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; b = true; } } } } for (int a : arr) { System.out.print(a + " "); } }
冒泡排序是入门级排序算法,当时学的时候也是感觉这个是最容易理解,也是学起来最容易的。
时间复杂度:O(n^2) 由此可以看出冒泡排序时间复杂度较高
稳定性:稳定(稳定性是指排序后是否会改变相等元素在数组中的相对位置)。
2、快速排序
快速排序被誉为“20世纪最伟大的十大经典算法”,对大量数据进行排序有较高的效率。
思想:分治策略
原理:取出一个基准值(一般取数组第一个或者最后一个),与剩下的元素进行比较,将比它小的放在它前面,比它大的放在它后面,这样这个基准值就在他的正确位置了,然后再分别对左侧和右侧的数据进行排序。
算法实现具体方法:(我曾看到一个“填坑法”,通俗易懂,十分容易理解)下面在代码中解释
public void quicksort(int[] arr, int left, int right) { //用两个指针分别从待排序列的左右两侧进行扫描 int l = left, r = right, temp = arr[l];//temp为中间变量,将待排序列最左侧元素“挖”出,此时形成一个坑 while (l < r) { while (l < r && arr[r] > temp)//从序列右边进行扫描 r--;
if(l<r) arr[l] = arr[r];//遇到比基准值大的,填入第一个坑中,此时它形成一个坑 while (l < r && arr[l] <= temp) l++;
if(l<r) arr[r] = arr[l];//找到比基准值小的,填入刚形成的坑中 } arr[l] = temp; quicksort(arr, l + 1, right);//递归调用 quicksort(arr, left, l - 1); } }
平均时间复杂度:O(nlog2n)
稳定性:不稳定