Java地基(五)----数组及排序

一、数组的筑基

1.概述(练体)

数组,是一组数据的集合,数组中的每个数据被称为元素。

关于parseint的使用:

//把接收到的值转换为int类型,并赋值给变量num
num = Integer.parseInt(args[0]);
2.数组的类型(分支)

在java中,数组也是对象。数组中的元素可以是任意类型(包括接口)(基本类型或引用类类型),但同一个数组里只能存放类型相同的元素。(或者兼容的,兼容就表示可以自动转 换)。

例如,int类型数组(int[])中,也是可以存放byte数据的,因为byte可以自动转换为int(兼容)

创建:

任意类型 + [] = 相应的数组类型

3.数组变量
  • 数组类型的变量,也是引用类型变量,简称引用,它是可以指向对象的(数组对象

声明方式:

推荐第一种:

  1. int[] a;
  2. int a[];
  • jvm中已经有数组类型因此可以直接使用:byte[] a = {1,2,3,4}
4.数组对象

数组对象,在内存中,就是一块连续的内存空间,在这个连续的空间中,可以存放多个类型相同的数据。

在这里插入图片描述

  • 数组对象中只有一个属性(length),表示数组的长度。
  • 数组对象中的方法,只有从父类型Object中继承过来的方法。
5.默认值

一个数组对象在创建的时候,需要指定数组长度,表示数组中最多存放的元素个数,并且在数组对象创建完成之后,数组中每一个元素位置上,就已经有了相应的默认值,这个默认值和数组的类型有关。

  • 类比实例变量即成员变量
6.数组初始化

下面以创建int类型数组对象进行说明

  1. int[] arr = new int[5]; 创建数组对象,没有还没有给其赋值

  2. int[] arr = new int[]{1,3,5,7,9}; 创建数组对象的同时,并赋值

  3. int[] arr = {1,3,5,7,9}; java提供了创建数组对象的简便形式

  4. int[] arr;

    arr = new int[]{1,3,5,7,9};

    显示声明数组类型变量,然后创建对象,并赋值

以下一些错误的数组创建方式:

错误方式一:

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

错误方式二:

int[] a;

a = {1,2,3};

6.数据拷贝

数组对象的长度确定之后便不能修改,但可以通过复制数组的内容变通实现改变数组长度

//该方法的声明
public static void arraycopy(Object src,
int srcPos,
Object dest,
int destPos,
int length)
//参数1,需要被复制的目标数组
//参数2,从目标数组的哪一个位置开始复制
//参数3,需要把数据复制到另外一个新的数组中
//参数4,把数据复制到新数组的时候,需要把数据从什么位置开始复制进去
//参数5,复制的目标数组的长度

写一个方法,接收一个数组对象,把这个数组对象的长度扩大到原来的2倍并返回。

public int[] test(int[] a){
	int[] b = new int[a.length*2];
	System.arraycopy(a, 0, b, 0, a.length);
	return b;
}
7.工具类

java.util.Arrays类,是JAVASE API中提供给我们使用的一个工具类,这个类的作用就是在代码中辅助我们对数组对象进行操作的。里面有很多静态方法可以直接调用,主要的功能就是对数组对象进行操作,例
如排序、查询、复制、填充数据等等

	int[] a = {5,6,3,2,1};
	String b= Arrays.toString(a);
	System.out.println(b);

Arrays中的常用方法:

  • toString方法
    可以把一个数组变为对应的String形式
  • copyOf方法
    可以把一个数组进行复制
    该方法中也是采用了arraycopy方法来实现的功能
  • copyOfRange方法
    也是复制数组的方法,但是可以指定从哪一个下标位置开始复制
    该方法中也是采用了arraycopy方法来实现的功能
  • sort方法
    可以对数组进行排序
  • binarySearch方法
    在数组中,查找指定的值,返回这个指定的值在数组中的下标,但是查找之前需要在数组中先进行
    排序
    ,可以使用sort方法先进行排序
  • equals方法
    可以比较俩个数组是否相等,但是要求俩个数组中的值一一相等并且顺序也要一致才行,所以在比较
    之前,我们最好是用sort方法对俩个数组先进行排序
    第一个要求,俩个数组的元素个数相同
    第二个要求,俩个数组的每个下标对应的数据相同
  • fill
    可以使用一个特定的值,把数组中的空间全都赋成这个值
  • asList
    可以把一组数据,封装到一个List集合中,并且把list集合对象返回。
8. 排序方式
冒泡排序:大数向后靠

规则:在一组数据中,从左到右,俩俩比较,然后把较大的数据往前推,一轮下来之后,最大的一个数
据就被推到了最右边。

在这里插入图片描述

//冒泡排序
public void test(int[] arr){
	//获取到数组的长度
	int len = arr.length;
	//外层循环控制一共比较几轮
	for(int i=0;i<len-1;i++){
		//内层循环控制每轮比较多少次数,每轮比较的次数是有变化的
		for(int j=0;j<(len-i-1);j++){
			//比较俩个相邻数据的大小
			//如果前一个数据比后一个数据大
			if(arr[j]>arr[j+1]){
				//交互这个俩个数据的位置
				arr[j] = arr[j] ^ arr[j+1];
				arr[j+1] = arr[j] ^ arr[j+1];
				arr[j] = arr[j] ^ arr[j+1];
			}
		} 
	//这个输出,可以看到每一轮比较结束后的结果是怎样的
	System.out.println("\t"+Arrays.toString(arr));
	}
}
选择排序:小数先向前排

规则:每一轮在待排序的区域中比较找到一个最小值后,把这个最小值放到已经排好顺序的区域的末
尾,剩下的部分,组成一个新的待排序部分,重复上面的步骤直到排序结束。

在这里插入图片描述

//注意,操作的核心目标:
// 1.每轮找到的最小值应该存放的下标位置是什么
// 2.每轮找到的最小值现在的下标位置是什么
// 3.找到之后,让这俩个位置的值进行交互就可以了
// 4.注意,最后一个数字就不用在比较了(前面都排好了,最后一个一定是最大的)
public void test(int[] arr){
	//数组的长度
	int len = arr.length;
	//min_now_index表示最小值【当前】在什么位置
	int min_now_index;
	//min_should_index表示最小值【应用】在什么位置
	int min_should_index;

	//外层循环,控制一共要比较多少轮,同时这个变量i,刚好是每轮我们需要指定的最小值应该存放置。
	for(int i=0;i<len-1;i++){
		//每一轮i的值,刚好就是本轮最小值应该存放的位置。
		min_should_index = i;
		//假设当前i的位置就是本轮最小值的实际位置
		min_now_index = i;
		//内层循环,负责每轮找出当前未排序区中的一个最小值的实际位置的下标
		for(int j=i+1;j<len;j++){
			//哪个数据小,就把这个数据下标赋值给min_now_index
			//目的是让了min_now_index变量中始终保持当前未排序区中的最小值的位置
			if(arr[j]<arr[min_now_index]){
				min_now_index = j;
			}
		} 
        //内层循环结束后,就明确了当前未排序区中的最新值的下标,以及这个最小值应该存放在什么置
		//接下来可以进行交互位置
		if(min_now_index != min_should_index){
			int temp = arr[min_now_index];
			arr[min_now_index] = arr[min_should_index];
			arr[min_should_index] = temp;
		}
	}
}
插入排序

规则:把数组分成俩部分,将后面部分的数据一个一个的和前面部分数据的元素进行比较,如果我们指
定的元素比前面部分的元素小,那么就将前面的元素往前移动一步,直到没有比我们这个指定元素还小
元素了,那么这个位置就是需要插入的地方。

在这里插入图片描述

//排序操作
//每轮操作完核心目标:
// 1 拿到右边当前要操作的数据,这个值需要临时的保存起来,以便向左边插入合适的位置
// 2 找出左边一个合适的插入位置
// 3 最后把右边当前操作的数据,插入到左边合适的位置
// 4.注意,最后一个数字也需要进行比较,因为要插入到左边一个合适的位置
public void test(int[] arr){
	//输出排序前的数组的排列
	System.out.println(Arrays.toString(arr));
	//当前在右边拿到的第一个要进行操作的数据
	int currentValue;
	//需要把数据在左边插入的位置
	int insertPosition;
	//外层循环,控制比较的轮数
	//同时,变量i的值,还是每一轮我们要操作的右边第一个数字的下标
	for(int i=1;i<arr.length;i++){
	//提前保存好我们当前要操作的值
		currentValue = arr[i];
		//假设当前变量i的值就是要插入的位置,因为这个数据有可能是原位置不动的。
		insertPosition = i;
		//内存循环,控制每轮比较的次数,以及比较的顺序
		//同时,变量j的值,还是左边数据中从大到小的下标值
		//例如:1 2 4 8 9 | 5 3 这个时候
		//我们拿着数字5 要依次和左边的9 8 4 2 1 比较
		//9 8 4 2 1的下标顺序就是 3 2 1 0 ,这就是j的值的变化规律
		for(int j=i-1;j>=0;j--){
				//每次比较,如果发现arr[j]比当前要操作的数字大
			if(arr[j]>currentValue){
				//就把这个大的数字往后移动一个位置,就是往后赋值
				arr[j+1] = arr[j];
				//然后记录一下这个位置,因为这个位置很可能是要插入的位置,到底是不是这个位置,需要和下一个数字比较后才知道
				insertPosition = j;
			}else{
				//如果发现一个比currentValue值还小的值,那么这个值的上一个比较的位置就是我们要找的插入的位置,结束当前循环
				break;
			}
		} 
        //内层循环结束后,把当前要操作的值currentValue,插入到指定位置insertPosition
		//如果insertPosition和当前i值相等,说明当前操作的这个值currentValue是不需要移的。
		if(insertPosition != i){
			//进行值的插入
			//把当前右边第一个值(正在操作的值),插入到左边合适的位置
			arr[insertPosition] = currentValue;
		} 
        //输出每一轮排序的过程
		System.out.println("\t"+Arrays.toString(arr));
	} 
    //最后输出排序的结果
	System.out.println(Arrays.toString(arr));
}
快速排序: 快速排序(Quicksort)

是对冒泡排序算法的一种改进

如果要排序数组中下标从 p 到 r 之间的一组数据,我们选择 p 到 r 之间的任意一个数据作为 pivot(分区点)。我们遍历 p 到 r 之间的数据,将小于 pivot 的放到左边,将大于 pivot 的放到右边,将 pivot 放到中间。经过这一步骤之后,数组 p 到 r 之间的数据就被分成了三个部分,前面 p 到 q-1 之间都是小于 pivot 的,中间是 pivot,后面的 q+1 到 r 之间是大于 pivot 的。

/*
 * 快速排序
 *
 * 参数说明:
 *     a -- 待排序的数组
 *     l -- 数组的左边界(例如,从起始位置开始排序,则l=0)
 *     r -- 数组的右边界(例如,排序截至到数组末尾,则r=a.length-1)
 */
void quick_sort(int a[], int l, int r)
{
    if (l < r)
    {
        int i,j,x;

        i = l;
        j = r;
        x = a[i];
        while (i < j)
        {
            while(i < j && a[j] > x)
                j--; // 从右向左找第一个小于x的数
            if(i < j)
                a[i++] = a[j];
            while(i < j && a[i] < x)
                i++; // 从左向右找第一个大于x的数
            if(i < j)
                a[j--] = a[i];
        }
        a[i] = x;
        if(i-1>l) quick_sort(a, l, i-1); /* 递归调用 */
        if(i+1<r) quick_sort(a, i+1, r); /* 递归调用 */
    }
}
}    
9. 二维数组

