第一部分几种简单的排序介绍
1.选择排序
选择排序的思路:假设定义一个数组,数组长度为n 下标是0到n-1
第一步从0到n-1下标中找出最小的数放到0下标的位置
第二步从1到n-1下标中找出最小的数放到1下标的位置
…
…
…
第n-1步 从n-2到n-1下标中找到最小的放到n-2下标位置
这样的话我们就可以排好一个数组
时间复杂度O(n^2)
代码展示:
import java.util.Arrays;
public class t {
public static void main(String[] args) {
int[] arr ={9,3,54,748,6,4,8};
for(int i = 0;i<arr.length;i++){
int mainx = i;
for(int j = i+1;j<arr.length;j++){
if(arr[mainx]>arr[j]){
mainx = j;
}
}
swap(i,mainx,arr);
}
System.out.println(Arrays.toString(arr));
}
public static void swap(int i,int j,int[] q){
int c = q[i];
q[i] = q[j];
q[j] = c;
}
}
2.插入排序
插入排序思路:假设定义一个数组,数组长度为n 下标是0到n-1
第一步将0下标到0下标变为有序、
第二步将0下标到1下标变为有序
第三步将0下标到2下标变为有序
…
…
…
第n步将0下标n-1下标变为有序
时间复杂度O(n^2)
这样这个数组就变成了一个有序数组了,实现代码如下:
import java.util.Arrays;
public class t {
public static void main(String[] args) {
int[] arr ={9,3,54,748,6,4,8,2,3,74,4};
for(int i = 0;i<arr.length-1;i++){
for(int j = i+1;j>0 ;j--){
if(arr[j]<arr[j-1]){
swap(j,j-1,arr);
}else {
break;
}
}
}
System.out.println(Arrays.toString(arr));
}
public static void swap(int i,int j,int[] q){
int c = q[i];
q[i] = q[j];
q[j] = c;
}
}
3.冒泡排序
import java.util.Arrays;
public class t {
public static void main(String[] args) {
int[] arr ={9,3,54,8,2,3,74,4};
for(int i = 0;i<arr.length;i++){
for(int j = 0;j<arr.length-i-1;j++){
if(arr[j]>arr[j+1]){
swap(j,j+1,arr);
}
}
}
System.out.println(Arrays.toString(arr));
}
public static void swap(int i,int j,int[] q){
int c = q[i];
q[i] = q[j];
q[j] = c;
}
}
第二部分:对二分法新的认识
1.二分查找代码实现
二分查找一般情况下使用条件:给定的数组要是一个有序数组
二分查找的实现代码:
import java.util.Arrays;
import java.util.Scanner;
public class t {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int g = scanner.nextInt();//输入要查询的数字
int[] arr = {1,2,3,4,5};
int left = 0;
int ringht = arr.length-1;
int min = left+(ringht-left)/2;
while(left<ringht){
if(arr[min]>g){
ringht = min-1;
min = left+(ringht-left)/2;
}
if(arr[min]<g){
left = min+1;
min = left+(ringht-left)/2;
}
if(arr[min]==g){
break;
}
}
if(arr[min] ==g){
System.out.println("找到了下标为"+min);
}else {
System.out.println("没找到");
}
}
这是我们常见的二分查找,当然使用条件是必须要拥有一个有序的数组
2.通过一个例题来重新认识二分查找
例题大意:给定一个数组长度为n,数组名为arr,找出一个数,这个数是数组的局部最小值
局部最小值定义:如果0下标的数小于1下标的数那么0下标这个数就算一个局部最小值;
如果n(n:数组中最后一个数的下标)下标的数小于n-1下标的数那n下标这个数就算一个局部最小值,设g是大于0小于n的数(g用来表示数组中间一些数的下标)如果满足
arr[g-1]>arr[g]且arr[g+1]>arr[g]那么就说g下标这个数就算一个局部最小值
==================================================================
以上就是题目的大意
那么这道题我们就可以用二分查找来实现
public class t {
public static void main(String[] args) {
int[] arr ={22,12,6,44,88,8,75};
System.out.println(ss(arr));
}
public static int ss(int[] arr){//这个函数返回的是满足要求值的下标
int right = arr.length;
int left = 0;
int mai = left+(right-left)/2;
//判断首个元素是不是局部最小值
if(arr[0]<arr[1]){
return 0;
}
//判断尾元素是不是局部最小值
if(arr[arr.length-1]<arr[arr.length-2]){
return arr.length-1;
}
while (left<=right){
if(arr[mai]<arr[mai+1]&&arr[mai]<arr[mai-1]){
return mai;
}
if(arr[mai]>arr[mai+1]){
left = mai+1;
mai = left+(right-left)/2;
continue;
}
if(arr[mai]<arr[mai+1]){
right = mai-1;
mai = left+(right-left)/2;
continue;
}
}
return -1;
}
}
这个是我用而二分法完成的代码用了少数用例如果有错误希望大家指出
综上可以看出就算给的数组不是有序我们对于某些特定的题也是可以用二分法来解题的
解题思路:
如果给的数组元素很多并且首尾元素都不满足局部最小定义则根据数组各个值得大小可以画出以下曲线图
如图所示我画出了七个有代表性的点,而这些点都有可能是二分法的中间值所获得的点
根据这张图和我上述的代码相信思路就很明显