JavaSE基础语法--傻瓜笔记--1031(第四章:数组与基础排序算法)

第四章:数组

1.数组的基本概念及作用

  1. 定义:数组是相同数据类型元素的集合。
  2. 数组本身是引用数据类型,即对象。但是数组可以存储基本数据类型,也可以存储引用数据类型。
  3. 数组是一种线性数据结构,在内存中是连续空间

2.数组的创建

数组声明的两种形式:
  1. 数据类型 [] 数组名 例:int [] a;
  2. 数据类型 数组名 [] 例:int a [];

:在java中两种声明格式没有任何区别,但是建议大家使用第一种,避免混淆 a 的数据类型。

特例

  1. int [] a ,c; 这两个都是数组。
  2. int a [] ,c;这里面 a 是数组,c 是int 类型的整数。
  3. int a,c [];这里面 a 是 int 类型的整数,c是数组。
数组创建的三种方式:
  1. 声明数组的同时,根据指定的长度分配内存,但数组中元素值都为默认的初始化值。int:0,double:0.0, char: 看不见的空格, boolean: flase ,引用类型:null。

    int [] array0 = new int [10]; // 数组的长度定义之后不能再修改。

     // 通过索引赋值
            int [] a = new int[5];
            // 比数组元素的数据类型容量小的可以赋值,大的不行。
            byte c = 10;
            a[0] = c;
            a[1] = 2*11;
            a[2] = a[0]*a[1];
            a[3] = 24;
            a[4] = 25;
    
  2. 声明数组并分配内存,同时将其初始化。

    int array1 = new int [] {1,2,3,4};

  3. 与前一种一样,但是语法相对的简化

    int array2 = {1,2,3,4};

  4. 如果存储的是引用类(类类型),会存储对象的引用(这时候就需要在被引用的类中重写Object的toString方法)

  5. 动态创建数组与静态创建数组

    1.动态创建数组(没有为元素赋值,可以结合for循环进行赋值)

    char [] charArray = new char[10];

    2.静态创建数组,在创建时即为每个元素赋初值

    int array1 = new int [] {1,2,3,4};

代码

/*
* 数组:具有相同数据类型元素的集合。
*       数组本身是引用类型的,但是它里面的元素既可以是基本类型,也可以是引用类型
* 数组是一种线性结构,在内存中是连续空间
* 数组一旦确定长度一般情况下是不可以改变的
* */
public class ArrayDemo1 {
    public static void main(String[] args) {
        // 数组的声明
        int [] a;
        int b [];
        // 这两种数组都是可以的,没有任何区别,但是推荐使用第一种。因为,第一种可以避免混淆。
        				// int代表的是数组里面的数据类型,而不是数组a的数据类型,这样排列会更加的明了。
        int [] a1,b1;
        int a2 [],b2;
        // 上面第一种表示的是a1,b1都是数组,而第二种表示的是a2是数组,而b2是int类型的整数。

        // 第一种数组定义,直接给数组分配10个长度,数组会默认初始化值。
        int [] c = new int[10];//int类型的默认赋值时0,浮点是0.0,
                                    // char是看不见的空格,boolean是false,引用类型是null
        System.out.println(Arrays.toString(c));

        // 第二组数组定义,不分配长度,直接赋值,然后数组自动生成长度。
        int [] d = new int[] {1,2,3,4,5};
        System.out.println(d);//由于数组d是引用类型,所以这样输出的是一组哈希值。
        System.out.println(Arrays.toString(d));//通过这个方法就可以以字符串的形式输出。

        // 第三中数组定义,与第二种一样,只是更加的简化。
        int [] e = {1,2,3,4,5};
        System.out.println(Arrays.toString(e));

        // 存储引用类型
        Car car0 = new Car("car1");
        Car car1 = new Car("car2");
        Car car2 = new Car("car3");
        Car car3 = new Car("car4");
        Car car4 = new Car("car5");
        Car [] car ={car0,car1,car2,car3,car4};
        // System.out.println(car0); 这样返回的是car0指向的对象的哈希值
        // com.ff.javaArray1030.day1.Car@4554617c

        // 所以如果存储的是引用类(类类型),会存储对象的引用。这个时候就需要在引用的类里面重写toString();
        System.out.println(Arrays.toString(car));
        for (Car item:car
             ) {
            System.out.print(item+"\t");
        }
    }
}

