Java学习日记基础篇(七) —— 数组、排序

数组

为什么要有数组?

案例:一个养鸡场有六只鸡,他们的体重分别为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方法,而不用==

数组小结

  1. 数组可存放同一类型数据
  2. 简单数据类型(int,float)数组,可直接赋值
  3. 对象数组在定以后,赋值时需要再次为每个独享分配空间(即:new  对象)
  4. 数组的大小必须事先指定
  5. 数组名可以理解为执行数组首地址的引用
  6. 数组的下标是从0开始编号的

排序(Sorting)

   排序是讲一群数据,依指定的顺序进行排列的过程。

排序的分类

  1. 内部排序:指将需要处理的数据都加载到内部存储器中进行排序。
    包括(交换式排序法,选择式排序法和插入式排序法
  2. 外部排序法:数据量过大,无法全部加载到内存中,需要借助外部存储进行排序。
    包括(合并排序法和直接合并排序法

排序是数据处理中一种很重要的算法,同时也是常用的算法,一般数据处理工作的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 }
Bubble sort

  这里直接把数组传递到了方法中进行排序,传递的是引用,所以会直接改变数组的内容
  但是基本数据类型并不是传引用,所以基本数据类型不会被类中的方法改变

 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 }
quick sort

选择式排序法

  选择式排序也属于内部排序法,是从欲排序的数据中,按指定的规则选出某一元素,经过和其他元素重整,在依原则交换位置后达到排序的目的

选择式排序法又可分为两种

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 }
Select sort

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 }
生成10000个数进行排序

结果是:

选择排序接受挑战
排序前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 }
Insert Sort

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 }
Binary Find

多维数组

三维四维都不用,即使是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 }
二维数组
原文地址:https://www.cnblogs.com/houzhaohui/p/9661321.html