• 数组(排序,二分,进制转换)


    选择排序

    package day07;
    
    public class try_1 {
        public static void main(String[] args) {
              int array[] = new int[]{12,14,2365,57,79,35};
              int x;
              int y;
              int i;
              int temp;
              for(x=0;x<array.length-1;x++)
              {
                  for(y=x+1;y<array.length;y++)
                  {
                      if(array[y]<array[x])
                      {
                          temp=array[y];
                          array[y]=array[x];
                          array[x]=temp;
                          
                      }
                      
                  }
                  
              }
              for(i=0;i<array.length;i++)
              {
                  System.err.print(array[i]+" ");
                  
              }
        }
    
    }
    12 14 35 57 79 2365 

       从选择排序的思想或者是上面的代码中,我们都不难看出,寻找最小的元素需要一个循环的过程,而排序又是需要一个循环的过程。因此显而易见,这个算法的时间复杂度也是O(n*n)的。这就意味值在n比较小的情况下,算法可以保证一定的速度,当n足够大时,算法的效率会降低。并且随着n的增大,算法的时间增长很快。因此使用时需要特别注意。

    选择最大或者最小的那个,与前面按顺序排好的后面一位交换位置。时间复杂度为o(n2),空间复杂度为o(1),是不稳定排序

    冒泡排序

     for(x=0;x<array.length-1;x++)
              {
                  for(y=0;y<array.length-1-x;y++)
                  {
                      if(array[y]>array[y+1])
                      {temp=array[y];
                      array[y]=array[y+1];
                      array[y+1]=temp;
                  }}
              }

    大的往后沉,逐轮比较元素递减。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越大的元素会经由交换慢慢“浮”到数列的顶端。是稳定排序,最好的情况时间复杂度为o(n)最坏的情况时间复杂度为o(n2).

    用Arrays.sort()函数进行排序也是非常快的,一般在开发的时候就不用再自己写排序函数,用java给封装好的函数就可以

     二分查找

    二分查找作为O(log(n))时间复杂度的查找算法得到了广泛的使用。

    1.在已排序的数组中查找特定的元素。或者是满足条件的第一个元素 
    2.数学常用的求解方程的解,也是数学家所指的对半查找。 
    3.程序调试中用来定位错误语句 
    4….

     

    package day07;
    
    import java.util.Arrays;
    
    public class try_3 {
    
        public static void main(String[] args) {
              int array[] = new int[]{12,14,2365,57,79,35};
              Arrays.sort(array);
              int key=79;
              int min=0;
              int max=array.length-1;
                     
              while(min<=max)
              {  int mid=(min+max)>>1;   
                 if(key>array[mid])
                    min=mid+1;
                 else if(key<array[mid])
                    max=mid-1;
                else
                     
                {
                    System.out.println("bingo~~~ "+array[mid]);
                    break;
                      
                }
              }
             
        }
    
    }
     int mid=(min+max)/2; 一定写在循环的里面,不然mid位置不变就会出现死循环。
     min=mid+1  max = mid-1千万不要写成 min=mid   max=mid

    在最后找到结果的时候一定要注意
    return 或者break不然会死循环
     记得是while(min<=max)而不是while(min<max)

    二分算法是我们经常会用到的一个算法。它是分治法的一个应用。不过,虽然他写起来貌似很简单,但是却很容易写错。

    关于溢出问题:师哥,这个问题,举个特例:比如short类型的mid  假如min=65534,max=65535,那么用mid = (min+max)>>1一加肯定就超了,但是用mid = min+(max-min)>>1就不会超.但是要注意的是在java当中是不能连加的,也就是说不能做连续运算。所以如果想使用
    mid = min+(max-min)>>1,那么可以定义一个中间变量,int ca = (max-min)>>1; int mid = ca+min;一般不会溢出,所以用(min+max)>>1足矣。


    数组逆转
    将一个数组逆转,你会怎么想?用链表?线性表?如果简单点想的话:如果是一个有序的数组,那么直接头尾交换,然后指向头和尾的指针分别向中间移动,如果不是一个有序的数组那么先排序,然后指向头和尾的指针分别向中间移动。



    package day07;
    
    public class try_9 {
    
    
            public static void main(String[] args) {
                int[] arr = {1,3,4,7,8,9,20,33,33,48};
                change(arr);
                 for(int i=0;i<arr.length;i++)
                     System.out.print(arr[i]+" ");
                 System.out.println();
                
                  
             
            }
                public static void change(int[]a)
                {
                    int head = 0;
                    int end = a.length-1;
                    while((a[head]<a[end])&&(head<end))
                    {
                        int temp = a[head];
                        a[head]= a[end];
                        a[end]= temp;
                        head+=1;
                        end-=1;
                        
                        
                    }
                    
                    
                }
            
        
    
        }
    48 33 33 20 9 8 7 4 3 1 
    
    

     也就是说:

       1、反转其实就是头尾角标的元素进行位置的置换

       2、然后让头角标自增,尾角标自减,再继续位置转换

       3、依次类推,直到头角标和尾角标相等或者头角标大于尾角标的时候结束

     

     查表法

    关于十进制转十六进制的示例:

    package day4;
    
    import java.lang.reflect.Array;
    import java.util.Arrays;
    import java.util.Scanner;
    
    public class Main {
        public static void main(String[] args) {
            
        toHex(26);  
            
        }
        public static void toHex(int num)
        {
            char[]ch = new char[8];
            int pos = ch.length;
            while(num!=0)
            {
                pos--;
                int temp = num&15;//因为四个二进制位是一个十六进制位,15是二进制的0000000000001111
                if(temp>9)
                {
                    ch[pos]=(char)(temp-10+'A');
                    
                }
                else
                    ch[pos]=(char)(temp+'0');//将字符转化成数字之后再转成字符
                num=num>>>4;//无符号右移,补0
                
            }
            System.out.println(pos);
            for(int x = pos;x<ch.length;x++)
             System.out.print(ch[x]);
            System.out.println();
            
            
        }
    }

    6
    1A

     

    关于查表法

    由上面的进制转换程序我们可以发现,十六进制中一共有十六个元素,而且没通过&15获取的数字都在15之内,都有对应的十六进制元素。而且元素对应的数字正好有规律的,而且符合了数组这种容器的特点——角标,那么可以讲十六进制的元素都存储到数组当中,将每次&15的结果作为角标去查询这个数组,就可以取到十六进制对应的元素。

    那么什么时候使用查表法,当元素很多,而且这些元素与数字有对应的关系,而且这些数字都有角标的规律,这时优先考虑查表法。

    package day07;
    
    public class try_10 {
        public static void main(String[] args) {
            transer(26,15,4);
            System.out.println();
            transer(26,1,1);
            System.out.println();
            transer(26,7,3);
            
        }
        public static void transer(int num,int offset,int move)
        {   
            char[]array = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'} ;
            char[]ch = new char[32];
            int pos = ch.length;
            while(num!=0)
            {
                pos--;
                int temp = num&offset;
                ch[pos] =array[temp];
                num=num>>>move;
                
            }
            System.out.println(pos);
            for(int x = pos;x<ch.length;x++)
               System.out.print(ch[x]);
             System.out.println();
                
            
            
        }
    
    }

    30
    1A

    
    

    27
    11010

    
    

    30
    32

     

    实现了由十进制转换成其他进制的转换过程。

     transer(26,15,4);将十进制的26转换成十六进制, 参数分别是转换数字,&,换算位数。四个二进制位是一个十六进制位,00001111是十进制中的15
     transer(26,1,1); 将十进制的26转换成二进制     00000001是十进制中的1
     transer(26,7,3); 将十进制的26转换成八进制     三个二进制位是一个八进制位,00000111是十进制中的7









     

  • 相关阅读:
    装饰 Markdown
    小技巧
    LINUX 下挂载 exfat 格式 u 盘或移动硬盘
    Matlab 也很强大!
    imageio 载入 Buffer 格式的图片
    Docker 入门
    COCO 数据集使用说明书
    Python 基础 json 与pickle
    Python 基础 常用模块
    Python 基础 装饰器
  • 原文地址:https://www.cnblogs.com/mmlovejj/p/5022359.html
Copyright © 2020-2023  润新知