数组常见算法

news2024/11/15 17:47:31

一、数组排序

冒泡排序

        本篇我们介绍最基本的排序方法:冒泡排序。

实现步骤

1、比较两个相邻元素,如果第一个比第二个大,就交换位置

2、对每一对相邻元素进行同样的操作,除了最后一个元素

特点

每一轮循环后都会把最大的一个数交换到末尾,因此下一轮就可以忽略最后的数。

总共比较n-1轮,每轮比较n-1-i次

代码实现

//无序数组
int[] number1= {8,9,7,4,3};
//int[] number1= {1,2,3,4,6};//有序数组 比较次数为:4
System.out.println("排序前"+Arrays.toString(number1));
int count=0;
for(int i=0;n=number1.length();i++){
    boolean isSorted=true;
    for(int k=0;k<n-1-i;k++){
        count++;
        //如果发生元素的交换则代表源数组无序
        if(number1[k]>number1[k+1]){
            number1[k]=number1[k]^number1[k+1];
            number1[k+1]=number1[k]^number1[k+1];    
            number1[k]=number1[k]^number1[k+1];
            isSorted=false;
        }
    }
    //若没有发生元素的交换则说明数组已经有序,则跳出循环,但至少比较一次
    if(isSorted){
        break;
    }
}
System.out.println("比较次数为:"+count);
System.out.println("排序后"+Arrays.toString(number1));

输出结果:

排序前[8, 9, 7, 4, 3]
比较次数为:10
排序后[3, 4, 7, 8, 9] 

 使用Arrays工具类排序

        实际上,Java的标准库已经内置了排序功能,我们只需要调用Arrays.sort()方法就可以实现快速排序:

int ns={3,6,1,8,2,9};
//排序前
System.out.println("排序前:"Arrays.toString(ns));
//排序
ns.sort();
//排序后
System.out.println("排序后:"Arrays.toString(ns));

输出结果:

排序前:[3,6,1,8,2,9]

 排序后:[1,2,3,6,8,9]

二、无序数组查找

        在一个无序数组中,如果需要进行指定元素的查找,可以通过循环遍历或Arrays工具类两种方式进行查找。

遍历查找

        我们可以通过对无序数组进行遍历,将数组中的每一个元素与目标元素进行比较,从而确定该数组中是否包含该目标数组:

整型数组

