一、常见数组算法应用
1.选择排序(直接排序)
选择排序(直接排序) : 使用数组中的一个元素与其他位置的元素挨个比较一次,符合条件交换位置。
需求2: 定义一个函数接收一个数组对象,然后把数组中最大值放在第一位。 其他元素不能丢失,顺序无所谓。
class Demo2 {
public static void main(String[] args)
{
int[] arr = {13,11,17,4,19};
selectSort(arr);
}
public static void selectSort(int[] arr){
for(int j = 0 ; j<arr.length-1 ; j++ ){
//把最大值放在第0号位置
for(int i = j+1 ; i<arr.length ; i++){
if(arr[j]<arr[i]){
int temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
}
}
//遍历数组的元素,查看效果
for(int i = 0 ; i<arr.length ; i++){
System.out.print(arr[i]+",");
}
}
}
2.冒泡排序
冒泡排序: 相邻的两个元素比较一次,符合条件交换 位置。
需求: 把最大值放在倒数第一个位置。
class Demo3
{
public static void main(String[] args)
{
int[] arr = {11, 14 , 5 , 18, 3}; // 长度:5 。 最大索引值:4
bubbleSort(arr);
}
public static void bubbleSort(int[] arr){
for(int j = 0 ; j<arr.length-1; j++){ // 疑问:arr.length-1。 因为五个数据只需要找出四个最大值即可排序
//把最大值放在倒数的第一个位置
for(int i = 0 ; i < arr.length-1 - j ; i++){ //i=4 疑问: 因为for循环每执行完一次就 可以找出一个最大值,每找出一个最大值其实就可以少比较一次。
if(arr[i]>arr[i+1]){
//交换位置
int temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
}
}
//遍历数组,查看效果
for(int i = 0; i < arr.length ; i ++){
System.out.print(arr[i]+",");
}
}
}
3.二分法(折半查找法)
二分法(折半查找法): 折半查找法只适用于有序的数组。
需求: 定义一个函数接收一个数组与一个要查找的元素,然后返回元素在数组中的索引值。如果不存在
返回-1表示。
class Demo4
{
public static void main(String[] args)
{
int[] arr = {12,15,18,19,34};
int index = halfSearch(arr,13);
System.out.println("索引值:"+ index);
}
//折半查找法
public static int halfSearch(int[] arr, int target){
//定义三个变量记录查找范围的最大、最小、中间索引值
int max = arr.length-1;
int min = 0;
int mid = (max+min)/2;
while(true){
if(target>arr[mid]){
min = mid+1;
}else if(target<arr[mid]){
max = mid-1;
}else{
//找到的情况
return mid;
}
//由于上面会改变最大、最小索引值,所以应该要重新计算中间值。
mid = (max+min)/2;
//找不到的情况
if(min>max){
return -1;
}
}
}
4.数组的元素翻转.
class Demo5
{
public static void main(String[] args)
{
// 值传递..
char[] arr = {'传','智','播','客'}; //0x97
reverse(arr); //
for(int i = 0; i < arr.length ; i++){
System.out.print(arr[i]+",");
}
}
public static void reverse(char[] arr){ // 0x97
for(int startIndex=0 ,endIndex=arr.length-1 ; startIndex<endIndex; startIndex++,endIndex--){
//交换位置
char temp = arr[startIndex];
arr[startIndex] = arr[endIndex];
arr[endIndex] = temp;
}
}
}
二、数组的工具类(Arrays):
对数组常见的操作:
1. 找出最大值。
2. 排序
3. 二分法查找元素
数组的工具类(Arrays):
String toString(boolean[] a) 返回指定数组内容的字符串表示形式
sort(数组) 排序
binarySearch() 二分法 返回返回的是元素在 数组的索引值,如果不存在返回负数表示。
import java.util.*;
class Demo6{
public static void main(String[] args)
{
int[] arr = {12,5,18,4,20};
//排序
Arrays.sort(arr);
//二分法查找
int index = Arrays.binarySearch(arr,6); // 返回的负数就是第一个比目标元素大的元素+1 ,再加上负号即可。
System.out.println("数组的元素:"+ Arrays.toString(arr));
System.out.println("元素的索引值:"+ index);
}
二、二维数组
二维数组的初始化方式:
动态初始化:
数据类型[][] 变量名 = new 数据类型[长度1][长度2];
静态初始化:
数据类型[][] 变量名 = {{元素1,元素2...},{元素1,元素2...}.....}
三、数组练习
例子:
1.需求: 现在有如下的一个数组:int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5} ,
要求清除数组中为0的元素,然后存储非零的数据存储到一个新数组中。而且要求新的数组不能浪费长度。
import java.util.*;
class Demo8
{
public static void main(String[] args)
{
int oldArr[]={0,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5};
int[] newArr = clearZero(oldArr);
System.out.println("新数组的元素:"+ Arrays.toString(newArr));
}
public static int[] clearZero(int[] oldArr){
//先统计0的个数
int count = 0; //定义该变量用于记录0的个数
for(int i = 0 ; i<oldArr.length ; i++){
if(oldArr[i]==0){
count++;
}
}
//创建新的数组
int[] newArr = new int[oldArr.length-count];
int index = 0; //新数组使用的索引值。
//遍历旧的数组,把非0的数据存储到新数组中。
for(int i = 0 ; i<oldArr.length ; i++){
if(oldArr[i]!=0){ //如果是非0的数据,就应该存储到新的数组中.
newArr[index++] = oldArr[i];
}
}
return newArr;
}
}
例子2: 清除重复元素。 int[] oldArr = {1,4,9,4,1,1,7}; 把非重复元素存储到一个新的数组中返回,而且也是不能浪费长度。
import java.util.*;
class Demo9
{
public static void main(String[] args)
{
int[] oldArr = {1,4,9,4,1,1,7};
int[] newArr = clearRepeat(oldArr);
System.out.println("清除重复元素的数组:"+ Arrays.toString(newArr));
}
public static int[] clearRepeat(int[] oldArr){
int count = 0 ; //count变量 是用于记录重复元素的个数
//计算出重复元素的个数
for(int i = 0 ; i<oldArr.length -1 ; i++ ){
for(int j = i+1 ; j<oldArr.length ; j++){
if(oldArr[i]==oldArr[j]){
count++;
break;
}
}
}
//创建一个新的数组
int[] newArr = new int[oldArr.length-count];
int index = 0; //新数组使用的索引值。
//遍历旧数组
for(int i = 0 ; i<oldArr.length ; i++){
boolean flag = false; //该标识是用于标识取出的元素是否存在新数组中。 false默认情况是不存在 的。
int temp = oldArr[i]; //从旧数组 中取出遍历的元素
//遍历新的数组是否存在该数据
for(int j = 0 ; j<newArr.length ; j++){
if(newArr[j]==temp){
flag = true;
break;
}
}
//该元素不存在新数组中,这时候应该存储起来
if(flag==false){
newArr[index++] = temp;
}
}
return newArr;
}
}
例子3.用户输入班级的人数,然后依次输入每个同学的成绩.
输入完毕之后,如果及格率没有达到60%, 就为每一位没有及格的成绩加2分,直到及格率达到60%为止。
import java.util.*;
class Demo10
{
public static void main(String[] args)
{
int[] arr ={98,89,45,59}; //readyData();
double rate = getRate(arr); //得到本班 的及格率
while(true){
if(rate<0.6){
for(int i = 0 ; i<arr.length ; i++){
if(arr[i]<60){
arr[i] = arr[i]+2;
}
}
rate = getRate(arr);//重新计算及格率
}else{
break;
}
}
System.out.println("及格率:"+ rate*100+"% ,数组的元素是:"+ Arrays.toString(arr));
}
//计算及格率
public static double getRate(int[] arr){
double count = 0 ; //定义一个变量记录及格的人数
for(int i = 0 ; i<arr.length ; i++){
if(arr[i]>=60){
count++;
}
}
double rate = count/arr.length; // rate 记录及格率的
return rate;
}
//准备数据
public static int[] readyData(){
Scanner scanner = new Scanner(System.in);
System.out.println("请输入班级的人数:");
int count = scanner.nextInt();
//创建一个数组对象
int[] arr = new int[count];
//录入学生的成绩
for(int i = 0 ; i<count ; i++){
System.out.println("请第"+(i+1)+"位同学的分数:");
arr[i] = scanner.nextInt();
}
return arr;
}
}