【Java】数组的几种简单操作(元素拷贝,排序,搜索)

本文深入探讨了数组的基本操作,包括元素拷贝、排序和搜索。详细介绍了冒泡排序、选择排序和插入排序等经典排序算法,并提供了线性搜索和二分搜索的实现。适合初学者理解和实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 数组元素的拷贝

需求

从指定远数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束。

即:原数组中位置在srcPos到srcPos+length-1之间的元素被分别复制到目标数组中的

destPos到desPos+length-1的位置。

代码实现
/*
	srcArr: 原数组
	srcPos: 从原数组中的哪一个索引开始拷贝
	desArr: 目标数组
	desPos: 在目标索引中的哪一个位置开始粘贴
	length: 拷贝原数组的元素个数
*/
public static void arrayCopy(int[] srcArr, int srcPos, int[] desArr, int desPos, int length){

	if (srcPos < 0 || desPos < 0 || length > srcArr.length )
	{
		return ;// 不合理
	}
	for (int i = 0; i < length ;i++ )
	{
		desArr[desPos+i] = srcArr[srcPos+i] ;
	}

}

但是以上代码存在以下问题:

  1. 只能拷贝int类型数组;
  2. 代码不够健壮;

因此:
在这里插入图片描述
在这里插入图片描述

2. 数组元素排序

排序主要有:

1.选择排序(直接选择排序,堆排序);
2. 交换排序(冒泡排序,快速排序);
3. 插入排序(直接插入排序,二分插入排序,Shell排序);
4. 归并排序;

这里主要写了冒泡排序,选择排序,插入排序;但是在开发中因为性能的问题,我们都不会自己写排序算法,不过排序在笔试中经常见到。

2.1 冒泡排序

基本思路:对要未排序的每一个元素从头到尾依次比较相邻的两个元素的大小,若大于则交换位置,经过第一轮的比较得出最大值,然后使用相同的方法把剩下的元素逐个比较即可。
可以看出,若是有N个元素,那么一共要进行N-1轮比较,第M轮要进行 N-M 次比较。(如有6个元素,要进行5轮比较,第一轮比较5次,第二轮比较4次,第三轮比较3次…);

代码实现


// 冒泡排序算法
public class BubbleSort{

    public static void main(String args[]){
    	int[] nums = {6,3,2,5,1};
		bubbleSort(nums); // 开始排序
		//printArray(nums); // 打印排序后的数组	
    }
	
	public static void bubbleSort(int[] nums){	
		for(int i = 0 ; i < nums.length - 1; i++){ // 要比较的轮数
			for(int j = 0; j < nums.length - 1 - i; j++){ //每一轮要比较多次数	
				int temp; //定义临时变量
				temp = nums[j];			
				if (nums[j] > nums[j+1]){
					
					nums[j] = nums[j+1];
					nums[j+1] = temp;			
				}
				System.out.print("第"+(i+1)+"轮"+"第"+(j+1)+"次排序结果:");
				printArray(nums);
			}
		}
	}
	// 按照格式打印数组	
	public static void printArray(int[] nums){		
		String res = "[";
		for (int i = 0; i < nums.length; i++){
			res = res + nums[i];	
			if ( i != nums.length - 1){
				res = res + ",";			
			}			
		}		
		res = res + "]";		
		System.out.println(res);
	}		
}
---------- 运行java ----------1轮第1次排序结果:[3,6,2,5,1]1轮第2次排序结果:[3,2,6,5,1]1轮第3次排序结果:[3,2,5,6,1]1轮第4次排序结果:[3,2,5,1,6]2轮第1次排序结果:[2,3,5,1,6]2轮第2次排序结果:[2,3,5,1,6]2轮第3次排序结果:[2,3,1,5,6]3轮第1次排序结果:[2,3,1,5,6]3轮第2次排序结果:[2,1,3,5,6]4轮第1次排序结果:[1,2,3,5,6]

输出完成 (耗时 0) - 正常终止

2.1 选择排序

基本思路: 选择某个索引位置的元素,然后和后面的元素一次比较,若大于则交换位置,经过第一轮比较排序得出最小值,然后使用相同的方法把剩下的元素逐个比较即可。可以看出:第一轮会选出最小值,第二轮中会选出第二个最小值,直到最后。

第一轮用arry[0]和后面的元素依次比较,第二轮使用arry[1]和后面的元素相比较,一次类推。N个数进行N-1轮比较。

Java选择排序的思想(以从小到大排序为例,从大到小排序于此相同):
在arr[0]到arr[n-1]中选出最小(大)的的数与arr[0]交换位置,
在arr[1]到arr[n-1]中选出最小(大)的的数与arr[1]交换位置,
在arr[2]到arr[n-1]中选出最小(大)的的数与arr[2]交换位置,
在arr[n-2]到arr[n-1]中选出最小(大)的的数与arr[n-2]交换位置,

选择排序每一轮只进行一次交换,相对于冒泡排序效率高一些。

