用Java代码实现算法
排序算法
简单排序
冒泡排序
原理:
- 比较相邻元素,如果前一个元素大于后一个元素,则交换位置,
- 对每一对元素进行相同的动作,从开始的第一对到结尾的最后一对,最终最后的位置就是最大值
具体代码
import java.util.Arrays;
public class Test3 {
public static void main(String[] args){
//冒泡排序法
int[] arr = {99,20,40,64,79,29,4};
for(int i=0; i<arr.length-1; i++) { //arr.length-1趟
for(int j=0; j<arr.length-1-i; j++) {
if(arr[j] > arr[j+1]) {
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
System.out.print(Arrays.toString(arr));
}
}
选择排序
原理:每一趟都拿第一个元素和所有的元素比较,将最小值的索引赋值为一个变量,在每趟结束后,将每趟的第一个元素和最小值所在的元素进行交换。
具体代码
import java.util.Arrays;
public class Test4 {
public static void main(String[] args){
int[] arr = {99,20,40,64,79,29,4};
//选择排序
for(int i=0; i<arr.length-1; i++) {
int min = i;
for(int j=i+1; j<arr.length;j++) {
if(arr[min] > arr[j]) {
min = j;
}
}
int temp = arr[min];
arr[min] = arr[i];
arr[i] = temp;
}
System.out.print(Arrays.toString(arr));
}
}
插入排序
原理:
- 将排序元素元素分为有序和无序两组
- 每一次都在无序列表中找到第一个元素倒序对有序列表元素依次进行比较
* 如果在有序列表中找到小于这个无序列表的元素的元素时,继续往前比较,如果该元素比有序列表的最小值还小,那么将其插入到有序列表的以一个元素中
* 如果在有序列表中找到大于这个无序列表的元素的元素时,将该无序列表元素插入到该有序列表元素的后面
具体代码
import java.util.Arrays;
public class Test5 {
public static void main(String[] args){
int[] arr = {99,20,40,64,79,29,4};
//插入排序
for(int i=0; i<arr.length-1 ; i++) {
int insertPositionIndex = -1; //要插入的索引位置
int eleIndex = i+1; //要插入的元素的索引位置
int ele = arr[i+1]; //要插入的元素(无序列表的第一个元素)
//寻找插入的位置
for(int j=eleIndex-1; j>=0; j--) {
if(ele > arr[j]) {
//大于插入到有序列表的后面
insertPositionIndex = j+1;
break;
}
//小于有序列表的最小值时,插入到有序列表的最前面
if(j == 0) {
insertPositionIndex=0;
break;
}
}
//位移(start:要插入索引处的位置,end:是元素索引位置)
for (int j=eleIndex; j>insertPositionIndex; j--) {
if(j==0){break;}
arr[j] = arr[j-1];
}
//插入
arr[insertPositionIndex] = ele;
}
System.out.print(Arrays.toString(arr));
}
}
高级排序
希尔排序
归并排序
快速排序
查找算法
普通查找
即将目标元素和数组/集合中的元素一一比较查找,效率极低
二分查找法
- 前提:建立在排序的基础上
- 原理:每次都会在数组中间的查找,如果目标元素 > 中间元素,会把中间元素的后一个元素作为左边边界;如果目标元素 < 中间元素,那么会把中间元素的前一个作为右边边界;重复上面的操作直到找到或找不到(左边边界索引值 > 右边边界索引值时)为止
import java.util.Arrays;
import java.util.Scanner;
public class Test2 {
//二分查找法
public static int binarySearch(int[] arr,int ele) {
//二分查找法,要求查找内容是有序的
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
int left = 0;
int right = arr.length-1;
//数组边界判断
if (ele > arr[right] || ele < arr[left]) {
return -1;
}
while(left <= right) {
int middle = (left + right)/2;
if(ele > arr[middle]) {
//找右边
left = middle+1;
}
else if(ele < arr[middle]) {
//找左边
right = middle-1;
}
else
return middle;
}
return -1;
}
public static void main(String[] args){
Scanner s = new Scanner(System.in);
System.out.print("请输入要查找的数字:");
int num = s.nextInt();
int[] arr = {99,20,40,64,79,29,4};
System.out.println("下标是:" + binarySearch(arr,num));
}
}
排序的稳定性
课后作业
员工管理系统——用数组存储员工,完成对员工的CRUD(增删改查)操作
import java.util.Scanner;
import java.util.Arrays;
public class ManageSystem {
public static void main(String[] args){
System.out.println("欢迎使用员工管理系统!");
Scanner sc = new Scanner(System.in);
int[] nos = new int[2]; //用于存放员工号
String[] names = new String[2]; //用于存放员工姓名
int empNo = 1000; //员工编号
int empSum = 0; //员工人数
boolean isAdd = false; //是否继续添加
while(true) {
System.out.println("请选择功能:1.添加员工 2.查询员工 3.修改员工 4.删除员工");
int flag = sc.nextInt();
switch (flag) {
case 1:
//添加
isAdd = true;
while(isAdd) {
System.out.print("请输入员工姓名:");
String name = sc.next();
//超出扩容,一次扩容2个单位
if(empSum >= nos.length) {
int[] new_nos = new int[nos.length + 2];
String[] new_names = new String[names.length + 2];
for(int i=0; i<nos.length; i++) {
new_nos[i] = nos[i];
new_names[i] = names[i];
}
nos = new_nos;
names = new_names;
}
//赋值并更新
nos[empSum] = ++empNo;
names[empSum++] = name;
System.out.println("你已添加成功!");
System.out.println("是否继续添加?(true/false):");
isAdd = sc.nextBoolean();
}
break;
case 2:{
/*
要求根据工号查询
*/
boolean isFindAll = false;
System.out.print("查询所有员工true;查询单个员工false:");
isFindAll = sc.nextBoolean();
if(isFindAll) {
//查询所有员工
if(names[0] == null) {System.out.println("没有任何员工"); break;}
for(int i=0; i<nos.length; i++) {
System.out.println("员工编号:" + nos[i] + "\t员工姓名:" + names[i]);
}
} else {
System.out.print("请输入你想查询的员工工号:");
int in_empNo = sc.nextInt();
boolean isFound = false;
for (int i=0 ;i<nos.length ; i++) {
if(in_empNo == nos[i]) {
System.out.println("员工编号:" + nos[i] + "\t员工姓名:" + names[i]);
isFound = true;
break;
}
}
System.out.print(isFound ? "" : "未找到该员工\n");
}
break;
}
case 3:{
//修改
System.out.print("请输入你想修改的员工工号:");
int in_empNo = sc.nextInt();
boolean isFound = false;
for (int i=0 ;i<nos.length ; i++) {
if(in_empNo == nos[i]) {
//显示原有信息
System.out.println("员工编号:" + nos[i] + "\t员工姓名:" + names[i]);
isFound = true;
System.out.print("请输入新名字:");
String new_name = sc.next();
//更新新名字
names[i] = new_name;
System.out.println("修改成功!修改结果如下");
System.out.println("员工编号:" + nos[i] + "\t员工姓名:" + names[i]);
break;
}
}
System.out.print(isFound ? "" : "员工号有误\n");
break;
}
case 4: {
//删除
System.out.print("请输入你想删除的员工工号:");
int in_empNo = sc.nextInt();
boolean isFound = false;
for (int i=0 ;i<nos.length ; i++) {
if(in_empNo == nos[i]) {
//显示原有信息
System.out.println("员工编号:" + nos[i] + "\t员工姓名:" + names[i]);
isFound = true;
System.out.print("是否确认删除该员工?(true/false):");
boolean isDel = sc.nextBoolean();
if(isDel) {//删除
for(int j=i; j<nos.length; j++){
if(j == nos.length-1) {
nos[j] = 0;
names[j] = null;
break;
}
//位移
nos[j] = nos[j+1];
names[j] = names[j+1];
}
//更新员工数量
empSum--;
System.out.println("删除成功!");
} else {
System.out.println("已取消删除操作!");
}
break;
}
System.out.print(isFound ? "" : "你要删除的员工并不存在!\n");
}
}
break;
default:
System.out.println("无效数值,请重新选择");
break;
}
}
}
}
通过上面的代码可以看出此处有很多功能是被重复编写的,代码冗余并且不够清晰明了,在后续学习过程中,会使用方法对此程序的功能进行封装。