排序
排序算法是理解时间复杂与空间复杂度的最基础的练习 我们先以数组为例子
1 排序算法 时间复杂度 时间复杂度 空间复杂 1 冒泡,插入,选择 o(n^2) 1 2 快排,归并 o(nlogn) 1 3 桶,计算,基数 o(n) 1
快排
思路是找基准数,然后从低位,高位把大于与小于的基准数的数据交换。 交换过程直到低位>=高位结束,并把基准数移到中间。 然后左右分成两队,分别递归执行每队的找基数交换。 时间复杂度为nlogn,因为每次交换只有logn,最后每个数都需要n^2 参考https://blog.csdn.net/shujuelin/article/details/82423852
public static void main(String[] args) {
int[] arr = {10,7,2,4,7,62,3,4,2,1,8,9,19};
quickSort(arr, 0, arr.length-1);
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
public static void quickSort(int[] arr, int low2, int high2) {
int i = low2;
int j = high2;
//因为采用递归的实现。
if (i > j) {
return;
}
//取低位作为基准位
int temp = arr[i];
while (i < j) {
//先看右边,依次往左递减,找大于temp数据,直到low<high
while (temp <= arr[j] && i < j) {
j--;
}
while (temp >= arr[i] && i < j) {
i++;
}
//交换左右边的数据
if (i < j) {
int t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
arr[low2] = arr[i];
arr[i] = temp;
quickSort(arr,low2,j-1);
quickSort(arr,j+1,high2);
}
归并
归并排序的一般步骤为: 将待排序数组(链表)取中点并一分为二; 递归地对左半部分进行归并排序; 递归地对右半部分进行归并排序; 将两个半部分进行合并(merge),得到结果。 链表找中间点,首先用快慢指针(快慢指针思路,快指针一次走两步,慢指针一次走一步,快指针在链表末尾时,慢指针恰好在链表中点)的方法找到链表中间节点,然后递归的对两个子链表排序,把两个排好序的子链表合并成一条有序的链表。 数组找中间的,直接左右索引取中间数。
public static void main(String[] args) {
int[] arr = {10, 7, 2, 4, 7, 62, 3, 4, 2, 1, 8, 9, 19};
// quickSort(arr, 0, arr.length-1);
// for (int i = 0; i < arr.length; i++) {
// System.out.println(arr[i]);
// }
int[] temp = new int[10];
mergeSort(arr, temp);
System.out.println(arr);
}
public static void mergeSort(int[] arr, int[] tmp) {
mergeSort(arr, 0, arr.length - 1, tmp);
}
/**
* 左右分组排序
* @param arr
* @param p 开始
* @param r 结束
* @param tmp
*/
public static void mergeSort(int[] arr, int p, int r, int[] tmp) {
if (p >= r) {
return;
}
//取中间index位置
int q = (p + r) / 2;
mergeSort(arr, p, q, tmp); //对左边序列进行排序
mergeSort(arr, q + 1, r, tmp); //对右边序列进行排序
merge(arr, p, q, r, tmp);
}
/**
* 合并有序数据组
* @param arr
* @param p left
* @param q middle
* @param r right
* @param tmp
*/
public static void merge(int[] arr, int p, int q, int r, int[] tmp) {
int i = p;
int j = q + 1;
int k = 0;
while (i <= q && j <= r) {
if (arr[i] <= arr[j]) {
tmp[k++] = arr[i++];
} else {
tmp[k++] = arr[j++];
}
}
int start = i;
int end = q;
if (j <= r) {
start = j;
end = r;
}
while (start <= end) {
tmp[k++] = arr[start++];
}
for (int m = 0; m <= r - p; m++) {
arr[m + p] = tmp[m];
}
}
}
插入
插入意思n元素与前面的n-1的有序元素依次比较,并交换位子。来找到自己位子。 n后面的元素是准备下次循环比较的元素。
package com.owntools.algorithm.sort;
import java.util.Arrays;
public class InsertSort {
public static void main(String[] args) {
int[] arr = {10, 7, 2, 4, 7, 62, 3, 4, 2, 1, 8, 9, 19};
insertSort(arr);
System.out.println(Arrays.toString(arr));
}
public static void insertSort(int[] arr) {
for (int i = 0; i < arr.length-1; i++) {
for (int j = i+1; j > 0; j--) {
if (arr[j - 1] > arr[j]) {
int b = arr[j - 1];
arr[j - 1] = arr[j];
arr[j] = b;
}
}
}
}
}
冒泡
选择
选择排序的意思n元素与n后面的元素比较,并利用中间变量记录min值的下标,比较完成后。 完成n与min值的交换。
package com.owntools.algorithm.sort;
import java.util.Arrays;
public class selectSort {
public static void main(String[] args) {
int[] arr = {10, 7, 2, 4, 7, 62, 3, 4, 2, 1, 8, 9, 19};
int[] temp = new int[10];
selectSort(arr);
System.out.println(Arrays.toString(arr));
}
public static void selectSort(int[] arr){
for(int i=0;i<arr.length;i++){
int min=i;
for(int j=i+1;j<arr.length;j++){
if(arr[j]<arr[min]){
min=j;
}
}
if(min!=i){
int t=arr[min];
arr[min]=arr[i];
arr[i]=t;
}
}
}
}