数组以及排序和查找
Posted 菜鸡蔡文姬
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数组以及排序和查找相关的知识,希望对你有一定的参考价值。
一、数组的定义
三种定义方法:
int b[]=new int[5]; Int []b=new int[5]; int[] a=new int[5]; //(建议使用这种定义方法) //必须规定数组长度,因为在编译的时候就要分配内存。
我们也可以在定义的时候就初始化数组
int[] a={1,2,3,3,5};
这默认了数组a的长度是5.
分配内存详情如下:
开辟一块内存,有5个小块,a指向数组的首地址。
int[][] b=new int[5][]; //至少确定第一维的个数(即数组行数)才不会提示有错。第二维的个数可以暂时不固定。 int[][][] b=new int[5][][]; //同理三维数组长度也至少确定第一维的个数才不会提示有错。也可以确定一二维的个数,int[][][] b=new int[5][4][]; 但是无法跨维确定,例如int[][][] b=new int[5][][5];
二、数组的遍历。
①只有确定了所有维数去遍历一个数组才不会报错。
②数组下标从0开始,到n-1结束(n为该维长度)。比如int[] s=new int[3]。这个数组长度为3,s[0],s[1],s[2]就是这三个值,访问s[3]是会报错的,报数组越界异常java.lang.ArrayIndexOutOfBoundsException。
为什么是0开始呢?跟外国人建房子习惯有关,因为外国人建房子都会建地下室,地下室不就是0层了(地下一层也叫地上0层,因为在地上一层的下一层)。
③没有初始化的时候,int数组所有元素值为0,float、double所有元素值为0.0,String所有元素值为null。Char所有元素都是一个空格(而不是什么都没有)。
④ char[] c=new char[a]; //a为已知常数
遍历方式一(for循环,用int变量控制):
for(int i=0;i<a;i++){ System.out.println(c[i]); }
遍历方式二(for循环):
for(char p:c){ System.out.println(p); }
char[][] c=new char[a][b]; //a,b为已知常数
遍历方式一(for循环,用int变量控制):
for(int i=0;i<a;i++){ for(int j=0;j<b;j++){ System.out.println(c[i][j]); } }
遍历方式二(for循环):
for(char i[]: c){ for(char j:i){ System.out.println(j); } }
三、排序
1.排序法种类:
内部排序: 指将需要处理的所有数据都加载到内部存储器中进行排序。(包括交换式排序法、选择式排序法、插入式排序法)
外部排序: 数据量过大,无法全部加载到内存中,需要借助外部存储进行排序。(包括合并排序法和直接合并排序法)
交换式排序法,数据比较后,依判断规则对数据位置进行交换,以达到排序的目的。
①冒泡排序法(Bubble sort)
②快速排序法(Quick sort)
选择式排序法,是从欲排序的数据中,按指定的规则选出某一元素,经过和其他元素重整,再依原则交换位置后达到排序的目的。
①选择排序法(Select sort)
②堆排序法(Heap Sort)
插入式排序法,是对欲排序的元素以插入的方式找寻该元素的适当位置,以达到排序的目的。
①插入排序法(Insertion sort)
②希尔排序法(Shell sort)
③二叉树排序法(Binary-tree sort)
其它排序法。
①选堆排序法
②合并排序法
2.冒泡排序法
public static int[] bubble(int[] array){ int temp=0; for(int i=0;i<array.length;i++){ //外层循环,决定一共走几趟 for(int j=0;j<array.length-1-i;j++){ //内层循环,开始逐个比较,发现前一个数比后一个数大则交换 if(array[j]>array[j+1]){ temp=array[j]; array[j]=array[j+1]; array[j+1]=temp; // array[j]=array[j]+array[j+1]; // array[j+1]=array[j]-array[j+1]; // array[j]=array[j]-array[j+1]; } } } return array; }
3.选择排序法:
public static int[] select(int[] array){ int temp=0; for(int j=0;j<array.length;j++){ //我认为第一个数就是最小的 int min=array[j]; //记录最小数的下标 int minIndex=j; for(int k=j+1;k<array.length;k++){ if(min>array[k]){ //修改最小 min=array[k]; minIndex=k; } } temp=array[j]; array[j]=array[minIndex]; array[minIndex]=temp; } return array; }
4.插入排序法:
public static int[] insert(int[] array){ for(int i=1;i<array.length;i++){ int insertVal=array[i]; //insertval准备和前一个数比较 int index=i-1; while(index>=0&&insertVal<array[index]){ //把array[index]向后移动 array[index+1]=array[index]; //让index向前移动 index--; }
//将insertVal插入到适当位置
array[index+1]=insertVal;
}
return array;
}
5.快速排序法(交换式排序法):
public static int[] quick(int[] array){ int left=0; int right=array.length-1; return px(left, right, array); } public static int[] px(int left,int right,int[] array){ int l=left,r=right; int privot=array[(l+r)/2]; int temp=0; while(l<r){ while(array[l]<privot) l++; while(array[r]>privot) r--; if(l>=r) break; temp=array[l]; array[l]=array[r]; array[r]=temp; if(array[l]==privot) --r; if(array[r]==privot) ++l; } if(l==r){ l++; r--; } if(left<r) px(left,r,array); if(right>l) px(l, right, array); return array; }
5.几种排序方法运行时间的比较:
随机生成十万个1~10000的数并存放到数组中。
int[] array=new int[100000]; for(int i=0;i<array.length;i++){ array[i]=(int)(Math.random()*10000); }
用冒泡排序法排序,排序前打印系统时间,排序后打印系统时间。
Calendar calendar=Calendar.getInstance(); System.out.println("排序前:"+calendar.getTime()); bubble(array); calendar=Calendar.getInstance(); System.out.println("排序后:"+calendar.getTime());
发现排序时间大约是16秒
换成选择排序法:
Calendar calendar=Calendar.getInstance(); System.out.println("排序前:"+calendar.getTime()); select(array); calendar=Calendar.getInstance(); System.out.println("排序后:"+calendar.getTime());
大约4秒钟
换成插入排序法:
Calendar calendar=Calendar.getInstance(); System.out.println("排序前:"+calendar.getTime()); insert(array); calendar=Calendar.getInstance(); System.out.println("排序后:"+calendar.getTime());
大约3秒钟
换成快速排序法:
Calendar calendar=Calendar.getInstance(); System.out.println("排序前:"+calendar.getTime()); quick(array); calendar=Calendar.getInstance(); System.out.println("排序后:"+calendar.getTime());
几乎没有排序时间。
6.浅测快速排序法
刚刚测试十万个数发现几乎没有排序时间。
我又测试了一百万个,发现还是没什么排序时间。
直到测试了一千万个:
发现仅有1s的排序时间。
那是不是快速排序法就是最好的呢?
不是,快速排序法在运行的时候对cpu和内存的占用是非常大的,其他排序法并不像快速排序法占用这么多。
四、查找
在java中我们常用的查找有两种
①顺序查找(最简单,效率最低的查找方法,一个一个找)
②二分查找(先排序,再择中查找,效率高)
public static void find(int val,int[] array){ int leftIndex=0; int rightIndex=array.length-1; f(leftIndex, rightIndex, val, array); } public static void f(int leftIndex,int rightIndex,int val,int array[]){ int midIndex=(rightIndex+leftIndex)/2; int midVal=array[midIndex]; if(rightIndex>=leftIndex){ if(midVal>val){ f(leftIndex, midIndex-1, val, array); }else if(midVal<val){ f(midIndex+1, rightIndex, val, array); }else if(midVal==val){ System.out.println("找到此数,下标为"+midIndex); } } }
二分查找要求数组已经是排好序(从小到大)的数组,所以我们一般先排序再使用二分查找。
以上是关于数组以及排序和查找的主要内容,如果未能解决你的问题,请参考以下文章