文章目录
- 排序分类/排序算法的分类
- 冒泡排序
- 代码1:
- 代码2(优化
- 代码3(算法优化 --当次排序没有进行交换则退出循环
- 代码4(封装为方法
- 代码5(检测冒泡排序时间复杂度
- 选择排序
- 代码1
- 代码2(优化算法
- 代码3(计算时间复杂度
- 插入排序
- 代码
- 时间复杂度
- 希尔排序
- 交换法
- 时间复杂度
- 移位法(效率高
排序分类/排序算法的分类
冒泡排序
介绍
模拟/思路讲解
数组转换成String类型输
代码1:
package Sort;
import java.lang.reflect.Array;
import java.util.Arrays;
public class BubbleSort {
public static void main(String[] args) {
int arr[] = {3,9,-1,10,-2};//从小到大排序
//第一趟排序 就是将最大的数排在最后
int temp = 0;//临时变量
for (int i = 0; i < arr.length-1; i++) {
if (arr[i] > arr[i+1]){
temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
}
System.out.println("第一趟排序后的数组:");
//???toString
System.out.println(Arrays.toString(arr));
//第二趟排序 就是第二大的数排在倒数第二位
for (int i = 0; i < arr.length - 2; i++) {
if (arr[i] > arr[i+1]){
temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
}
System.out.println("第二趟排序后的数组:");
//???toString
System.out.println(Arrays.toString(arr));
//第三趟排序 就是将第三大的数排在倒数第三位
for (int i = 0; i < arr.length - 3; i++) {
if (arr[i] > arr[i+1]){
temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
}
System.out.println("第三趟排序后的数组:");
//???toString
System.out.println(Arrays.toString(arr));
//第四趟排序 就是将第四大的数排在倒数第三位
for (int i = 0; i < arr.length - 4; i++) {
if (arr[i] > arr[i+1]){
temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
}
System.out.println("第四趟排序后的数组:");
//???toString
System.out.println(Arrays.toString(arr));
}
}
代码2(优化
package Sort;
import java.lang.reflect.Array;
import java.util.Arrays;
public class BubbleSort {
public static void main(String[] args) {
int arr[] = {3,9,-1,10,-2};//从小到大排序
//第一趟排序 就是将最大的数排在最后
int temp = 0;//临时变量
for (int i = 0; i < arr.length-1; i++) {
for (int j = 0; j < arr.length-1-i; j++) {
if (arr[j] > arr[j+1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
System.out.println("第"+(i+1)+"趟排序后的数组:");
System.out.println(Arrays.toString(arr));
}
}
}
代码3(算法优化 --当次排序没有进行交换则退出循环
package Sort;
import java.lang.reflect.Array;
import java.util.Arrays;
public class BubbleSort {
public static void main(String[] args) {
int arr[] = {3,-1,9,10,20};//从小到大排序
//第一趟排序 就是将最大的数排在最后
int temp = 0;//临时变量
boolean flag = false;
for (int i = 0; i < arr.length-1; i++) {
for (int j = 0; j < arr.length-1-i; j++) {
if (arr[j] > arr[j+1]){
flag = true;
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
System.out.println("第"+(i+1)+"趟排序后的数组:");
System.out.println(Arrays.toString(arr));
if (!flag){
break;
}else {
flag = false;
}
}
}
}
代码4(封装为方法
代码5(检测冒泡排序时间复杂度
package Sort;
import java.lang.reflect.Array;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
public class BubbleSort {
public static void main(String[] args) {
// int arr[] = {3,-1,9,10,20};//从小到大排序
int[] arr = new int[80000];
for (int i = 0; i < 80000; i++) {
arr[i] = (int)(Math.random() * 8000000);//生成[0,8000000)的数
}
Date date1 = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date1Str = simpleDateFormat.format(date1);
System.out.println("排序前的时间是="+date1Str);
//测试冒泡排序
bubbleSort(arr);
Date date2 = new Date();
String date2Str = simpleDateFormat.format(date2);
System.out.println("排序后的时间是="+date2Str);
}
public static void bubbleSort(int[] arr){
//第一趟排序 就是将最大的数排在最后
int temp = 0;//临时变量
boolean flag = false;
for (int i = 0; i < arr.length-1; i++) {
for (int j = 0; j < arr.length-1-i; j++) {
if (arr[j] > arr[j+1]){
flag = true;
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
// System.out.println("第"+(i+1)+"趟排序后的数组:");
// System.out.println(Arrays.toString(arr));
if (!flag){
break;
}else {
flag = false;
}
}
}
}
冒泡排序时间复杂度:O(n2 )
选择排序
选择排序思路:
图解流程:
代码1
package Sort;
import java.util.Arrays;
public class SelectSort {
public static void main(String[] args) {
int[] arr = {101, 119, 34,1};
System.out.println("排序前:");
System.out.println(Arrays.toString(arr));
selectSort(arr);
}
public static void selectSort(int[] arr) {
//第1轮
int minIndex = 0;
int min = arr[0];
for (int i = 0 + 1; i < arr.length; i++) {
if (min > arr[i]) {//说明假定的最小值不是最小的
min = arr[i]; //重置min
minIndex = i; //重置minIndex
}
}
// System.out.println("minIndex = "+minIndex);
// System.out.println("min = "+min);
//将最小值元素与arr[0] 两者交换
if (minIndex != 0){
arr[minIndex] = arr[0];
arr[0] = min;
}
System.out.println("第1轮后:");
System.out.println(Arrays.toString(arr));
//第2轮
minIndex = 1;
min = arr[1];
for (int i = 1 + 1; i < arr.length; i++) {
if (min > arr[i]) {//说明假定的最小值不是最小的
min = arr[i]; //重置min
minIndex = i; //重置minIndex
}
}
//将最小值元素与arr[0] 两者交换
if (minIndex != 1){
arr[minIndex] = arr[1];
arr[1] = min;
}
System.out.println("第2轮后:");
System.out.println(Arrays.toString(arr));
//第3轮
minIndex = 3;
min = arr[3];
for (int i = 2 + 1; i < arr.length; i++) {
if (min > arr[i]) {//说明假定的最小值不是最小的
min = arr[i]; //重置min
minIndex = i; //重置minIndex
}
}
//将最小值元素与arr[0] 两者交换
if (minIndex != 3){
arr[minIndex] = arr[2];
arr[2] = min;
}
System.out.println("第3轮后:");
System.out.println(Arrays.toString(arr));
}
}
代码2(优化算法
package Sort;
import java.util.Arrays;
public class SelectSort {
public static void main(String[] args) {
int[] arr = {101, 119, 34,1,-1,90,123};
System.out.println("排序前:");
System.out.println(Arrays.toString(arr));
selectSort(arr);
System.out.println("排序后:");
System.out.println(Arrays.toString(arr));
}
public static void selectSort(int[] arr) {
for (int i = 0; i < arr.length-1; i++) {
//第1轮
int minIndex = i;
int min = arr[i];
for (int j = i + 1; j < arr.length; j++) {
if (min > arr[j]) {//说明假定的最小值不是最小的
min = arr[j]; //重置min
minIndex = j; //重置minIndex
}
}
//将最小值元素与arr[0] 两者交换
if (minIndex != i){
arr[minIndex] = arr[i];
arr[i] = min;
}
// System.out.println("第"+(i+1)+"轮后:");
// System.out.println(Arrays.toString(arr));
}
}
}
选择排序的时间复杂度是O(n2 )
比冒泡排序快的原因:
多了个判断筛选,减小循环次数
代码3(计算时间复杂度
main内
//计算选择排序的时间复杂度
int[] arr = new int[80000];
for (int i = 0; i < 80000; i++) {
arr[i] = (int)(Math.random() * 8000000);//生成[0,8000000)的数
}
Date date1 = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date1Str = simpleDateFormat.format(date1);
System.out.println("排序前的时间是="+date1Str);
//测试冒泡排序
selectSort(arr);
Date date2 = new Date();
String date2Str = simpleDateFormat.format(date2);
System.out.println("排序后的时间是="+date2Str);
插入排序
思想
思路图
代码
package Sort;
import java.util.Arrays;
public class InsertSort {
public static void main(String[] args) {
//从小到大
int[] arr = {101,34,119,1,-1,89};
insertSort(arr);
}
public static void insertSort(int[] arr){
for (int i = 1; i < arr.length; i++) {
int insertVal = arr[i];
int insertIndex = i-1; //arr[1]前面数的下标
//1.insertIndex >= 0:保证不越界
//2.insertVal < arr[insertIndex]还没找到插入位置
while (insertIndex >= 0 && insertVal < arr[insertIndex]){
arr[insertIndex+1] = arr[insertIndex]; //将arr[insertIndex]后移
insertIndex--;//让arr[1]再和前面的数进行比较
}
//当退出while循环时 说明插入的位置找到 insertIndex+1(因为
// 1.insertIndex可能--多了
// 2.就算arr[1]=334则一开始不需要insertIndex-1
arr[insertIndex + 1] = insertVal;
System.out.println("第"+i+"轮插入:");
System.out.println(Arrays.toString(arr));
}
}
}
优化:
if (insertIndex+1 != i){
arr[insertIndex + 1] = insertVal;
}
例如arr[1]一开始为334 则不需要任何交换排序
时间复杂度
main内
int[] arr = new int[80000];
for (int i = 0; i < 80000; i++) {
arr[i] = (int)(Math.random() * 8000000);//生成[0,8000000)的数
}
Date date1 = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date1Str = simpleDateFormat.format(date1);
System.out.println("排序前的时间是="+date1Str);
//测试冒泡排序
insertSort(arr);
Date date2 = new Date();
String date2Str = simpleDateFormat.format(date2);
System.out.println("排序后的时间是="+date2Str);
希尔排序
插入排序存在的问题-效率低下
希尔排序图解
希尔排序的两种应用方法
交换法
package Sort;
import java.util.Arrays;
public class ShellSort {
public static void main(String[] args) {
int[] arr = {8,9,1,7,2,3,5,4,6,0};
shellSort1(arr);
}
//使用交换法
public static void shellSort1(int[] arr){
int temp = 0;
int count = 0;
//第1轮
//10个数据分为了5组
for(int gap = arr.length/2;gap > 0;gap /= 2){
for (int i = gap; i < arr.length; i++) {
//遍历各组中所有的元素(共gap组) 步长为gap
for (int j = i-gap; j >= 0 ; j -= gap) {
//如果当前元素大于加上步长后的那个元素 则交换
if (arr[j] > arr[j +gap]){
temp = arr[j];
arr[j] = arr[j+gap];
arr[j+gap] = temp;
}
}
}
System.out.println("希尔排序的第"+(++count)+"轮 = "+ Arrays.toString(arr));
}
}
}
时间复杂度
代码同上
反而比插入排序更慢了
加上弹幕说的break后时间变成了不到1秒,why啊!?谢谢你陌生人(呵呵
答案:减少forj的循环判断
移位法(效率高
//使用交换法
public static void shellSort1(int[] arr){
int temp = 0;
int count = 0;
//第1轮
//10个数据分为了5组
for(int gap = arr.length/2;gap > 0;gap /= 2){
for (int i = gap; i < arr.length; i++) {
//遍历各组中所有的元素(共gap组) 步长为gap
for (int j = i-gap; j >= 0 ; j -= gap) {
//如果当前元素大于加上步长后的那个元素 则交换
if (arr[j] > arr[j +gap]){
temp = arr[j];
arr[j] = arr[j+gap];
arr[j+gap] = temp;
break;
}
}
}
// System.out.println("希尔排序的第"+(++count)+"轮 = "+ Arrays.toString(arr));
}
效率也比方法一高