zoukankan      html  css  js  c++  java
  • 冒泡,选择,插入排序算法

    排序算法

    排序也成排序算法(Sort Algorithm),排序是将一组数据,依指定的顺序进行排列的过程

    排序的分类

    内部排序:指将需要处理的所有数据都加载到内部存储器中进行排序

    外部排序法:数据量过大,无法全部加载到内存中,需要借助外部存储进行排序

    度量一个程序(算法)执行时间的两种方法

    1.事后统计的方法

    这种方法可行,但是有两个问题,一是要想对设计的算法的运行性能进行评测,需要实际运行该程序:二是所得时间的统计量依赖于计算机的硬件,软件等环境因素,这种方式,要在同一台计算机的相同状态下运行,才能比较那个算法速度更快

    2.事前估算的方法

    通过分析某个算法的时间复杂度来判断那个算法更优

    算法的时间复杂度

    时间频度:一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法中语句执行次数多,他花费时间就多,一个算法中的语句执行次数称为语句频度或时间频度 . 记为: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. 用常数1代替运行时间中的所有加法常数 T(n)=n^2+7n+6 => T(n)=n^2+7n+1
    2. 修改后的运行次数函数中,只保留最高阶项 T(n)=n^2+7n+1 => T(n)=n^2
    3. 去除最高阶项的系数 T(n)=n^2=> T(n)=n^2

    常见的时间复杂度

    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秒
    
  • 相关阅读:
    C# 虚方法virtual详解
    悟透javascript中的function
    C#并行编程-Task
    C#编程高并发的几种处理方法
    【CG】CG标准函数库——数学函数
    【Unity Shaders】学习笔记——SurfaceShader(八)生成立方图
    【Unity Shaders】学习笔记——SurfaceShader(七)法线贴图
    【Unity Shaders】学习笔记——SurfaceShader(六)混合纹理
    【Unity Shaders】学习笔记——SurfaceShader(五)让纹理动起来
    【Unity Shaders】学习笔记——SurfaceShader(四)用纹理改善漫反射
  • 原文地址:https://www.cnblogs.com/train99999/p/11123096.html
Copyright © 2011-2022 走看看