3

java之基础算法精选

 1 year ago
source link: https://blog.51cto.com/JavaArchitect/5580699
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

我们上一篇和大家聊了java基础之数组,今天和大家聊一下java基础之算法,我们会讲到排序,递归等常用的算法, 并且每个知识点都会配上我自己敲的代码演示截图,和完整代码,希望能帮到更多兄弟,在java历险中我们一同前行。

java之基础算法精选_二分查找

算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制。也就是说,能够对一定规范的输入,在有限时间内获得所要求的输出。

如果一个算法有缺陷,或不适合于某个问题,执行这个算法将不会解决这个问题。不同的算法可能用不同的时间、空间或效率来完成同样的任务。

算法中的指令描述的是一个计算,当其运行时能从一个初始状态和(可能为空的)初始输入开始,经过一系列有限而清晰定义的状态,最终产生输出并停止于一个终态。一个状态到另一个状态的转移不一定是确定的。随机化算法在内的一些算法,包含了一些随机输入。

二.知识点介绍

1、水仙花数

3、排序(插入、冒泡、选择)

5、经典问题

三.知识详解

1、水仙花数

(1)水仙花数是一个三位数100-999

(2)取出个位、十位、百位

(3)个位的立方+十位的立方+百位立方==原来这个数,这就是水仙花数

代码演示:

package com.Test;

public class Main{

private final static String name = "磊哥的java历险记-@51博客";
public static void main(String args[]){
for(int n=100;n<=999;n++){
int a=n%10;//取个位
int b=n/10%10;//取十位
int c=n/100;//取百位
if(a*a*a+b*b*b+c*c*c==n){
System.out.println(n+ "为水仙花数!");
System.out.println("============="+name+"=============");
}
}
}
}
java之基础算法精选_冒泡_02

2、1949-2018年中的闰年

(1)找出 1949-2018年之间的闰年

(2)能被4整除且不能被100整除

(3)能被400整除

代码演示:

package com.Test;

public class Main{

private final static String name = "磊哥的java历险记-@51博客";

public static void main(String args[]){
for(int year=1949;year<=2018;year++){
//当年份能被4并且不能被100整除,或者能被400整除时,为闫年
if(year%4==0&&year%100!=0||year%400==0){
System.out.println(year+"为闰年!");
}
}
System.out.println("============="+name+"=============");
}
}
java之基础算法精选_冒泡_03

3.1、选择排序

java之基础算法精选_冒泡_04

(1)初始化我们的数组,int n[]={26,53,48};

(2)第1次执行循环,找出下标从0开始,后面数组中最小的值,与我们的下标为0的位置交换。

(3)第2次执行循环,找出下标从1开始,后面数组中最小的值,与我们的下标为1的位置交换。

(4)第3次执行循环,找出下标从2开始,后面数组中最小的值,与我们的下标为2的位置交换。

(5)以此内推,到循环结束。

代码演示:
package com.Test;

public class Main{

private final static String name = "磊哥的java历险记-@51博客";
/*
选择排序
选出最小元素和第1个元素-N个元素交换。
*/
public static void main(String args[]){
int n[]={26,53,48,11,13,48,32,15};
for(int i=0;i<n.length;i++){
//最小值
int min=n[i];
//最小值的下标
int k=i;
for(int j=i;j<n.length;j++){
//找出最小值,并记住下标
if(n[j]<min){
min=n[j];
k=j;
}
}
//交换值
n[k]=n[i];
n[i]=min;
}
//增强for,显示数组里面的值
for(int m:n){
System.out.println(m+" ");
}
System.out.println("============="+name+"=============");
}

}
java之基础算法精选_递归_05

3.2、插入排序

java之基础算法精选_代码_06

(1)初始化我们的数组:int n[]={26,53,48};

(2)第1次执行循环,找出下标为1开始,保存这个数,保存好的数与他前面的数进行比较 ,如果前面的数比他大,那么前面的数后移,保存好的数放在后移的数的位置,如果不比他大,位置不变

(3)第2次执行循环,找出下标为2开始,保存这个数,保存好的数与他前面的数进行比较 ,如果前面的数比他大,那么前面的数后移,继续比较前面的数,如果不比他大,就将保存好的数放在后移这个数位置,如果比他大,就后移,将保存的数放在第一个位置

(4)以此内推,到循环结束

代码演示:
package com.Test;

/*
插入排序
右移,插入
*/
public class Main{

private final static String name = "磊哥的java历险记-@51博客";
public static void main(String args[]){
int n[]={26,53,48,11,13,48,32,15};
int i=1;
while(i<n.length){
//要插入的值
int k=n[i];
//下标
int j=i;
while(j>0&&k<n[j-1]){
//满足条件的数,右移
n[j]=n[j-1];
j--;
}
//插入数据到指定位置
n[j]=k;
i++;
}
for(int m:n){
System.out.println(m+" ");

}
System.out.println("============="+name+"=============");
}

}
java之基础算法精选_二分查找_07

3.3、冒泡排序

java之基础算法精选_冒泡_08

(1)初始化我们的数组, int n[]={26,53,48};

(2)第1次执行循环,如果第一个数比第二个数大,交换位置,继续和第三个数比较,如果还大,继续交换,如果第四个数比,第三个数大,那么位置不变,以第四个数继续和后面的数比较 ,至到最大的数跑到最后。

(3)以此内推,到循环结束

代码演示:
package com.Test;

