排序分为内部排序,外部排序。
内部排序分为:
冒泡排序,选择排序,插入排序,希尔排序,快速排序,归并排序,基数排序。
外部排序:主要是内存+外部存储文件方式的排序
1.冒泡排序
冒泡排序基本思想:通过对待排序序列从前往后,从下标0开始依次比较相邻元素的大小,如果是从小到大排序,则将较大值放在后面,即较大值放在索引较大的元素位置,反之如果是从大到小排序,将较大值放在索引较小的元素位置即可。
package Sort;
import javax.jws.soap.SOAPBinding;
import java.lang.reflect.Array;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
/**
* @auther SQ
*/
public class bubbleSort {
public static void main(String[] args) {
//int arr[] = {3, 9, -1, 10, 20};
//System.out.println("原本数组:" + Arrays.toString(arr));
// 冒泡排序 时间复杂度 O(n*n)
// 冒泡排序的优化
int num = 80000;
int arr[] = new int[num];
for (int i = 0; i < num; i++) {
arr[i] = (int) (Math.random() * num); //记得加上括号
}
Date date = new Date();
SimpleDateFormat sd = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
String sTime = sd.format(date);
System.out.println("开始时间:" + sTime);
// 冒泡排序
BubbleSort(arr);
Date date1 = new Date();
String eTime = sd.format(date1);
System.out.println("结束时间:"+eTime);
}
public static void BubbleSort(int[] arr) {
boolean flag = false;
int temp = 0;
int t = -1;
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
flag = true;
t = i;
temp = arr[j + 1];
arr[j + 1] = arr[j];
arr[j] = temp;
}
}
//System.out.println("第" + (i + 1) + "趟排序后的数组");
//System.out.println(Arrays.toString(arr));
// 冒泡排序的优化
if (!flag) { // 如果内层循环没有执行过一次的话,就跳出该循环
//System.out.printf("flag=%s,t=%d", flag, t);
//System.out.println();
break;
} else {
//System.out.printf("flag=%s,t=%d", flag, t);
//System.out.println();
flag = false;
}
}
}
}
开始时间:2022-07-07 15:59:39
结束时间:2022-07-07 15:59:52
2.选择排序
选择排序基本思路:
在一组数中选择最小的放在第一个位置,在剩下的元素中在选择最小的放在第二个位置,直到遍历完成。
package Sort;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
/**
* @auther SQ
*/
@SuppressWarnings("all")
public class SelectSort {
public static void main(String[] args) {
//int arr[] = {101, 34, 119, 1};
int num = 80000;
int arr[] = new int[num];
for (int i = 0; i < num; i++) {
arr[i] =(int) (Math.random() * num);
}
//System.out.println("排序前=" + Arrays.toString(arr));
Date date = new Date();
SimpleDateFormat sd = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
String sTime = sd.format(date);
System.out.println("开始时间:" + sTime);
//选择排序
selectsort(arr);
Date date1 = new Date();
String eTime = sd.format(date1);
System.out.println("结束时间:"+eTime);
}
public static void selectsort(int[] arr) {
// 选择排序
for (int i = 0; i < arr.length; i++) {
// 假定第一个为最小值
int min = arr[i];
int minIndex = i;
for (int j = i + 1; j < arr.length; j++) {
if (min > arr[j]) {
min = arr[j];
minIndex = j;
}
}
arr[minIndex] = arr[i];
arr[i] = min;
//System.out.println("第" + (i + 1) + "轮排序" + Arrays.toString(arr));
}
}
}
开始时间:2022-07-07 16:05:28
结束时间:2022-07-07 16:05:33
3.插入排序
插入排序的基本思想是:把n个待排序的元素看成为一个有序表和一个无序表,开始有序表只含有一个元素,无序表中有n-1个元素,排序过程中每次从无序表中取出第一个元素,把它跟有序表的第一个元素比较,比较之后如果大于有序表的第一个元素,将其放置在有序表的后面位置,无序表减1,使之成为新的有序表。(从小向后排列)
package Sort;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
/**
* @auther SQ
*/
@SuppressWarnings("all")
public class InsertSort {
public static void main(String[] args) {
int num = 80000;
int arr[] = new int[num];
for (int i = 0; i < num; i++) {
arr[i] =(int) (Math.random() * num);
}
//System.out.println("排序前=" + Arrays.toString(arr));
Date date = new Date();
SimpleDateFormat sd = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
String sTime = sd.format(date);
System.out.println("开始时间:" + sTime);
//选择排序
insertsort(arr);
Date date1 = new Date();
String eTime = sd.format(date1);
System.out.println("结束时间:"+eTime);
}
public static void insertsort(int[] arr) {
//插入排序
for (int i = 0; i < arr.length - 1; i++) {
int insertVal = arr[i + 1];
int insertIndex = i;
while (insertIndex >= 0 && insertVal < arr[insertIndex]) {
arr[insertIndex + 1] = arr[insertIndex]; // 大的值向后移一位
insertIndex--;
}
arr[insertIndex + 1] = insertVal;
}
}
}
开始时间:2022-07-07 17:25:23
结束时间:2022-07-07 17:25:24
4. 快速排序
package Sort;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
/**
* @auther SQ
*/
public class quickSort {
public static void main(String[] args) {
// int[] arr = {1, 5, -1, -3, 0, 2, -9, 20, -100};
// //System.out.println((int) Math.floor(5 / 2.0));
// shellsort(arr);
// System.out.println("排序后="+Arrays.toString(arr));
int num = 8000000;
int arr[] = new int[num];
for (int i = 0; i < num; i++) {
arr[i] =(int) (Math.random() * num);
}
//System.out.println("排序前=" + Arrays.toString(arr));
Date date = new Date();
SimpleDateFormat sd = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
String sTime = sd.format(date);
System.out.println("开始时间:" + sTime);
//选择排序
quicksort(arr, 0, arr.length - 1);
//System.out.println(Arrays.toString(arr));
Date date1 = new Date();
String eTime = sd.format(date1);
System.out.println("结束时间:" + eTime);
}
public static void quicksort(int[] arr, int left, int right) {
int l = left; //左下标
int r = right; //右下标
//pivot 中轴值
int pivot = arr[(left + right) / 2];
int temp = 0; //临时变量,作为交换时使用
//while循环的目的是让比pivot 值小放到左边
//比pivot 值大放到右边
while( l < r) {
//在pivot的左边一直找,找到大于等于pivot值,才退出
while( arr[l] < pivot) {
l += 1;
}
//在pivot的右边一直找,找到小于等于pivot值,才退出
while(arr[r] > pivot) {
r -= 1;
}
//如果l >= r说明pivot 的左右两的值,已经按照左边全部是
//小于等于pivot值,右边全部是大于等于pivot值
if( l >= r) {
break;
}
//交换
temp = arr[l];
arr[l] = arr[r];
arr[r] = temp;
//如果交换完后,发现这个arr[l] == pivot值 相等 r--, 前移
if(arr[l] == pivot) {
r -= 1;
}
//如果交换完后,发现这个arr[r] == pivot值 相等 l++, 后移
if(arr[r] == pivot) {
l += 1;
}
}
// 如果 l == r, 必须l++, r--, 否则为出现栈溢出
if (l == r) {
l += 1;
r -= 1;
}
//向左递归
if(left < r) {
quicksort(arr, left, r);
}
//向右递归
if(right > l) {
quicksort(arr, l, right);
}
}
}
排序算法对比
算法 | 执行时间 | 时间复杂度 | 算法思路比较 |
---|---|---|---|
冒泡排序 | 大约13s | O(n*n) | 外层循环执行n次,内层循环也执行n次,且内层两两元素比较 |
选择排序 | 大约4s | O(n*n) | 外层循环执行n次,内层循环执行n-1次,且找到最值内层寻找结束 |
插入排序 | 大约1s | O(n*n) | 外层循环执行n次,内层循环进行无序表中取出的元素,与有序列表进行对比 |