理解:可以把这个二维数组,理解为一栋大厦,共有4层楼,每层楼有3间房,每个房间可以存放一个int
数据,现在每个房间的默认值都是0

9.1 声明与创建:
//第一个中括号中的4,代表这个二维数组对象里面,最多可以存放4个一维数组
//第二个中括号中的3,代表这个二维数组中,每个存放的一维数组对象,都可以存放存放3个int数据
int[][] a = new int[4][3];
//这句代码等价于以下代码
int[][] a = new int[4][];
a[0] = new int[3];
a[1] = new int[3];
a[2] = new int[3];
a[3] = new int[3];
//这句代码等价于以下代码
int[][] a = {
{0,0,0},
{0,0,0},
{0,0,0},
{0,0,0}
};
10. 可变参数 …

JDK1.5或者以上版本中,可以使用可变参数

语法格式及使用:

public void test(int... a){
} 
//在调用这种方法的时候,我们所传的参数情况就可以有多种选择了
int[] arr = {1,2,3};
t.test();
t.test(1);
t.test(1,2,3,4);
t.test(arr);


//传其他普通类型
public void test(String str,int... a){
}

方法中有一个可变参数同时,还可以有其他普通的参数
注意,可变参数和普通参数共存的时候,可边参数必须放到最后一个参数的位置

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值