所谓排序算法,即通过特定的算法因式将一组或多组数据按照既定模式进行重新排序。这种新序列遵循着一定的规则,体现出一定的规律,因此,经处理后的数据便于筛选和计算,大大提高了计算效率。
对于排序:
我们首先要求其具有一定的稳定性
即当两个相同的元素同时出现于某个序列之中
则经过一定的排序算法之后
两者在排序前后的相对位置不发生变化。
所以,就让我们先来看看,面试中,有哪些超高频的排序算法
冒泡排序冒泡排序可以说是最基础的了,无非就是两个 for 循环嵌套,然后两两比较交换罢了。这就不多说了。
步骤:1、比较相邻的元素。如果第一个比第二个大(小),就交换他们两个。
2、对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大(小)的数。
3、针对所有的元素重复以上的步骤,除了最后已经选出的元素(有序)。
4、持续每次对越来越少的元素(无序元素)重复上面的步骤,直到没有任何
视频:数据结构排序算法之冒泡排序演示
示例代码: public void bubbleSort(int[] arr) { int temp = 0; boolean swap; for (int i = arr.length - 1; i > 0; i--) { // 每次需要排序的长度 // 增加一个swap的标志,当前一轮没有进行交换时,说明数组已经有序 swap = false; for (int j = 0; j < i; j++) { // 从第一个元素到第i个元素 if (arr[j] > arr[j + 1]) { temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; swap = true; } } if (!swap){ break; } } }对于归并排序而言,思想可以概括为:分而治之。也就是将一个数组,首先划分为一堆单个的数,然后再一个接一个的,进行两两有序合并,最后就得到了一个有序数组。
步骤:将待排序的数列分成若干个长度为1的子数列
然后将这些数列两两合并;得到若干个长度为2的有序数列
再将这些数列两两合并;得到若干个长度为4的有序数列
再将它们两两合并;直接合并成一个数列为止
这样就得到了我们想要的排序结果
视频:归并排序
示例代码: // 入口 public void mergeSort(int[] arr) { int[] temp = new int[arr.length]; internalMergeSort(arr, temp, 0, arr.length - 1); } private void internalMergeSort(int[] arr, int[] temp, int left, int right) { // 当left == right时,不需要再划分 if (left < right) { int mid = (left + right) / 2; // 左右往下拆分 internalMergeSort(arr, temp, left, mid); internalMergeSort(arr, temp, mid + 1, right); // 拆分结束后返回结果进行合并 mergeSortedArray(arr, temp, left, mid, right); } } // 合并两个有序子序列 public void mergeSortedArray(int[] arr, int[] temp, int left, int mid, int right) { int i = left; int j = mid + 1; int k = 0; while (i <= mid && j <= right) { temp[k++] = arr[i] < arr[j] ? arr[i++] : arr[j++]; } // 合并完,将非空的那列拼入 while (i <= mid) { temp[k++] = arr[i++]; } while (j <= right) { temp[k++] = arr[j++]; } // 把temp数据复制回原数组 for (i = 0; i < k; i++) { arr[left + i] = temp[i]; } }快速排序的思想,可以简单的概括为:两边包抄、一次一个。每选一个基准点,一次排序后确定它的最终位置,一步到位。
步骤:1、先从数列中取出一个数作为基准数
2、分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边
3、再对左右区间重复第二步,直到各区间只有一个数
概括来说为 挖坑填数+分治法
注: 快排算法不唯一,到目前为止我已经看到三种排法,这里我用最老的,就是很多教材上的排法解析
视频:快速排序算法
示例代码: public void quickSort(int[] arr){ quickSort(arr, 0, arr.length-1); } private void quickSort(int[] arr, int low, int high){ if (low >= high) return; int pivot = partition(arr, low, high); //将数组分为两部分 quickSort(arr, low, pivot - 1); //递归排序左子数组 quickSort(arr, pivot + 1, high); //递归排序右子数组 } private int partition(int[] arr, int low, int high){ int pivot = arr[low]; //基准 while (low < high){ while (low < high && arr[high] >= pivot) { high--; } arr[low] = arr[high]; //交换比基准大的记录到左端 while (low < high && arr[low] <= pivot) { low++; } arr[high] = arr[low]; //交换比基准小的记录到右端 } //扫描完成,基准到位 arr[low] = pivot; //返回的是基准的位置 return low; }计数排序顾名思义,其思想就在于记录各个数的出现次数,最后按顺序取出即可。
步骤:建一个长度为K+1的的数组C,里面的每一个元素初始都置为0(Java里面默认就是0)。
遍历待排序的数组,计算其中的每一个元素出现的次数,比如一个key为i的元素出现了3次,那么C[i]=3。
累加C数组,获得元素的排位,从0开始遍历C, C[i+1]=C[i]+C[i-1]