/*
冒泡排序:
遇到小的就交换,将最大的数放到最后
*/
public class Main{

private final static String name = "磊哥的java历险记-@51博客";

public static void main(String args[]){

int n[]={26,53,48,11,13,48,32,15};

for(int j=n.length-1;j>=0;j--){
for(int i=0,t=0;i<j;i++){
if(n[i]>n[i+1]){//满足条件交换数据
t=n[i];n[i]=n[i+1];n[i+1]=t;
}
}
}

for(int m:n){
System.out.println(m+" ");

}
System.out.println("============="+name+"=============");
}
}
java之基础算法精选_代码_09

4、递归算法

递归概念:

是指在定义自身的同时又出现了对自身的引用。如果一个算法直接或间接的调用了自己,则称之为递归算法。

java之基础算法精选_递归_10

代码演示:

package com.Test;


/**
* 求5的阶乘? 5*4*3*2*1 = ?
*/
public class Main{

private final static String name = "磊哥的java历险记-@51博客";

//定义int number 接受参数
public static int test(int number){
//当条件满足时,返回1,否则,反复调用自身
if(number == 1){
return 1;
}else{
//反复调用自身
return number * test(number - 1);
}
}
public static void main(String[] args) {
//调用上面的test方法,传入参数 5
System.out.println(test(5));
System.out.println("============="+name+"=============");
}
}
java之基础算法精选_代码_11

如案例:当我们的number不为1的时候,我们反复的去调用test(number),当为1时,返回1;

5、经典问题

5.1正整数分解质因数

将一个正整数分解质因数。例如:输入90,打印出90=233*5。  1.程序分析:对n进行分解质因数,应先找到一个最小的质数i,然后按下述步骤完成:  

(1)如果这个质数恰等于n,则说明分解质因数的过程已经结束,打印出即可。

(2)如果n > i,但n能被i整除,则应打印出i的值,并用n除以i的商,作为新的正整数你,重复执行第一步。

(3)如果n不能被i整除,则用i+1作为i的值,重复执行第一步。

代码演示:

package com.Test;

import java.util.Scanner;
public class Main {

private final static String name = "磊哥的java历险记-@51博客";
//分解方法
public void fenjie(int n) {
for (int i = 2; i <= n; i++) {
if (n % i == 0) {
System.out.print(i);
if(n!=i){//分解完后打印*
System.out.print("*");
}
fenjie(n/i);//改变值后,调用本身
}
}
System.out.println("============="+name+"=============");
System.exit(0); //退出程序

}
//调用分解方法
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("请输入N的值:");
int N = in.nextInt();
System.out.print( "分解质因数:" + N +"=");

new Main().fenjie(N);

}
}
java之基础算法精选_代码_12

5.2最大公约数和最小公倍数

输入两个正整数m和n,求其最大公约数和最小公倍数。 程序分析:利用辗除法。

代码示例:  

package com.Test;

import java.util.Scanner;
public class Main {

private final static String name = "磊哥的java历险记-@51博客";

public static void main(String[] args){
//定义四个变量
int a,b,m,n;
Scanner in=new Scanner(System.in);
System.out.println("请输入一个正整数:");
a=in.nextInt();
System.out.println("再输入一个正整数:");
b=in.nextInt();
commonDivisor use=new commonDivisor();
//调用commonDivisor方法,传入参数a,b
m=use.commonDivisor(a,b);
n=a*b/m;
System.out.println("最大公约数:"+m);
System.out.println("最小公倍数:"+n);
System.out.println("============="+name+"=============");
}
}
class commonDivisor{
public int commonDivisor(int x,int y){
//x小于y,交换二个值
if(x<y){
int t=x;
x=y;
y=t;
}
while(y!=0){
if(x==y){
return x;
//x不等于y,取x与y的余数
}else{
int k=x%y;
//y赋值给x
x=y;
//k赋值给y
y=k;
}
}
return x;
}
}
java之基础算法精选_java_13
java之基础算法精选_递归_14

5.4、二分查找(扩展) 

       对于二分查找算法要求, 查找前的数据必须是已经排好序的, 然后得到数组的开始位置start和结束位置end, 取中间位置mid的数据a[mid]跟待查找数据key进行比较, 若 a[mid] > key, 则取end = mid - 1;

若 a[mid] < key, 则取start = mid + 1; 若 a[mid] = key 则直接返回当前mid为查找到的位置. 依次遍历直到找到数据或者最终没有该条数据. 啰嗦这么多, 上代码!!!

代码示例:

package com.Test;

//二分查找算法
public class Main {

private final static String name = "磊哥的java历险记-@51博客";

//已经排好序的数组
public static int binarySearch(int[] nums, int key) {
int start = 0;
int end = nums.length - 1;
int mid = -1;
while (start <= end) {
mid = (start + end) / 2;
if (nums[mid] == key) {
return mid;//已经查到返回!
} else if (nums[mid] > key) {
end = mid - 1;
} else if (nums[mid] < key) {
start = mid + 1;
}
}
return -1;
}
public static void main(String[] args) {
//定义一组传入数组nums
int[] nums = {1,2,3,4,5};
//定义传入参数k
int k = 5;
//调用上面的binarySearch方法,传入参数nums数组和 key
System.out.println(binarySearch(nums,k));
System.out.println("============="+name+"=============");
}

}
java之基础算法精选_二分查找_15
java之基础算法精选_冒泡_16

基础算法就暂时说到这里,感兴趣的兄弟,可以去看看别的算法玩法,算法的价值也很大,特别是算法功底比较好的大神,年薪都是百万起步,虽然我的算法不是特别好,但是日常开发中还是会用到,多少得研究研究,对于初学的朋友们可以根据自己的实际情况,动手跟着上面的演示代码敲一敲,先掌握基础的算法,再循序渐进,一步一步走。 

希望我的文章对各位兄弟有帮助,感谢大家持续关注!!!

java之基础算法精选_递归_17

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK