• 每天一算法之插入排序


    我们看这样一个数组:array={12,23,9,24,15,3,18}如何按从小到大顺序用选择排序算法实现??

    我们用插入排序算法的思维先选择排序的过程:

    先从数组中依次选出一个假定最小数,然后依次和后面的数比较大小,记录下实际最小数的下标,并在一趟比较完之后,将假定最小数和实际最小数调换位子!

    我们注意到在比较过程中,我们要先选定“假定最小数”,再拿这个假定的比较数和后面没有排序的数比较,得出实际最小数!

    注意这里:第一趟:我们先选“假定最小数”, 选完后依次比较--------这里就涉及到会有几趟,每趟会比较几次的问题;

    我们将问题用实际例子画个流程图出来:

    拿数组array:我们先定义每趟的假定最小值的下标是minIndex,最小值是min

    index—> 0   1   2  3  4  5   6

      array={12,23,9,24,15,3,18}

    第一趟:minIndex=0 ,index=12

             第1次比较:<0,1>比较(指数组下标对应的值)

                             minIndex=0 ,min=12

             第2次比较:<0,2>

                             minIndex=0 ,min=12

             第3次比较:<0,3>

                             minIndex=0 ,min=12

             第4次比较:<0,4>

                             minIndex=0 ,min=12

             第5次比较:<0,5>

                             minIndex=5 ,min=3

             第6次比较:<5,6>

                             minIndex=5 ,min=3                                                 index——>0  1  2  3   4  5    6

    第一趟比较的结果:假定最小值的下标是0 ,实际最小值的下标是5,两者交换值:     array={3,23,9,24,15,12,18}

    第二趟:minIndex=1 ,index=23

             第1次比较:<1,2>比较(指数组下标对应的值)

                             minIndex=2 ,min=9

             第2次比较:<2,3>

                             minIndex=2 ,min=9

             第3次比较:<2,4>

                             minIndex=2 ,min=9

             第4次比较:<2,5>

                             minIndex=2 ,min=9

             第5次比较:<2,6>

                             minIndex=2 ,min=9

    第二趟比较的结果:假定最小值的下标是1 ,实际最小值的下标是2,两者交换值:     array={3,9,23,24,15,12,18}

    就这样一直比较直到结果出现:[3, 9, 12, 15, 18, 23, 24]

    我们可以看出:

    1.比较的趟数时array.length-1

    2.每次取无须数组的第一个数作为假定的最小值,它的比较次数是剩余数组形成的无序数组的length-1

    3.那么比较趟数i和内部比较次数j的关系:  j=len-i(假设i从1开始)

    根据这个可以得到程序:(注意:后来证明字体大的部分逻辑是错误的,因为对于子无序数组而言,假定最小值就是是实际最小值时,后面的数组排序不一定是排序好的)为什么在代码中红色显示不了呢??

    /**选择排序思想:每次从无序序列中选择第一个数为假定最小值,依次后后面的数比较,存在更小的数,与其交换位置
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
            int array[]={12,23,9,24,15,3,18};
    		
    		int len=array.length;
    		//外层控制趟数 7-1=6趟
    		for(int i=1;i<=len-1;i++)   
    		{
    			int minIndex=i-1;
    			int min=array[minIndex];
    			boolean flag=false;          //在i趟时,是否存在比假定最小数更小的数存在
    			boolean boolNoSmall=false;   //标记值:判断假定最小数是否是在这一趟中的实际最小数,如果是,那么后面的循环就不用了
    			//内层控制比较次数  剩下几个数就比较len-1次
    			for(int j=len-i;j>=1;j--)
    			{
    				boolNoSmall=false;
    				if(array[len-j]<min)
    				{
    					minIndex=len-j;
    					min=array[minIndex];
    					flag=true;           //假定最小数不是实际最小数,标志值
    				}
    				if(minIndex==(i-1))      //假定最小值就是实际最小值,数组已经排序好
    					boolNoSmall=true;
    				
    			}
    			if(boolNoSmall)               //假定最小值就是实际最小值,数组已经排序好
    				break;
    			if(flag)                      //假定错误,交换两个数
    			{
    				int temp=array[i-1];
    				array[i-1]=min;
    				array[minIndex]=temp;
    			}
    			
    		}
    		System.out.println(Arrays.toString(array));
    
    	}
    

     注意程序上方红色部分是对程序的优化:

    上方的程序是从i=1开始计数,也就是程序的趟数(第1趟。。。。。)开始。平时我们还是应该从数组的对应下标开始计数更加符合实际情况,但是我们为了便于理解,这样写也ok啦

    正确的算法

    public static void  sort()
    	{
    		int array[]={1,12,23,9,24,15,3,18};
    		int len=array.length;
    		int minIndex,min;     //定义每次的假定最小值和最小坐标
    		//外层循环控制趟数:0———len-1即(0——5)
    		for(int i=0;i<len-1;i++)
    		{
    			minIndex=i;
    			min=array[minIndex]; //初始化每次的假定最小值和最小坐标
    			boolean flag=false; //假定最小值是否存在比其更小的数
    		
    			//开始第i+1趟
    			
    		    //内部循环控制每趟比较的次数
    			//每次都得比较 len-i-1,每次比较至少比较1次(j>=1)
    			for(int j=len-i-1;j>=1;j--)
    			{
    				if(array[len-j]<array[minIndex])  //存在比其更小的数
    				{
    					minIndex=len-j;
    					flag=true;
    				}
    				
    			}
    			if(flag)  //交换数据
    			{
    				int temp=array[minIndex];
    				array[minIndex]=array[i];
    				array[i]=temp;
    			}
    		}
    		System.out.println(Arrays.toString(array));
    
    	}
    

     给个更快的算法

    public static void sort2()
    	{
    		int array[]={1,12,23,9,24,15,3,18};
    		int min;
    		int len=array.length;
    		for(int i=0;i<len-1;i++)  //从0开始
    		{
    			min=array[i];
    			for(int j=i+1;j<len;j++)  //从i+1开始和i比较,
    			{
    				if(array[j]<array[i])
    				{
    					min=array[j];
    				}
    				if(!(min==array[i]))  //直接交换
    				{
    					int temp=array[i];
    					array[i]=array[j];
    					array[j]=temp;
    					
    				}
    				
    			}
    		}
    		System.out.println(Arrays.toString(array));
    		
    	}
    

                

  • 相关阅读:
    工资是用来支付给责任的,责任越大,工资越高。 涨工资,是因为承担了更大的责任。
    水平分库分表的关键问题及解决思路
    APP多版本共存,服务端如何兼容?
    ListView动态加载数据分页(使用Handler+线程和AsyncTask两种方法)
    Java 并发专题 :闭锁 CountDownLatch 之一家人一起吃个饭
    Java进阶 创建和销毁对象
    Java OCR tesseract 图像智能字符识别技术
    网页信息抓取进阶 支持Js生成数据 Jsoup的不足之处
    从原理角度解析Android (Java) http 文件上传
    android pop3与imap方式接收邮件(javamail)
  • 原文地址:https://www.cnblogs.com/fjsnail/p/3477691.html
Copyright © 2020-2023  润新知