1、输入操作
import java.util.Scanner;
Scanner scanner =new Scanner(System.in);
int m=scanner.nextInt(); //注意大小写
2、一维数组
a、动态初始化:初始化时只指定数组长度,由系统为数组分配初始值
数据类型[] 数组名=new 数据类型[数组长度] 数组长度其实就是数组中元素的个数
b、静态初始化:初始化时指定每个数组元素的数十只,由系统决定数组长度
数据类型[] 数组名=new 数据类型[]{元素1,元素2,元素3,...};
int[] arr1=new int[5];//指定长度为5的数组
int[] arr2=new int[]{1,2,3,4}; //直接定义好数组并且赋值
int[] arr3={1,2,3,4}; //最简单的赋值定义数组
注意:为了简化,通常说arr是一个数组,实际上arr是一个含有int型元素数组的引用变量
int[] arr1=new int[]{1,2,3,4};
arr1[2]=10;
int[] arr2=arr1;
arr2[2]=20;
System.out.println(arr1[2]);
//结果输出arr1[2]=10
上面代码中实际上只存在一个数组,只不过存在两个引用变量arr1和arr2,修改arr2并不会影响arr1
2.1数组的异常
ArrayIndexOutofBoundsException 数组角标越界异常
NullPointerException 空指针异常
2.2数组输入赋值
System.out.print("请输入第一个数组");
int[] list1=new int[scanner.nextInt()]; //将键盘输入的第一个元素作为数组长度
for(int i=0;i<list1.length;i++) {
list1[i]=scanner.nextInt();
}
2.2数组的默认值
数值型基本数据类型为0
char类型的默认值为‘\u0000’
boolean型的默认值为false
3、二维数组
格式1:数据类型[][] 变量名=new 数据类型[m][n]
格式2:数据类型[][] 变量名=new 数据类型[m][];
格式3:数据类型[][] 变量名=new 数据类型[][]{{...},{...},{...},...} 数据类型[][] 变量名={{...},{...},{...}...}
int[][] arr1=new int[2][3]; //创建一个2行3列的数组
int[][] arr2=new int[][]{{1,2},{3,4},{5,6}}; //创建3行2列的数组
int[][] arr3={{1,2},{3,4},{5,6}};
4、字符串数组
String[] arr1=new String[5]; //定义一个字符串数组,数组元素有5个
String path=""; //初始化一个字符串
path+="L"; //改变字符串
paths[i]=path; //利用循环控制语句将字符串存入到字符串数组中
“字符串数组名.charAt(i)”将角标i的元素提取出来,和普通数组有区别
for(int j=0;j<path.length();j++) { //遍历字符串中的单个元素
if(path.charAt(j)=='R') { //注意
count++; //统计R的个数
}
}
每一个if或else必须对应一个return
4.1二维数组的输入赋值
采用嵌套循环进行操作
int[][] m1= new int[3][3]; //创建数组m1
for(int i=0;i<m1.length;i++) {
for(int j=0;j<m1[0].length;j++) {
m1[i][j]=scanner.nextInt();
}
}
5、数组的打印输出
import java.util.Arrays;
Arrays.toString();工具类,将一个数组以字符串的形式输出,需要导包
7、复制数组
复制数组有三种方法:
1 )使用循环语句逐个地复制数组的元素。
2 ) 使用 System类中的静态方法 arraycopy。
3 )使用 clone 方法复制数组
1、用 for 循环将 sourceArray 复制到 targetArray
int[] sourceArray ={2, 3, 1, 5, 10};
int[] targetArray = new int[sourceArray.length];
for (int 1 = 0; i < sourceArray.1enath; i++) {
targetArray[i] = sourceArray[i];
}
2、另一种方式是使用java.lang.System 类的 arraycopy 方法复制数组,而不是使用循环
arraycopy(sourceArray, srcPos, targetArray, tarPos,length);
参数 srcPos 和 tarPos 分别表示在源数组 sourceArray 和目标数组 targetArray 中的 起始位置。从 sourceArray 复制到 targetArray 中的元素个数由参数 length 指定。
System.arraycopy(sourceArray, 0, targetArray, 0,sourceArray.length);
arraycopy 方法没有给目标数组分配内存空间。复制前必须创建目标数组以及分配给它 的内存空间。复制完成后,sourceArray 和 targetArray 具有相同的内容,但占有独立的内 存空间。
注意:arraycopy 方法违反了 Java 命名习惯。根据命名习慣,该方法应该命名为 arrayCopy (即字母C 大写)。
8、 Arrays类
可以使用sort或者 parallelSort方法对整个数组或部分数组进行排序
例如,下面的 代码对数值型数组和字符型数组进行排序。
可以采用 equals 方法检测两个数组是否相等
可以使用 fill 方法填充整个数组或部分数组。例如:下列代码将 5 填充到 listl 中, 将 8 填充到元素 list2[l] 到 list2[5-l] 中。
还可以使用 toString 方法来返回一个字符串,该字符串代表了数组中的所有元素。这 是一个显示数组中所有元素的快捷和简便的方法。例如,下面代码
int[] list = {2, 4, 7, 10};
System.out.println(Arrays.toString(list));
显示 [ 2, 4 , 7, 10]。
9、 数组的查找
常用的俩个查找方法时线性查找和二分查找,如果是数组已经排好序,则使用二分查找可以大大降低查找的时间复杂度
线性查找:
让关键字与数组中的元素挨个比较,如果找到返回所在位置的下标,如果没有找到返回-1
如;
public class LinearSearch {
public static void main(String args[]) {
int[] list= {1,4,4,2,5,-1,6,2};
int key=linearSearch(list, 2);
System.out.println(key);
}
public static int linearSearch(int[] list,int key) {
for(int i=0;i<list.length;i++) {
if(key==list[i])
return i;
}
return -1;
}
}
二分查找
假设数组已按升序排列。二分査找法首先将关键字与数组的中间 元素进行比较。考虑下面三种情况: • 如果关键字小于中间元素,只需要在数组的前一半元素中继续査找关键字。
• 如果关键字和中间元素相等,则匹配成功,査找结束。
• 如果关键字大于中间元素,只需要在数组的后一半元素中继续査找关键字。
如:
public class BinarySearch {
public static void main(String args[]) {
int[] list= {1,4,4,2,5,-1,6,2};
int key=binarySearch(list, 2);
System.out.println(key);
}
public static int binarySearch( int[] list, int key) {
int low=0;
int high=list.length-1;
while(low<=high) {
int mid=(low+high)/2;
if(key<list[mid])
high=mid-1;
else if(key==list[mid])
return mid;
else
low=low+1;
}
return -1;
}
}
10、 数组的排序
import java.util.Arrays;//数组工具类
public class sortDemo{
public static void main(String[] args){
//选择排序
selectSort();
//冒泡排序
bubbleSort();
//插入排序
insertSort();
}
public static void insertSort(){
int[] arr=new int[800];
for(int i=0;i<arr.length;i++){
arr[i]=(int)(Math.random()*5);
}
long start=System.currentTimeMillis();
for(int i=1;i<arr.length;i++){
int e=arr[i];
int j;
for(j=i;j>0&&arr[j-1]>e;j--){
arr[j]=arr[j-1];
}
arr[j]=e;
}
long end=System.currentTimeMillis();
System.out.println("插入排序time="+(end-start));
System.out.println(Arrays.toString(arr));
}
public static void bubbleSort(){
int[] arr=new int[800];
for(int i=0;i<arr.length;i++){
arr[i]=(int)(Math.random()*5);
}
long start=System.currentTimeMillis();
for(int i=0;i<arr.length-1;i++){
for(int j=0;j<arr.length-1-i;j++){
if(arr[j]>arr[j+1]){
int temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
long end=System.currentTimeMillis();
System.out.println("冒泡排序time="+(end-start));
System.out.println(Arrays.toString(arr));
}
public static void selectSort(){
int[] arr=new int[800];
for(int i=0;i<arr.length;i++){
arr[i]=(int)(Math.random()*5);
}
long start=System.currentTimeMillis();
for(int i=0;i<arr.length-1;i++){//-1 最后一个数字没必要参与比较
for(int j=i+1;j<arr.length;j++){
if(arr[i]>arr[j]){
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
}
long end=System.currentTimeMillis();
System.out.println("选择排序time="+(end-start));
System.out.println(Arrays.toString(arr));
}
}
选择排序
首先,从表头开始往后扫描线性表,依次比较相邻两个元素,若前面的元素大于后面的元素,将它们交换。
然后,从下一个元素开始往后扫描后面的线性表,依次比较相邻两个元素,若后面的元素大于前面的元素,将他们交换。
对剩下的线性表重复上述过程,直到剩余表为空。此时的线性表为有序。
冒泡排序
相邻俩个元素比较,第一个元素和第二个元素相比较并交换,第二个元素和第三个元素相比较并交换,以此类推
非比较类:计数排序
主要思想:角标=数字,角标对应的元素是数字的个数
public class CountSort {
public static void main(String[] args) {
int[] old= {1,2,5,3,4,5,6,9,-2,-3,6};
//1.找最小值和最大值
int min=old[0];
int max=old[0];
for(int i=1;i<old.length;i++) {
if(old[i]<min) {
min=old[i];
}
if(old[i]>max) {
max=old[i];
}
}
//2.确定一个合适的区间长度(创建数组)max-min+1
int[] arr=new int[max-min+1];
//3.寻找偏移量(0-最小值)
int offset=0-min;
//4.将之前数组中的元素存储在新的数组中,数字+offset=角标,角标对应元素是数字个数
for(int i=0;i<old.length;i++) {
arr[old[i]+offset]++;
}
//5.打印新数组中的元素
for(int i=0;i<arr.length;i++) {
while(arr[i]!=0) {
System.out.print(i-offset+" ");//数字=角标-offset
arr[i]--;
}
}
}
}