数组
为什么要有数组?
案例:一个养鸡场有六只鸡,他们的体重分别为3kg,5kg,1kg,3.4kg,2kg,50kg。请问这六只鸡的总体重和平均体重是多少?
1 public class test5 2 { 3 public static void main(String[] args) 4 { 5 //如果没有数组就要定义六个变量,然后算出结果,太麻烦了 6 //现在我们定义一个可以存放6个float类型的数组 7 float arr[] = new float[6]; 8 //给数组的各个元素赋值 9 arr[0] = 3; //3是低精度会自动转成高精度的float类型 10 arr[1] = 5; 11 arr[2] = 1; 12 arr[3] = 3.4f; //java中默认小数是double的所以在后面加上f说明是float类型,避 13 arr[4] = 2; 14 arr[5] = 50; 15 16 float all = 0; 17 for(int i=0;i<6;i++) //遍历数组 18 { 19 all += arr[i]; 20 } 21 System.out.println("总体中是" + all); 22 } 23 }
数组可以存放多个同一类型的数据
数组的语法
//数组的定义1 —— 正常方法 数据类型 数组名[ ] = new 数据类型[ 大小 ]; int a[ ] = new int[ 10 ]; //数组的定义2 —— 没事找事法 //第一步:先声明数组 数据类型 数组名[ ]; 或者 数据类型[ ] 数组名; int a[ ]; 或 int[ ] a; //第二步创建数组 数组名 = new 数据类型[ 大小 ]; a = new int[ 10 ]; //数组的定义3 —— 古板用法 //在定义的时候直接初始化数组,大小有后面给的数的个数决定的 数据类型 数组名[] = { 元素值, 元素值, ... } int a[] = { 2,5,6,7,8,9 } //数组的引用 数组名[ 下标 ]
public class test5 { public static void main(String[] args) { float arr[] = {1.2f,2,3,4,5,7.8f}; float all = 0; for(int i=1;i<arr.length;i++) //可以用length来获取数组的长度 { all += arr[i]; } System.out.println("平均时间: "+(all/arr.length)); } }
数组越界的报错
java.lang.ArrayIndexOutOfBoundsException
如何知道数组的大小
System.out.println(arr.length); //这个length是这个数组的成员属性
对象数组
案例:一个养狗场有4只狗,分别是:
名字 | 体重 |
花花 | 4.5kg |
白白 | 5.6kg |
黑黑 | 7.8kg |
红红 | 9.0kg |
请编写一个程序,计算他们的平均体重,可以找出体重最大和最小的狗的名字,可以通过输入狗的名字,查找他们的体重
public class test6 { public static void main(String[] args) { //定义一个可以存放四只狗的对象数组 Dog dogs[] = new Dog[4]; //给每只狗赋值 dogs[0].setName("花花"); dogs[0].setWeight(4.5f); } } class Dog { private String name; public float weight; public float getWeight() { return weight; } public void setWeight(float weight) { this.weight = weight; } public String getName() { return name; } public void setName(String name) { this.name = name; } } 报错:空指针异常 java.lang.NullPointerException
Java中没有指针,但引用的实质就是一个指针,引用里面存放的并不是对象而是该对象的地址,使得该引用指向了对象那个。而“=”在JAVA中并不该被翻译成赋值语句,因为他执行的是传递至的过程。
1 public class test6 2 { 3 public static void main(String[] args) 4 { 5 //定义一个可以存放四只狗的对象数组 6 Dog dogs[] = new Dog[4]; //仅仅创建了四个引用 7 8 //给每只狗赋值 9 dogs[0] = new Dog(); //创建Dog()对象,然后传递给dogs[0]引用 10 dogs[0].setName("花花"); 11 dogs[0].setWeight(4.5f); 12 } 13 14 } 15 class Dog 16 { 17 private String name; 18 public float weight; 19 public float getWeight() { 20 return weight; 21 } 22 public void setWeight(float weight) { 23 this.weight = weight; 24 } 25 public String getName() { 26 return name; 27 } 28 public void setName(String name) { 29 this.name = name; 30 } 31 }
1 import java.io.*; 2 3 public class test6 4 { 5 public static void main(String[] args) throws Exception 6 { 7 //定义一个可以存放四只狗的对象数组 8 Dog dogs[] = new Dog[4]; //仅仅创建了四个引用 9 //从控制台输入各个狗的信息 10 InputStreamReader isr=new InputStreamReader(System.in); 11 BufferedReader br= new BufferedReader(isr); 12 for(int i=0 ; i<4 ; i++) 13 { 14 dogs[i] = new Dog(); 15 System.out.println("请输入狗的名子"); 16 //从控制台读取狗名 17 String name = br.readLine(); //之后会讲异常 18 //讲名字赋值给对象 19 dogs[i].setName(name); 20 System.out.println("请输入狗的体重"); 21 String s_weight = br.readLine(); 22 float weight = Float.parseFloat(s_weight);//String->float 23 //讲名字赋值给对象 24 dogs[i].setWeight(weight); 25 } 26 //计算总体重 27 float allWeight = 0; 28 for(int i=0;i<4;i++) 29 { 30 allWeight+=dogs[i].getWeight(); 31 } 32 //计算平均体重 33 float avgWeight = allWeight/dogs.length; 34 System.out.println("总体重="+allWeight+"平均体重"+avgWeight); 35 } 36 37 } 38 class Dog 39 { 40 private String name; 41 public float weight; 42 public float getWeight() { 43 return weight; 44 } 45 public void setWeight(float weight) { 46 this.weight = weight; 47 } 48 public String getName() { 49 return name; 50 } 51 public void setName(String name) { 52 this.name = name; 53 } 54 }
找出体重最大的狗,且输入狗的名字,返回体重
1 import java.io.*; 2 3 public class test6 4 { 5 public static void main(String[] args) throws Exception 6 { 7 //定义一个可以存放四只狗的对象数组 8 Dog dogs[] = new Dog[4]; //仅仅创建了四个引用 9 //从控制台输入各个狗的信息 10 InputStreamReader isr=new InputStreamReader(System.in); 11 BufferedReader br= new BufferedReader(isr); 12 for(int i=0 ; i<4 ; i++) 13 { 14 dogs[i] = new Dog(); 15 System.out.println("请输入狗的名子"); 16 //从控制台读取狗名 17 String name = br.readLine(); //之后会讲异常 18 //讲名字赋值给对象 19 dogs[i].setName(name); 20 System.out.println("请输入狗的体重"); 21 String s_weight = br.readLine(); 22 float weight = Float.parseFloat(s_weight);//String->float 23 //讲名字赋值给对象 24 dogs[i].setWeight(weight); 25 } 26 //计算总体重 27 float allWeight = 0; 28 for(int i=0;i<4;i++) 29 { 30 allWeight+=dogs[i].getWeight(); 31 } 32 //计算平均体重 33 float avgWeight = allWeight/dogs.length; 34 System.out.println("总体重="+allWeight+"平均体重"+avgWeight); 35 36 //找出最大体重的狗 37 //假设第一只狗体重最大 38 float maxWeight = dogs[0].getWeight(); 39 int maxIndex=0; 40 //按顺序和后面的狗比较 41 for(int i=1;i<dogs.length;i++) 42 { 43 if(maxWeight<dogs[i].getWeight()) 44 { 45 //修改 46 maxWeight=dogs[i].getWeight(); 47 maxIndex=i; 48 } 49 } 50 System.out.println("体重最大的狗是第"+(maxIndex+1)+"体重是"+dogs[maxIndex].getWeight()); 51 //比较字符串内容是否相等时用 字符串提供的equals 不要用== 52 InputStreamReader isr1=new InputStreamReader(System.in); 53 BufferedReader br1= new BufferedReader(isr1); 54 System.out.println("请输入狗的名字"); 55 String name= br1.readLine(); 56 //我TM想了一下午 57 for (int j=0;j<dogs.length;j++) 58 { 59 if(name.equals(dogs[j].getName())) 60 { 61 System.out.println("狗的体重是" + dogs[j].getWeight()); 62 break; 63 } 64 //如果正好是3号狗j的值为3,然后会执行break退出 65 else if(j==3) //如果都没有这条狗j会变成3,执行这条语句 66 { 67 System.out.println("没有这只狗"); 68 } 69 } 70 } 71 72 } 73 class Dog 74 { 75 private String name; 76 public float weight; 77 public float getWeight() { 78 return weight; 79 } 80 public void setWeight(float weight) { 81 this.weight = weight; 82 } 83 public String getName() { 84 return name; 85 } 86 public void setName(String name) { 87 this.name = name; 88 } 89 }
注:比较字符串内容是否相等时用String提供的equals方法,而不用==
数组小结
- 数组可存放同一类型数据
- 简单数据类型(int,float)数组,可直接赋值
- 对象数组在定以后,赋值时需要再次为每个独享分配空间(即:new 对象)
- 数组的大小必须事先指定
- 数组名可以理解为执行数组首地址的引用
- 数组的下标是从0开始编号的
排序(Sorting)
排序是讲一群数据,依指定的顺序进行排列的过程。
排序的分类
- 内部排序:指将需要处理的数据都加载到内部存储器中进行排序。
包括(交换式排序法,选择式排序法和插入式排序法) - 外部排序法:数据量过大,无法全部加载到内存中,需要借助外部存储进行排序。
包括(合并排序法和直接合并排序法)
排序是数据处理中一种很重要的算法,同时也是常用的算法,一般数据处理工作的25%的时间都在继续那你给排序。简单地说,排序就是把一组记录(元素)按照递增或递减的次序重新排列的过程。
交换式排序法
交换式排序属于内部排序法,是运用数据值比较后,依判断规则对数据位置进行交换,一打到排序的目的。
交换式排序法又可分为两种:
1、冒泡排序法(Bubble sort)
核心思想:依次比较,使数值小(或大)的元素逐渐向前移动
1 public class test7 2 { 3 public static void main(String[] args) 4 { 5 int arr[]={1,6,0,-1,9}; 6 Bubble bubble = new Bubble(); 7 bubble.sort(arr); 8 } 9 10 } 11 class Bubble 12 { 13 //排序王法 14 public void sort(int arr[]) 15 { 16 int temp=0; 17 //排序开始 18 //外层循环——它决定一共走几趟 19 for(int i=0;i<arr.length-1;i++) 20 { 21 //内层循环,开始逐个比较,如果发现前一个数比后一个数大,则交换 22 for(int j=0;j<arr.length-1-i;j++) 23 { 24 if(arr[j]>arr[j+1]) 25 { 26 //换位 27 temp = arr[j]; 28 arr[j] = arr[j+1]; 29 arr[j+1] = temp; 30 } 31 32 } 33 } 34 //输出最后结果 35 for(int i=0;i<arr.length;i++) 36 { 37 System.out.println(arr[i]); 38 } 39 } 40 }
这里直接把数组传递到了方法中进行排序,传递的是引用,所以会直接改变数组的内容
但是基本数据类型并不是传引用,所以基本数据类型不会被类中的方法改变
1 public class test8 { 2 public static void main(String[] args) { 3 // TODO Auto-generated method stub 4 int a=12; 5 Test test1=new Test(); 6 test1.test(a); 7 System.out.println(a); 8 9 } 10 11 } 12 class Test 13 { 14 public void test(int a) 15 { 16 a++; 17 System.out.println(a); 18 } 19 } 20 21 输出结果: 22 13 23 12
2、快速排序法(Quick sort)
是对冒泡排序的一种改进。基本思想:在所有的数中找一个基准,然后将数分成两拨,一拨大于这个基准,一波小于这个基准。然后在对这两拨数进行相同的操作,这道所有的数都成为基准,也就意味着所有的数都有的次序。
图解:
1 package project1; 2 3 import java.util.*; 4 5 public class test2 { 6 public static void main (String[] args) 7 { 8 int arr1[]={-1,4,-3,7,34,98,0}; 9 int len = 100000; 10 int[] arr2 = new int[len]; 11 for(int i=0;i<len;i++) 12 { 13 //让程序产生一个1-10000数 14 //Math.random会随机产生一个0-1的数 15 int t=(int)(Math.random()*100000); 16 arr2[i] = t; 17 } 18 System.out.print("hello"); 19 QuickSort qs = new QuickSort(); 20 21 Calendar cal = Calendar.getInstance(); 22 System.out.println("排序前: "+cal.getTime()); 23 24 qs.sort(0,arr1.length-1,arr1); 25 26 cal = Calendar.getInstance(); 27 System.out.println("排序前: "+cal.getTime()); 28 29 for(int i=0;i<arr1.length;i++) 30 { 31 System.out.print(arr1[i]+" "); 32 } 33 } 34 } 35 class QuickSort{ 36 public void sort(int left,int right,int arr[]){ 37 int l=left; 38 int r=right; 39 int pivot=arr[(left+right)/2]; 40 int temp=0; 41 while(l<r){ 42 while(arr[l]<pivot) l++; 43 while(arr[r]>pivot) r--; 44 if(l>=r) break; 45 temp=arr[l]; 46 arr[l]=arr[r]; 47 arr[r]=temp; 48 if(arr[l]==pivot) --r; 49 if(arr[r]==pivot) ++l; 50 } 51 if(l==r){ 52 l++; 53 r--; 54 } 55 if(left<r) sort(left,r,arr); 56 if(right>l) sort(l,right,arr); 57 } 58 }
选择式排序法
选择式排序也属于内部排序法,是从欲排序的数据中,按指定的规则选出某一元素,经过和其他元素重整,在依原则交换位置后达到排序的目的
选择式排序法又可分为两种
1、选择排序法(Selection Sort)
核心思想:0-9,10个元素,选出最小的放到0上,然后从1-9中选出最小的放到1上,以此类推、
1 public class test9_2 2 { 3 public static void main(String[] args) 4 { 5 6 int arr[]={1,6,0,-1,9}; 7 8 Select select = new Select(); 9 select.sort(arr); 10 } 11 12 } 13 class Select 14 { 15 public void sort(int arr[]) 16 { 17 18 for(int j=0;j<arr.length-1;j++) 19 { 20 int temp=0; 21 int min = arr[j]; 22 int minIndex=j; 23 for(int k=j+1;k<arr.length;k++) 24 { 25 if(min>arr[k]) 26 { 27 min = arr[k]; 28 minIndex=k; 29 } 30 } 31 32 temp=arr[j]; 33 arr[j] = arr[minIndex]; 34 arr[minIndex] = temp; 35 } 36 for(int i=0;i<arr.length;i++) 37 { 38 System.out.println(arr[i]); 39 } 40 } 41 }
2、堆排序法(Heap Sort)
比较两个排序方法的速度
1 import java.util.*; 2 3 public class test9 4 { 5 public static void main(String[] args) 6 { 7 int len = 100000; 8 int[] arr = new int[len]; 9 for(int i=0;i<len;i++) 10 { 11 //让程序产生一个1-10000数 12 //Math.random会随机产生一个0-1的数 13 int t=(int)(Math.random()*100000); 14 arr[i] = t; 15 } 16 System.out.println("选择排序接受挑战"); 17 Select select = new Select(); 18 //排序前打印一个时间 19 Calendar cal=Calendar.getInstance();//单态模式,系统里面只有一个实例 20 System.out.println("排序前"+cal.getTime()); 21 select.sort(arr); 22 //重新得到实例,因为是单态的 23 cal=Calendar.getInstance(); 24 System.out.println("排序后"+cal.getTime()); 25 26 System.out.println("冒泡排序接受挑战"); 27 Bubble bubble=new Bubble(); 28 cal=Calendar.getInstance(); 29 System.out.println("排序前"+cal.getTime()); 30 bubble.sort(arr); 31 cal=Calendar.getInstance(); 32 System.out.println("排序后"+cal.getTime()); 33 34 } 35 36 } 37 class Select 38 { 39 public void sort(int arr[]) 40 { 41 42 for(int j=0;j<arr.length-1;j++) 43 { 44 int temp=0; 45 int min = arr[j]; 46 int minIndex=j; 47 for(int k=j+1;k<arr.length;k++) 48 { 49 if(min>arr[k]) 50 { 51 min = arr[k]; 52 minIndex=k; 53 } 54 } 55 56 temp=arr[j]; 57 arr[j] = arr[minIndex]; 58 arr[minIndex] = temp; 59 } 60 } 61 } 62 63 class Bubble 64 { 65 public void sort(int arr[]) 66 { 67 int temp=0; 68 for(int i=0;i<arr.length-1;i++) 69 { 70 for(int j=0;j<arr.length-1-i;j++) 71 { 72 if(arr[j]>arr[j+1]) 73 { 74 temp = arr[j]; 75 arr[j] = arr[j+1]; 76 arr[j+1] = temp; 77 } 78 79 } 80 } 81 } 82 }
结果是:
选择排序接受挑战 排序前Thu Sep 20 16:15:20 CST 2018 排序后Thu Sep 20 16:15:28 CST 2018 冒泡排序接受挑战 排序前Thu Sep 20 16:15:28 CST 2018 排序后Thu Sep 20 16:15:42 CST 2018
插入式排序法
插入式排序属于内部排序法,是对于欲排序的元素以插入的方式找寻该元素的适当位置,以达到排序的目的。
插入式排序法可分为三种
1、插入排序法(Insertion sort)
核心思想:两个数列一个有序,一个无序,开始时有序表只包含一个元素,无需表包含n-1个元素,从无需表中取一个元素,然后依次和有序表中的排序码进行比较,将它插入到合适的位置
1 public class test 2 { 3 public static void main(String[] args) { 4 int arr[]={-1,4,7,34,98,0}; 5 InsertSort insertsort = new InsertSort(); 6 insertsort.sort(arr); 7 for(int i=0;i<arr.length;i++) 8 { 9 System.out.println(arr[i]); 10 } 11 12 } 13 } 14 15 class InsertSort 16 { 17 public void sort(int arr[]) 18 { 19 for(int i=1;i<arr.length;i++) 20 { 21 //从arr数列中拿出一个数来 22 int insertVal = arr[i]; //和前一个数比较 23 int index = i-1; //index就是前面的数 24 while(index>=0 && insertVal<index) 25 { 26 //就把arr[index]向后移动 27 arr[index+1]=arr[index];//将index向后移动,腾出空间来 28 index--; 29 }//一直循环到前面的数比insertVal小为止然后把insertVal放到这个数后边 30 //或者当index--变成负数的时候,也就是要插入的数是最小的时候 31 arr[index+1] = insertVal;// 32 } 33 34 } 35 }
2、希尔排序法(Shell sort)
3、二叉树排序法(Binary-tree sort)
查找
1、顺序查找
2、二分查找
核心思想:运用递归每次都找中间的数
1 public class pra1 { 2 3 /** 4 * @param args 5 */ 6 public static void main(String[] args) { 7 // TODO Auto-generated method stub 8 int arr[] = {2,5,7,12,25}; 9 BinaryFind bf = new BinaryFind(); 10 //传递的数组的引用,也就直接对数组操作 11 bf.find(0, arr.length - 1, 12, arr); 12 } 13 14 } 15 16 class BinaryFind 17 { 18 public void find(int leftIndex,int rightIndex,int val,int arr[]) 19 { 20 //首先找到中间的数 21 int midIndex=(rightIndex+leftIndex)/2; 22 int midVal = arr[midIndex]; 23 24 if(rightIndex>=leftIndex)//如果没有数,用它来保障可以跳出递归 25 { 26 //如果要找的数比midVal大 27 if(midVal>val){ 28 //在arr左边数中找 29 find(leftIndex,midIndex-1,val,arr); 30 } 31 else if(midVal<val) 32 { 33 find(midIndex+1,rightIndex,val,arr); 34 } 35 else if(midVal == val) 36 { 37 System.out.println("找到下标"+midIndex); 38 } 39 } 40 } 41 }
多维数组
三维四维都不用,即使是3D MAX也用不到这些东西,3Dmax中会使用封装好的东西
二维数组
1、定义
语法: 类型 数组名 [][] = new 类型[大小][大小] 例如: int a[][] = new int[2][3]
2、二维数组在内存中的存放形式
3、案例,请用二维数组输出如下图形
0 0 0 0 0 0
0 0 1 0 0 0
0 2 0 3 0 0
0 0 0 0 0 0
1 public class pra { 2 public static void main(String[] args) { 3 int a[][] = new int[4][6];//简单的数据类型定义就可以用 4 //数组中未给值的元素默认都是0 5 a[1][2] = 1; 6 a[2][1] = 2; 7 a[2][3] = 3; 8 9 //把图形输出 10 for (int i=0;i<4;i++) //行 11 { 12 for(int j=0;j<6;j++) //列 13 { 14 System.out.print(a[i][j]+" "); 15 } 16 //换行 17 System.out.println(); 18 } 19 } 20 }