1、冒泡排序
冒泡排序是知名排序方式,逻辑简单,实现起来也容易;
总的来说就是两层for循环,缺点就是时间复杂度较高。
一共进行n-1次循环,总比较次数:(n-1)+(n-2)+(n-3)……2+1=n*(n-1)/2,时间复杂度为O(n²)。
代码如下:
public class BubbleSort {public static void main(String[] args) {int[] arr = {12, 45, 5677, 344, 56, 3, 546, 2435};//冒泡排序int[] bubbleSort = bubbleSort(arr);System.out.println(Arrays.toString(bubbleSort));}/*** 冒泡排序** @param arr*/public static int[] bubbleSort(int[] arr) {//i控制循环次数,长度为len的数组只需要循环len-1次,i的起始值为0所以i<len-1for (int i = 0; i < arr.length - 1; i++) {//但是由于是由arr[j]跟arr[j+1]进行比较,所以为了保证arr[j+1]不越界,j<len-i-1for (int l = 0; l < arr.length - i - 1; l++) {if (arr[l] > arr[l + 1]) {//交换两个数,//如果前一个数比后一个数大,则交换位置将大的数往后放。arr[l + 1] = arr[l + 1] ^ arr[l];arr[l] = arr[l + 1] ^ arr[l];arr[l + 1] = arr[l + 1] ^ arr[l];}}}return arr;}
2、选择排序
选择排序是比冒泡更为快速的排序方式,时间复杂度有所降低,实现思路如下:
- 将第一个值看成最小值
- 然后和后续的比较找出最小值和下标
- 交换本次遍历的起始值和最小值
- 说明:每次遍历的时候,将前面找出的最小值,看成一个有序的列表,后面的看成无序的列表,然后每次遍历无序列表找出最小值。
实现代码如下:
/*** 选择排序** @return*/public static int[] selectSort(int[] arr) {//第一次循环数组for (int i = 0; i < arr.length - 1; i++) {//定义最小数下标int miniIndex = i;//第二次循环数组for (int l = i + 1; l < arr.length; l++) {//碰到比最小值小的,重新标记最小标if (arr[l] < arr[miniIndex]) {miniIndex = l;}}//交换下标对于数值if (miniIndex != i) {arr[miniIndex] = arr[miniIndex] ^ arr[i];arr[i] = arr[miniIndex] ^ arr[i];arr[miniIndex] = arr[miniIndex] ^ arr[i];}}return arr;}
3、归并排序
归并排序体现了分治思想,把排序对象分割成两个,在进行比对大小,思路如下:
- 将列表按照对等的方式进行拆分
- 拆分小最小快的时候,在将最小块按照原来的拆分,进行合并
- 合并的时候,通过左右两块的左边开始比较大小。小的数据放入新的块中
- 说明:简单一点就是先对半拆成最小单位,然后将两半数据合并成一个有序的列表。
代码实现如下:
/*** 归并排序** @return*/public static int[] mergeSort(int[] arr) {if (arr.length<=1) {return arr;}//得到数组长度中值int num = arr.length >> 1;int[] left = Arrays.copyOfRange(arr, 0, num);int[] right = Arrays.copyOfRange(arr, num, arr.length);//合并方法,递归return merge(mergeSort(left), mergeSort(right));}//归并排序合并方法private static int[] merge(int[] a, int[] b) {int i = 0, j = 0, k = 0;int[] result = new int[a.length + b.length];while (i < a.length && j < b.length) {if (a[i] <= b[j]) {result[k++] = a[i++];} else {result[k++] = b[j++];}}while (i < a.length) {result[k++] = a[i++];}while (j < b.length) {result[k++] = b[j++];}return result;}
4、快速排序
快速排序是最近面试常考排序方法,建议多练习;
快速排序也体现了分治思想,思路如下:
- 选择基点的值(随意,建议去下标中值)
- 将比基点值小的值放在左边,比基点值大的放在右边,这样基点左边都是比基点小的,右边都是比基点大的
- 分别对左右两边进行递归运算
代码如下:
import java.util.Arrays;/*** 快速排序*/public class QuickSort {public static void main(String[] args) {int[] arr = {14, 25, 255, 7, 6, 89, 52, -5, 58, -88, -9, 5845, 4};quickSort(arr, 0, arr.length - 1);System.out.println("arr:" + Arrays.toString(arr));}/*** 排序方法** @param arr 数组* @param left 左下标* @param right 右下标*/private static void quickSort(int[] arr, int left, int right) {int l = left;int r = right;int pivot = arr[(left + right) / 2];int temp = 0;while (l < r) {//找到左边大于等于pivot的值下标while (arr[l] < pivot) {l += 1;}//找到右边小于等于pivot的值下标while (arr[r] > pivot) {r -= 1;}if (l >= r) {break;}//交换值temp = arr[l];arr[l] = arr[r];arr[r] = temp;//如果交换完成后,发现arr[l]==pivot,r--,r左移一位if (arr[l] == pivot) {r -= 1;}//如果交换完成后,发现arr[l]==pivot,r--,r左移一位if (arr[r] == pivot) {l += 1;}//如果l==r,错开,否则造成栈溢出if (l == r) {l += 1;r -= 1;}//向左递归if (left < r) {quickSort(arr, left, r);}//向右递归if (right > l) {quickSort(arr, l, right);}}}}