数组的长度:

int [] a = new int []{1,2,3,4,5};

System.out.println(a.length);

代码

int [] a1 = new int[]{1,2,3,4,5};
 System.out.println(a1.length);

3.数组的访问与迭代

索引:
  1. 数组的索引从0开始
  2. 索引的数据类型是整型
  3. 索引的最大值比数组长度少一
数组元素的访问

​ 数组的名字[索引] 例如:a[0],a[1] ,数组中每个位置都有索引(下标,标号)

数组的迭代:
  1. for循环遍历(区间已知)
		 int [] b = {11,21,31,41,51};
        //for循环迭代:适合区间已知的
        // 因为索引的最大值是数组的最大值减一,,所以刚好比数组的长度减一就行,Java也默认设置了数组的长度变量length
        for(int i=0;i<b.length;i++){
            System.out.print(b[i]+" ");
        }
  1. foreach循环(加强for ,JDK5以后拥有)

    原理:每次从数组中取一个值赋给变量item,直到遍历结束。

    for(int item:b){
                System.out.print(item+" ");
            }
    

4.冒泡排序

原理:大的下沉,小的冒上来。

算法描述:相邻两个元素之间比较,若前一个大,就交换。

规律

​ 总趟数是数组的长度减一。

​ 每比较一趟,下一趟就少比较一次。

/*
* 冒泡排序
* 大的下沉,小的冒起来
* 趟数比数组的长度减一
* 每比完一次,就少比较一次
* */
public class BubbleSort {
    public static void sort(int [] a){
        for (int i = 0; i < a.length-1; i++) {// 趟数
            for (int j = 0; j <a.length-i-1; j++) {// a.lenrth-i-1 ,意为每比较一趟之后少比较一个,
                                                    // 并且第一次比较的次数就比数组长度小一
                int temp;// 临时变量 ,暂时存储元素。
                if(a[j]>a[j+1]){
                    temp = a[j];
                    a[j] = a[j+1];
                    a[j+1] = temp;
                }
            }
        }
    }
    public static void main(String[] args) {
        int [] a = {54,123,23,113,5,35,1};
        // 54,23,113,5,35,1,123
        // 23,54,5,35,1,113,123
        // 23,5,35,1,54,113,123
        // 5,23,1,35,54,113,123
        // 5,1,23,35,54,113,123
        // 1,5,23,35,54,113,123
        BubbleSort.sort(a);// 引用类型传递
        System.out.println(Arrays.toString(a));//这里输出的a和Array指向的是同一个引用,
                                                // 所以方法中的内容改变会影响到外面的对象引用
    }
}

5.选择排序

原理:用一个元素与后面所有的元素比较,若最小则不变,若不是,则交换位置,之后继续用"新"的最小的与后面尚未比较的一一比较,比完之后,这是一次比较的完成。

规律:内层循环的 j 的初始值为 j = j + 1;这是因为第一个元素要与后面的一一比较。

未优化的算法:每成立一次,就需要交换一次。

优化后的算法:先记录,最后只交换一次。

/*
* 选择排序
* */
public class SelectSort {
    public static void sort(int [] a){
        //未优化算法
        for (int i = 0; i < a.length-1; i++) {// 趟数还是数组长度减一
            for (int j = i+1; j < a.length; j++) {// 这里只需要第一个和后面的每一个排序,
                                                    // 所以j=i+1,j
                if(a[i]>a[j]){// 这样是每次符合条件,都需要交换一次
                    int temp = a[i];
                    a[i] = a[j];
                    a[j] = temp;
                }
            }
        }
    }

    public static void sort1(int [] a){
        // 优化的算法
        int minindex;// 加了一个变量,可以记录目前最小的元素的下标
        for (int i = 0; i < a.length-1; i++) {// 趟数比数组长度少一
            minindex = i;
            for (int j = i+1; j <a.length ; j++) {
                if(a[minindex]>a[j]){
                    minindex = j;
                }
            }
            // 在内层循环找出最小的元素的下标之后,再在外层循环里面进行一次交换。
            int temp1 = a[i];
            a[i] = a[minindex];
            a[minindex] = temp1;
        }
    }
    public static void main(String[] args) {
        int [] a = {7,5,9,1,3};
                    // 1,7,9,5,3
                    // 1,3,9,7,5
                    // 1,3,5,9,7
                    // 1,3,5,7,9
        SelectSort.sort(a);
        System.out.println(Arrays.toString(a));

        SelectSort.sort1(a);
        System.out.println(Arrays.toString(a));
    }
}