int[] array= {2,3,1,56,72,19,2,5,1};
int index=-1;
//查找元素第一次出现的位置
try(Scanner input=new Scanner(System.in)){
    System.out.println("请输入要查找的元素");
    int target=input.nextInt();
    //案例1:查找在无序数组中目标元素第一次出现的位置
    for(int i=0;i<array.length;i++){
        if(array[i]==target){
            index=i;
            System.out.println("%d第一次出现的位置是%d",target,index);
            break;
        }
    }
    System.out.println();
    index=-1;
    //案例2:查找在无序数组中目标元素最后一次出现的位置
    for(int i=array.length-1;i>=0;i--){
        if(array[i]==target) {
			index=i;
            System.out.printf("%d最后一次出现的位置是%d",target,index);
			break;
		 }
    }

输出:请输入要查找的元素
输入:1

输出:
1第一次出现的位置是2
1最后一次出现的位置是8

字符串数组

String[] singerArray = { "李荣浩", "盘尼西林", "王菲", "王贰浪", "鹿先森乐            
                    队","孙燕姿", "G.E.M.邓紫棋", "方大同", "品冠儿子" };
	int count=0;
	int index=-1;
	System.out.println("请输入你要查找的歌手:");
	try(Scanner input=new Scanner(System.in)){
		String target=input.next();
		for(int i=0;i<singerArray.length;i++) {
			count++;
			//String字符串的等值比较,必须用equals方法
			if(singerArray[i].equals(target)) {
				index=i;
				break;
			}	
		}
	System.out.printf("%s的位置在%d,查找了%d次",target,index,count);
	}

输出:请输入你要查找的歌手:
输入:孙燕姿
输出:孙燕姿的位置在5,查找了6次 

双指针遍历查找--字符串数组

String[] singerArray = { "李荣浩", "盘尼西林", "王菲", "王贰浪", "鹿先森乐        
                    队","孙燕姿", "G.E.M.邓紫棋", "方大同", "品冠儿子" };
int count=0;
int index=-1;
try(Scanner input=new Scanner(System.in)){
	System.out.println("请输入你要查找的歌手:");
	String target=input.next();	
    for(int i=0,k=singerArray.length-1;i<=k;i++,k--) {
        count++;
        //从头开始比较
        if(singerArray[i].equals(target)){
            index=i;
            break;
        }
        //从尾部开始比较
        if(singerArray[k].equals(target)){
            index=k;
            break;
        }
    }
System.out.printf("%s的位置在%d,查找了%d次",target,index,count);
}

 输出:请输入你要查找的歌手:
输入:孙燕姿
 输出:孙燕姿的位置在5,查找了4次

双指针的查找次数少,效率更高

三、有序数组查找

二分查找

作用

        在一个有序数组中,如果需要进行指定元素的查找,可以采用二分查找(binarySearch),这样会比通过遍历数组来进行查找的效率高很多。以下是二分查找的代码实现:

int[] num={1,3,5,7,8};
int target=3;
int index=-1;
//数组的首元素和尾元素
int low=0,high=num.length-1;

while(low<=high){
    int mid=(low+high)/2;
    //判断mid是否等于target
    if(num[mid]==target){
        index=mid;//如果等于代表查找成功,则循环退出
        break;
    }else if(num[mid]>target){//此时代表目标元素可能在mid的左半区
        hight=mid-1;
    }else if(num[mid]<target){//此时代表目标元素可能在mid的右半区
        low=mid+1;
    }
}
System.out.printf("%d的位置为%d",target,index);

输出结果:3的位置为1 

Arrays工具类查找

        在Java的标准库中也为我们内置了二分查找,可以直接通过调用Arrays.binarySearch()的方法进行查找:由于该方法基于二分查找,所以进行排序的数组必须是有序的,所以我们可以先使用Arrays.sort()进行排序,再调用Arrays.binarySearch()进行查找

int[] array={28,12,89,73};
int target=12;
//先排序
Arrays.sort(array);
//在查找
int index=Arrays.binarySearch(array,target);

System.out.println("%s的位置在%d",target,index)

输出结果:12的位置在1  

四、数组乱序

算法简述

         题目:将一个数组中所有元素的顺序都打乱。

        那不是直接用Math.random()*100重复50次不就好了吗?不,Math.random()的重复概率很大,不能保证50个数字每个都不同,所以我们为大家介绍一种算法:乱序算法

实现步骤

①假设有一个等待乱序的数组P

②从P中随机选取一个未乱序的元素

③将该元素与数组P中最后一个元素交换

④重复2、3两个步骤直到数组P中所有元素全部完成排序

代码实现

int[] number= {11,12,13,14,15,16,17};
System.out.println("乱序前:"+Arrays.toString(number));
for(int i=number.length-1;i>0;i--){
    //产生随机下标
    int randomIndex=(int)(Math.random()*i);
    //交换元素
    number[i]=number[i]^number[randomindex];
	number[randomindex]=number[i]^number[randomindex];
	number[i]=number[i]^number[randomindex];
}
System.out.println("乱序后:"+Arrays.toString(number));
    

输出结果:

乱序前:[11, 12, 13, 14, 15, 16, 17]
乱序后:[12, 16, 17, 15, 11, 13, 14]

应用

题目:产生7个不重复的1-33的数字

int[] num=new int[33];
for(int i=0;i<num.length;i++){
    num[i]=i+1;
}
System.out.println("乱序前:"+Arrays.toString(number));
//先乱序
for(int i=num.length;i>0;i--){
    int randindex=(int)(Math.random()*i);
    num[i]=num[randindex]^num[i];
    num[randindex]=num[randindex]^num[i];
    num[i]=num[randindex]^num[i];
}
//存前7个
int[] n=new int[7];
System.arraycopy(num,0,n,0,n.length);
System.out.println("乱序后:"+Arrays.toString(number));

输出结果:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33]
[21, 12, 8, 26, 16, 5, 25]
 

五、数组旋转

算法描述

数组向右旋转3位:将尾元素通过不断旋转,交换到头部

数组向左旋转三位:将头元素通过不断旋转,交换到尾部

 

代码实现 

向右旋转

//遍历的顺序:从尾部开始
//交换的双方:k和k-1

int[] number= {1,2,3,4,5,6,7};
//向右旋转3次
//外层循环控制旋转次数,向右旋转3次
for(int i=0;i<3;i++){
    //内层循环控制旋转方向,每次向右旋转一位
    //遍历的顺序:从尾部开始
    //交换的双方:k和k-1
    for(int k=number.length;k>0;k--){
        number[k]=number[k]^number[k-1];
		number[k-1]=number[k]^number[k-1];
		number[k]=number[k]^number[k-1];
    }
}
System.out.println("向右旋转3次:"+Arrays.toString(number));

 输出结果:向右旋转3次:[5, 6, 7, 1, 2, 3, 4]

向左旋转

//遍历的顺序:从头部开始
//交换的双方:k和k+1

int[] number= {1,2,3,4,5,6,7};
//外层循环控制旋转次数,向左旋转3次
for(int i=0;i<3;i++) {
//内层循环控制旋转方向,每次向左旋转一位
    for(int k=0;k<number.length-1;k++){
        number[k]=number[k]^number[k+1];
		number[k+1]=number[k]^number[k+1];
		number[k]=number[k]^number[k+1];  
    }
}
System.out.println("向左旋转3次:"+Arrays.toString(number));      

输出结果:向左旋转3次:[4, 5, 6, 7, 1, 2, 3]

写作不易,如果帮到了你就点赞收藏吧!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1491112.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java基础概念 1-6注释关键字字面量变量-基本用法变量-使用方式和注意事项变量练习-计算公交车的人数

Java基础概念 1-注释 单行注释 // 多行注释 /* */ 文档注释 /** */ --暂时不用 例: public class HelloWorld{ //main方法,表示程序的主入口.public static void main (String[] args){/*输出语句(打印语句)会把小括号内的内容进行输出打印.*/System.out.…

网盘拉新平台,如何授权对接“星子助推”?

找到“星子助推”&#xff1a;首先&#xff0c;找到“星子助推”这个授权渠道。他们是网盘服务提供商的合作伙伴&#xff0c;为你提供机会。注册并申请授权&#xff1a;在“星子助推”的平台上注册&#xff0c;并同时申请授权。填写邀请码8x25k&#xff0c;提交申请。获得授权并…

怎么写苹果群控核心功能的源代码!

随着移动设备的普及和技术的不断发展&#xff0c;苹果设备群控技术成为了许多开发者关注的焦点&#xff0c;苹果群控技术允许开发者通过编写源代码&#xff0c;实现对多台苹果设备的集中管理和控制。 一、了解苹果群控技术的基本原理 在编写苹果群控核心功能的源代码之前&…

如何使用生成式人工智能探索视频博客的魅力?

视频博客&#xff0c;尤其是关于旅游的视频博客&#xff0c;为观众提供了一种全新的探索世界的方式。通过图像和声音的结合&#xff0c;观众可以身临其境地体验到旅行的乐趣和发现的喜悦。而对于内容创作者来说&#xff0c;旅游视频博客不仅能分享他们的旅行故事&#xff0c;还…

Qt绘制动态罗盘

介绍&#xff1a;罗盘指针以30角旋转巡逻&#xff0c;扫描航海范围内的点位&#xff0c;并绘制点云。字段信息在表格中显示&#xff0c;该数据都存储在数据库中。选择不同的范围&#xff0c;显示该范围内的点位。 #include "mainwindow.h" #include "ui_mainwi…

自建Redis蜜罐以捕获和分析潜在攻击

一、引言 随着网络攻击的日益频繁和复杂&#xff0c;传统的防御措施往往难以应对。蜜罐作为一种主动防御技术&#xff0c;通过模拟有价值的服务来吸引攻击者&#xff0c;从而收集和分析攻击数据&#xff0c;提高网络安全性。本文将介绍如何自建一个Redis蜜罐&#xff0c;以捕获…

会员管理系统怎么更加有效触达会员?

如何更有效地触达会员&#xff0c;提高他们的满意度和忠诚度&#xff0c;是许多企业面临的挑战。以下是博阳会员管理系统建议的一些可以帮助企业更有效触达会员的方法。 首先&#xff0c;精准定位是触达会员的关键 企业需要深入了解他们的会员是谁&#xff0c;他们的需求是什么…

学习javascript,前端知识精讲,助力你轻松掌握

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;前端泛海 景天的主页&#xff1a;景天科技苑 文章目录 1.JavaScript 简介2.js中,一切皆是对象3.js的引入方式4.js的变量以及…

3Dmax最全快捷键大全,赶紧收藏起来练习起来吧

3Dmax做为一款专业的建模软件&#xff0c;有很多快捷键能帮助我们更好地学习&#xff0c;提升自己的能力。 废话不多说&#xff0c;我们一起来看看。 以上就是3dmax最全快捷键大全&#xff0c;看着容易&#xff0c;但是想要掌握好还需要我们多多练习。 本地max跑图太慢的朋友可…

python水表识别图像识别深度学习 CNN

python水表识别&#xff0c;图像识别深度学习 CNN&#xff0c;Opencv,Keras 重点&#xff1a;项目和文档是本人近期原创所作&#xff01;程序可以将水表图片里面的数据进行深度学习&#xff0c;提取相关信息训练&#xff0c;lw1.3万字重复15%&#xff0c;可以直接上交那种&…

打通易快报与金蝶K3Wise,实现采购流程高效协同!

一、客户介绍 某三维科技有限公司&#xff0c;作为业内知名的科技创新型企业&#xff0c;专注于高端三维科技产品的研发、生产与销售。随着企业规模的扩大和业务的不断增长&#xff0c;公司对于采购流程的高效管理和协同需求日益凸显。为了实现采购流程的自动化和智能化&#…

自动驾驶轨迹规划之碰撞检测(四)

欢迎大家关注我的B站&#xff1a; 偷吃薯片的Zheng同学的个人空间-偷吃薯片的Zheng同学个人主页-哔哩哔哩视频 (bilibili.com) 目录 1.基于圆覆盖 2.BVH 自动驾驶轨迹规划之碰撞检测&#xff08;一&#xff09;-CSDN博客 自动驾驶轨迹规划之碰撞检测&#xff08;二&#x…

MySQL——性能调优

性能调优&#xff08;重要&#xff09; SQL 优化的目的 减少磁盘 IO&#xff1a;尽可能避免全表扫描、尽量使用索引、尽量使用覆盖索引减少回表操作减少 CPU 和内存的消耗&#xff0c;尽可能减少排序、分组、去重之类的操作&#xff0c;尽量减少事务持有锁的时间 优化途径&…

在三个el-form-item中的el-radio的值中取一个发送给后端怎么获取

问: 请问,这段代码怎么获取:无策略,策略1,策略2的值? 回答: 问: 三个里面只可以选中一个吗? 回答:

SpringCloud-数据认证加密总结

一、数据加密认证介绍 在当今分布式系统的日益复杂和信息传递的广泛网络化环境中&#xff0c;确保通信的安全性至关重要。数据的加密和认证作为保障信息传递安全的关键手段&#xff0c;在分布式系统中扮演着不可或缺的角色。Spring Cloud&#xff0c;作为一套构建微服务架构的…

【LeetCode每日一题】1976. 到达目的地的方案数

文章目录 [1976. 到达目的地的方案数](https://leetcode.cn/problems/number-of-ways-to-arrive-at-destination/)思路&#xff1a;代码&#xff1a; 1976. 到达目的地的方案数 思路&#xff1a; 利用 Dijkstra 算法计算最短路径&#xff0c;并同时记录最短路径的数量&#xf…

双指针的一些题目

题目1&#xff1a;统计子矩阵 4405. 统计子矩阵 - AcWing题库 解题 前缀和暴力枚举x1、y1、x2、y2的做法是O()的&#xff0c;考虑用双指针进行优化。 优化的方式是&#xff1a;我们将每一列在[x1,x2]范围内的部分看作一个整体&#xff0c;用指针维护左右边界。 当当前矩阵的…

直播预告|从一张 CD 说起,关于播放器的前世今生

1877 年&#xff0c;天才发明家爱迪生研发出了人类历史上第一台可以录音和放音的装置&#xff0c;被称为“话筒”。 当时&#xff0c;这台机器使用一张薄薄的铁箔盘来录制声音&#xff0c;爱迪生亲手转动铁箔盘&#xff0c;在上面刻下声音的波纹。不过这个设计并不太实用&…

python中的defaultdict

collections.defaultdict 是 collections 模块提供的一个有用的类&#xff0c;它是内置字典类 dict 的一个子类。与普通字典一样&#xff0c;可以进行元素的访问、添加、删除等操作。区别在于当访问一个不存在的键时&#xff0c;defaultdict 会返回默认值&#xff0c;而不会引发…

ArcGIS学习(十二)ModelBuilder参数化建模

ArcGIS学习(十二)ModelBuilder参数化建模 1.ModelBuilder应用基础 本任务给大家带来的是ArcGIS中一个非常有意思也很重要的模块一-ModelBuilder。ModelBuilder有什么用呢? 大家设想一下这些场景: 你在做一项复杂研究,使用到ArcGIS中的多个工具和步骤,包括缓冲区分析、空…