代码实现
class SelectSortDemo 
{
	public static void main(String[] args) 
	{		
		int[] nums = {6,3,2,5,1};
		selectSort(nums);
		printArray(nums);
	}
	public static void selectSort(int[] nums){
		for(int i=0; i < nums.length-1; i++){ //要比较的轮数
		
			for (int j=0; j < nums.length-i-1; j++ ) //每一轮要交换的次数
			{

				if (nums[i] > nums[i+j+1] )
				{
					int temp = nums[i]; // 先把当前索引记录在临时变量中
					nums[i] = nums[i+j+1]; 
					nums[i+j+1] = temp;
				}
				System.out.print("第"+(i+1)+"轮"+"第"+(j+1)+"次排序结果:");
				printArray(nums);
			}		
		}	
	}
	// 按照格式打印数组
	public static void printArray(int[] nums){	
		String res = "[";
		for (int i = 0; i < nums.length; i++){			
			res = res + nums[i];			
			if ( i != nums.length - 1){				
				res = res + ",";			
			}			
		}		
		res = res + "]";		
		System.out.println(res);
	}	
}
---------- 运行java ----------1轮第1次排序结果:[3,6,2,5,1]1轮第2次排序结果:[2,6,3,5,1]1轮第3次排序结果:[2,6,3,5,1]1轮第4次排序结果:[1,6,3,5,2]2轮第1次排序结果:[1,3,6,5,2]2轮第2次排序结果:[1,3,6,5,2]2轮第3次排序结果:[1,2,6,5,3]3轮第1次排序结果:[1,2,5,6,3]3轮第2次排序结果:[1,2,3,6,5]4轮第1次排序结果:[1,2,3,5,6]

输出完成 (耗时 0) - 正常终止

选择排序到这里并没有结束!!上述的选择排序的代码其实是有点小瑕疵的。在N轮的排序中,第M轮要进行 N-M 次比较。比如,5个元素的排序,第一轮中需要进行4次位置交换,第二轮进行3次位置交换,效率不够高效!其实,在一轮的排序中,完全可以只进行一次位置的交换!

改进代码

public static void selectSort(int[] nums){

	for(int i = 0 ; i < nums.length - 1; i++){ // 要比较的轮数
		int minValueIndex = i; // 假设一个最小值的索引
		for(int j = 0; j < nums.length - 1 - i; j++){ //每一轮要比较多次数			
			if (nums[minValueIndex] > nums[i+j+1]){
				minValueIndex = i+j+1;  // 获取到最小值的索引							
			}
		}
		int temp = nums[i]; //定义临时变量
		nums[i] = nums[minValueIndex];
		nums[minValueIndex] = temp;
		System.out.print("第"+(i+1)+"轮排序结果:");
		printArray(nums);
	}
}
---------- 运行java ----------1轮排序结果:[1,3,2,5,6]2轮排序结果:[1,2,3,5,6]3轮排序结果:[1,2,3,5,6]4轮排序结果:[1,2,3,5,6]

输出完成 (耗时 0) - 正常终止

数组元素搜索

数组的搜索:从一个数组中搜索指定元素的索引位置;

搜索的方式:

(1)线性搜索:从头到位 / 从尾到头(indexOf / lastIndexOf)
但是这种搜索方式对于元素个数多的数组性能极低(最少搜索次数为1,最多搜索次数为N,平均搜索次数 (N+1) / 2)。

(2) 二分搜索法(折半查找法/二分搜索法):

代码实现(线性搜索)


// 线性搜索
import java.util.ArrayList;
import java.util.List;
public class LinearSearch{
    public static void main(String args[]){
		
		int[] nums = new int[]{6,1,3,3,5,6,9,1};	
		int ele = 1;
		List<Integer> list = linearSearch(nums,ele);  
		for(int index : list){
			
			System.out.println(index);
		}
    }
	// 线性搜索
	public static List<Integer> linearSearch(int[] nums, int ele){
		
		List<Integer> list = new ArrayList<Integer>();		
		for (int i = 0 ; i < nums.length; i++){		
			if (nums[i] == ele){
			
				list.add(i);			
			}
		}	
		return list;	
	}
}

代码实现(二分查找法)

// 二分查找法的前提:数组必须是有序的!
class BinarySearch 
{
	public static void main(String[] args) 
	{
		int[] nums = new int[]{4,3,2,5,1,99,22,23,11,21,8,6,9,18,919};
		selectSort(nums);
		printArray(nums);

		int index = binarySearch(nums,99);
		
		if (index == -1) // 判断元素是否存在
		{
			System.out.println("This element does not exist! ");
		}else{
			System.out.println(index);
		}		
	}

	// 二分查找法
	public static int binarySearch(int[] nums, int ele){

		int lowIndex = 0;
		int highIndex = nums.length-1;
		
		while(lowIndex <= highIndex){

			int midIndex = (lowIndex + highIndex) / 2;
			
			if ( ele < nums[midIndex])
			{
				highIndex = midIndex - 1;
			}

			else if(ele > nums[midIndex])
			{
				lowIndex = midIndex + 1;
			}
				
			else 
			{
				return midIndex;
			}
		}
		
		return -1;
	}
	
	// 选择排序
	public static void selectSort(int[] nums){
	
		for (int i = 0; i < nums.length-1 ; i++)
		{
			int minValueIndex = i;
			for(int j = 0; j < nums.length-1-i; j++){
			
				if (nums[minValueIndex] > nums[i+j+1])
				{
					minValueIndex = i+j+1;				
				}
			}
		int temp = nums[i];
		nums[i] = nums[minValueIndex];
		nums[minValueIndex] = temp;
		}	
	}	
	
	// 打印数组
	public static void printArray(int[] nums){		
		String res = "[";
		for (int i = 0; i < nums.length; i++){			
			res = res + nums[i];			
			if ( i != nums.length - 1){				
				res = res + ",";			
			}			
		}		
		res = res + "]";	
		System.out.println(res);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值