排序也成排序算法(Sort Algorithm),排序是将一组数据,依指定的顺序进行排列的过程java
排序的分类算法
内部排序:指将须要处理的全部数据都加载到内部存储器中进行排序数组
外部排序法:数据量过大,没法所有加载到内存中,须要借助外部存储进行排序dom
度量一个程序(算法)执行时间的两种方法函数
1.过后统计的方法性能
这种方法可行,可是有两个问题,一是要想对设计的算法的运行性能进行评测,须要实际运行该程序:二是所得时间的统计量依赖于计算机的硬件,软件等环境因素,这种方式,要在同一台计算机的相同状态下运行,才能比较那个算法速度更快测试
2.事前估算的方法设计
经过分析某个算法的时间复杂度来判断那个算法更优code
算法的时间复杂度orm
时间频度:一个算法花费的时间与算法中语句的执行次数成正比例,哪一个算法中语句执行次数多,他花费时间就多,一个算法中的语句执行次数称为语句频度或时间频度 . 记为:T(n)
统计时间频度时:随着n的变大,常数项,低次项,系数能够忽略
时间复杂度
1.通常状况下,算法中的操做语句的重复执行次数是问题规模n的某个函数,用T(n)表示,如有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数。记做T(n)=O(f(n)),称O(f(n))为算法的渐进时间复杂度,简称时间复杂度
2.T(n)不一样,但时间复杂度可能相同
3计算时间复杂度的方法
常见的时间复杂度
1.常数阶O(1) :不管代码执行多少行,只要是没有循环等复杂结构,那么这个代码的时间复杂度就都是O(1)
2.对数阶O(log2n) :
//说明:在while循环里面,每次都将i乘以2,乘完以后,i距离n就愈来愈近了,假设循环x次以后,退出循环,也就是说2的x次方等于n,那么x=log2n也就是说当循环log2n次之后,这个代码就结束了。所以这个代码的时间复杂度为:O(log2n) //若是a的x次方等于N(a>0,且a不等于1),那么数x叫作以a为底N的对数(logarithm),记做x=logaN。其中,a叫作对数的底数,N叫作真数 //这段代码执行log2^1024次 public static void main(String[] args) { int count=0; int i=1; int n=1024; while(i<n) { i=i*2; count++; } //log2^1024=10 System.out.println(count);//10 }
3.线性阶O(n) :for循环代码执行n遍,所以他消耗的时间是随着n的变化而变化的
4线性对数阶O(nlog2n) :线性对数阶O(nlogN)其实很是容易理解,将时间复杂度为O(logn)的代码循环N遍的话,那么时间复杂度就是n*O(logN)
5.平方阶O(n^2) :若是把O(n)的代码在嵌套一遍,他的时间复杂度就是O(n^2),
//这段代码其实就是嵌套了2层n循环,他的时间复杂度就是O(n*n) for(x=1;i<=n;x++) { for(x=1;i<=n;x++) { j=i; j++; } }
6.立方阶O(n^3) :至关于三层for循环
7.k次方阶(n^K)
8.指数阶O(2^n)
空间复杂度
相似于时间复杂度的讨论,一个算法的空间复杂度定义为该算法锁耗费的存储空间,他也是问题规模n的函数
冒泡排序
每一次进行排序都会肯定出一个最大值
package sort; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; public class BubbleSort { public static void main(String[] args) { //int arr[] = {3,9,-1,10,-2}; //时间复杂度O(n^2) //测试冒泡排序的速度,要求排序80000个数字 int[] arr = new int[80000]; for(int i=0;i<arr.length;i++) { //每循环一次就添加一个元素 arr[i]=(int)(Math.random()*80000); } Date data1 = new Date(); System.out.println(data1); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String dateStr = sdf.format(data1); System.out.println("开始时间"+dateStr); System.out.println("排序进行中........"); //对数组进行排序 bubbleSort(arr); Date data2 = new Date(); String dateStr2 = sdf.format(data2); System.out.println("开始时间"+dateStr2); System.out.println("排序结束"); } public static void bubbleSort(int[] arr) { int temp = 0;//临时变量 boolean b = false; for(int i=0;i<arr.length-1;i++) {//一共须要进行arr.length-1次排序 for(int j=0; j<arr.length-1-i;j++) { if(arr[j]>arr[j+1]) { b=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(!b) { break; }else { b=false;//重置为false,是由于已经有进行过排序 } } } } //冒泡排序平均15秒
选择排序
每次排序都肯定出一个最小值
package sort; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; public class SelectSort { public static void main(String[] args) { int[] arr = new int[80000]; for(int i=0;i<arr.length;i++) { //每循环一次就添加一个元素 arr[i]=(int)(Math.random()*80000); } Date data1 = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String dateStr = sdf.format(data1); System.out.println("开始时间"+dateStr); System.out.println("排序进行中........"); selectSort(arr); Date data2 = new Date(); String dateStr2 = sdf.format(data2); System.out.println("开始时间"+dateStr2); System.out.println("排序结束"); //System.out.println(Arrays.toString(arr)); } //选择排序arr[0]=min public static void selectSort(int[] arr) { for(int i=0;i<arr.length-1;i++) { int minIndex = i;//假定最小索引为0 int min = arr[i];//假定最小值是arr数组的0索引 for(int j = 1+i;j<arr.length;j++) { if(min > arr[j]) { min=arr[j];//重置最小值 minIndex=j;//重置最小值得索引 } } if(minIndex !=i) {//表示minIndex没有放生交换 arr[minIndex] = arr[i+0];//101赋值给索引3 arr[0+i] = min;//1赋值给索引0 } } } } //选择排序平均3秒
插入排序
插入式排序属于内部排序法,是对于欲排序的元素以插入的方式找寻该元素的适当位置,已达到排序的目的
插入排序的思想:就是把一个数组当作两张表,一张表存放有序元素,一张表存放无序元素,有序表初始元素为arr[0],经过与arr[0]的比较来决定插入的位置,以此类推。
package sort; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; public class InsertSort { public static void main(String[] args) { int[] arr = new int[80000]; for(int i=0;i<arr.length;i++) { //每循环一次就添加一个元素 arr[i]=(int)(Math.random()*80000); } Date data1 = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String dateStr = sdf.format(data1); System.out.println("开始时间"+dateStr); System.out.println("排序进行中........"); insertSort(arr); Date data2 = new Date(); String dateStr2 = sdf.format(data2); System.out.println("开始时间"+dateStr2); System.out.println("排序结束"); //int arr[] = {3,9,-1,10,-2}; } public static void insertSort(int[] arr) { for(int i = 1;i < arr.length; i++) { int insertVal = arr[i]; int insertIndex = i-1;//i-1的意思是要把插入的数与前一个数比较 //insertIndex >=0 防止越界 //insertVal < arr[insertIndex]) while(insertIndex >=0 && insertVal < arr[insertIndex]) { arr[insertIndex+1] = arr[insertIndex];//日后移 insertIndex--;//继续与前面的数比较 } if(insertIndex+1!=i) { arr[insertIndex+1] = insertVal; } } } } //平均时间5秒