标签:for 重复 val mic 常见 列表 temp oid 选择
一个算法花费的时间与算法种语句的执行次数成正比,哪个算法种语句执行次数多,它花费时间就多。
一个算法中的语句执行次数称为语句频度或时间频度。记为T(n)
eg:计算1-100的和
方法一:for循环 T(n) = n + 1
方法二:直接计算 T(n) = 1
说明:常见的算法时间复杂度由小到大如上述,从上到下,随着n的增加,时间复杂度不断增大,算法的执行效率越低
排序也称为排序算法(Sort Algorithm),排序是将一组数据,依指定的顺序进行排列的过程。
内部排序
指将需要处理的所有数据都加载到内部存储器中进行排序
外部排序
数据量过大,无法全部加载到内存中,需要借助外部存储进行排序
排序算法 | 平均时间复杂度 | 最好情况 | 最坏情况 | 空间复杂度 | 排序方式 | 稳定性 |
---|---|---|---|---|---|---|
冒泡排序 | O(n^2) | O(n) | O(n^2) | O(1) | 不占用额外内存 | 稳定 |
选择排序 | O(n^2) | O(n^2) | O(n^2) | O(1) | 不占用额外内存 | 不稳定 |
插入排序 | O(n^2) | O(n) | O(n^2) | O(1) | 不占用额外内存 | 稳定 |
序 | O(n log n) | O(n log2 n) | O(n log2 n) | O(1) | 不占用额外内存 | 不稳定 |
排序 | O(n log n) | O(n log n) | O(n log n) | O(n) | 占用额外内存 | 稳定 |
序 | O(n log n) | O(n log n) | O(n^2) | O(log n) | 不占用额外内存 | 不稳定 |
序 | O(n log n) | O(n log n) | O(n log n) | O(1) | 不占用额外内存 | 不稳定 |
序 | O(n + k) | O(n + k) | O(n + k) | O(K) | 占用额外内存 | 稳定 |
序 | O(n + k) | O(n + k) | O(n^2) | O(n + k) | 占用额外内存 | 稳定 |
序 | O(n * k) | O(n * k) | O(n * k) | O(n + k) | 占用额外内存 | 稳定 |
冒泡排序(Bubble Sorting)的基本思想是:通过对待排序顺序从前向后(从下标较小的元素开始),依次比较相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部,就像水中的气泡一样逐渐向上冒
因为排序的过程中,各个元素不断接近自己的位置,若一趟比较下来没有进行过交换,则说明排序有序,因此要在排序中设置一个标志 flag 判断元素是否进行过交换,若没有,说明排序完毕,从而减少不必要的比较
public static void bubbleSort(int[] arr){
//冒泡排序的时间复杂度O(n^2)
int temp = 0; //临时变量
boolean flag = false; //标识变量,表示是否进行过交换
for(int i = 0; i < arr.length - 1; i++) { //共进行n-1躺排序
for(int j = 0; j < arr.length - 1 - i; j++) { //共比较 n - 1 - i 次比较
//若前面的数大于后面的数,则交换
if(arr[j] > arr[j + 1]) {
flag = true; //若交换,则 将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; //重置flag让其进行下次判断
}
}
}
public static void main(String[] args) {
int[] arr = {3, 9, -1, 10, -2};
System.out.println("排序前:");
System.out.println(Arrays.toString(arr));
bubbleSort(arr);
System.out.println("排序后:");
System.out.println(Arrays.toString(arr));
}
public static void main(String[] args) {
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);
}
排序八万个数,大约花费时间 13 秒
选择排序(select sorting)也属于内部排序,是从要排序的数据中,按指定的规则选出来某一元素,再按规定交换位置后达到排序的目的
第一次从arr[0] ~ arr[n - 1]中选取最小值,与arr[0] 交换
第二次从arr[1] ~ arr[n - 1]中选取最小值,与arr[1] 交换
第i次...
第n - 1次从arr[n - 2] ~ arr[n - 1]中选取最小值,与arr[n - 2] 交换
总共通过 n - 1 次,得到一个从小到大的有序序列
package cn.imut.sort;
import java.util.Arrays;
//选择排序
public class SelectSort {
public static void main(String[] args) {
int[] arr = {101, 34, 119, 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++) {
int minIndex = i; //最小值的索引,假定为0
int min = arr[i]; //假定第一个数就是最小值
for(int j = i + 1; j < arr.length; j++) {
if(min > arr[j]) { //说明假定的最小值并不是最小的
min = arr[j]; //重置最小值
minIndex = j; //重置最小值下标
}
}
//将最小值,放在arr[0],进行交换
if(minIndex != i) { //i与假设最小值下标是重合的,只有交换才有区别
arr[minIndex] = arr[i];
arr[i] = min;
}
}
}
}
public static void main(String[] args) {
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);
}
插入排序属于内部排序,是对要排序的元素以插入的方式寻找该元素的适当位置,以达到排序的目的
把n个待排序的元素看成一个有序表和一个无序表
开始时,有序表只含有一个元素,无序表中有n-1个元素
排序过程中每次从无序表取出第一个元素,把它的排序码依次和有序表元素的排序码进行比较
将它插入到有序表中的适当位置,使之称为新的有序表
package cn.imut.sort;
import com.sun.org.apache.xpath.internal.SourceTree;
import java.util.Arrays;
//插入排序
public class InsertSort {
public static void main(String[] args) {
int[] arr = {101, 34, 119, 1};
insertSort(arr);
}
//插入排序
public static void insertSort(int[] arr) {
for(int i = 1; i < arr.length; i++) {
int insertVal = arr[i]; //要插入的数(第二个列表的首位)
int insertIndex = i - 1; //要插入数的前一个数的下标(第一个列表的末尾的编号)
//注:第一个列表是有序的
//insertIndex > 0 保证 插入的位置不越界
//insertVal < arr[insertIndex] 说明 要插入的数还没有找到插入的位置,否则它正常加入到最后即可
//接着将 arr[insertIndex] 后移
while(insertIndex >= 0 && insertVal < arr[insertIndex]) {
arr[insertIndex + 1] = arr[insertIndex];
insertIndex--;
}
//退出while循环时,说明插入的位置找到,insertIndex + 1
arr[insertIndex + 1] = insertVal;
System.out.println("第" + i + "轮插入");
System.out.println(Arrays.toString(arr));
}
}
}
public static void main(String[] args) {
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 format = simpleDateFormat.format(date1);
System.out.println("排序前的时间是:" + format);
insertSort(arr);
Date date2 = new Date();
String format1 = simpleDateFormat.format(date2);
System.out.println("排序后的时间是:" + format1);
}
插入排序测试八万个数据,只需1秒
标签:for 重复 val mic 常见 列表 temp oid 选择
原文地址:https://www.cnblogs.com/yfyyy/p/12554321.html