6.插入排序

原理:假定前面都是排好序的,现在要往其中插入一个数,但是为了保持之后仍是排好序的。因此,这个要插入的数需要与前面的每一个比较,直到找到自己的位置。反复执行,直到找到全部排好。

:需要注意保存需要插入的元素的值,和已经排好序的紧挨的元素的下标,因为这个下标是后面用来判断下标合法范围的。

/*
* 插入排序
* */
public class InsertSort {
    public static void sort(int [] a){
        for (int i=0; i < a.length-1; i++) { /* 这里只需要走过一遍数组就可以完成排序。
                                                所以这里的 a.length-1 约束的是下标,而非趟数。*/
            int current = a[i+1];/* 使用current变量存储a[i+1]的值,这里只能存储值,如果存储下标的话,
                                     在for循环中会改变当前下标的值,导致值丢失。*/
            int perindex = i; /* 使用perindex变量存储啊a[i]的下标 i ,这里不存储值是为了,
                                     后面判断索引合法范围的时候需要使用。*/
            while(perindex>=0 && a[perindex]>current){/* 假设目前用3进行比较,3的值被存储在current中,是隐式的,
                                                         但是是一直在用3和前面的比较,直到找到位置。*/
                a[perindex+1] = a[perindex];// 用两者中的前一个将后面的覆盖
                perindex--;// 光标前移,继续比较
            }
            a[perindex+1] = current;// 这里的加一是因为上面的for循环多减了一个一,因此需要加一,返回到正确的位置。
        }
    }
    
    // 这个是使用for循环来实现的
    public static void sort1(int [] a){
        for (int i = 0; i < a.length-1; i++) {
            int current1 =a[i];
            int j=i-1;
            for ( ; j>0 && a[j]>a[i]; j--) {
                a[i] = a[j];
            }
           a[j+1] =current1;
        }
    }
    public static void main(String[] args) {
        int [] a = {2,4,1,3,7,0};
                    // 2,4,1
                    // 2,4,4
                    // 2,2,4
                    // 1,2,4,3,7
                    // 1,2,4,4(3),7
                    // 1,2,3,4,7
        InsertSort.sort(a);
        System.out.println(Arrays.toString(a));

        InsertSort.sort1(a);
        System.out.println(Arrays.toString(a));
    }
}

7.二维数组

定义:数组的数组,二维数组的每一个元素都是一个二维数组。

  1. 二维数组声明:

    1. 数据类型 [] [] 变量名 int [][] a = new int [][]{};
    2. 数据类型 变量名 [] [] int a [][] = new int [2][3];
    3. 是第一种的简化 int [][] a = {{1,2,3},{4,5,6}};
  2. 特例

int [][] b = new int [2][];// 先声明二维数组的长度
b[0] = new [3]; // 在声明二维数组中第一个一维数组的长度
b[0][0] = 1;
b[0][1] = 1;
b[0][2] = 1;
b[1] = new [2];
b[1][0] = 1;
b[1][1] = 1;
// 执行后的效果  1  1  1
			// 1  1

  1. 二维数组创建及遍历代码:

    /*
    * 二维数组
    * */
    public class TwoArray {
        public static void main(String[] args) {
            // 声明二维数组
            // 第一种
            int [][] a = new int[][]{};
    
            // 第二种
            int [][] b = new int[3][2];// 这里的3代表的是二维数组的长度,也是二维数组中一维数组的个数。
                                            // 2代表的是一维数组的长度
    
            // 第三种
            int [][] c = {{1,2,3},{4,5,6},{7,8,9}};
                        // 0 1 2    0 1 2  0 1 2
                        //  0         1      2
    
            //二维数组的遍历
            for (int i = 0; i < c.length; i++) {// 每次从二维数组中取出一个一维数组,
                                                    // 这里从c.length代表的是二维数组的长度
                for (int j = 0; j < c[i].length; j++) {// 这里的c[i].length是一维数组的长度
                    System.out.print(c[i][j]+"\t");// \t转义table
                }
                System.out.println();
            }
        }
    }
    

    若有错误,欢迎私信指正。

你可能感兴趣的:(笔记,java,数组,排序算法)