目录
插值查找:基于二分查找,将mid值=(key-a[min])/(a[max]-a[min])*(max-min),比二分查找更加快速
1.基本查找
import java.util.ArrayList;
/*
* 基本查找
* 遍历数组一个一个找
* */
public class basicSearch {
public static void main(String[] args) {
int[] arr = {1,84,8,64,8,748,1321,};
System.out.println(basicSearch(arr, 8));
}
public static ArrayList<Integer> basicSearch(int[] arr , int num){
ArrayList<Integer> index = new ArrayList<>();
for (int i = 0; i < arr.length; i++) {
if(arr[i] == num){
index.add(i);
}
}
return index;
}
}
2.二分查找
/*
* 二分查找(适用于已经排好序的数据)
* 定义一个min一个max分别记录arr的最小索引和最大索引,定义一个mid记录max+min/2,即min和max的中间值
* 用找的值与mid所对应的值去比较
* 如果大于mid对应的值,则所找的数据在mid的右边,min=mid+1,max不变
* 如果小于mid对应的值,则找的数据在mid左边,max=mid-1,min不变
* 一直这样循环下去直到mid对应的值与所找的值相等,则视为找到数据
* 如果min的值大于了max,则这个数据集合中没有所找的数据
* */
public class binarySearch {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5,8,9,10};
System.out.println(binarySearch(arr, 3));
}
public static int binarySearch(int[] arr , int nums){
//定义一个min值记录数组的最小索引
int min = 0;
//定义一个max值记录数组的最大值
int max = arr.length-1;
while(true){
//如果min大于max则数组中没有nums的值
if(min > max){
return -1;
}
//定义一个mid值记录min和max的中间值
int mid = (max+min)/2;
//如果mid所对应的值大于nums,则说明nums的值在mid左边
if(arr[mid] > nums){
//max向mid左边移动,移动到mid-1的位置
max = mid - 1;
}
//如果mid所对应的值小于nums,则说明nums的值在mid右边
else if(arr[mid] < nums){
//min向mid右边移动,移动到mid+1的位置
min = mid + 1;
}
//如果mid == nums 则找到这个值
else {
return mid;
}
}
}
}
插值查找:基于二分查找,将mid值=(key-a[min])/(a[max]-a[min])*(max-min),比二分查找更加快速
3.分块查找
/*
* 分块查找:用于有如下规律的数据
* int[] arr ={16,5,9,12,21,18,32,23,37,26,45,34,50,48,61,52,73,66};
* 在这个数组中,可以将数据分成几块,每一块都要一个最大值,这个最大值比自己后一块的每一个值都要小
* 这样这个数组就可以分成:
* 【16,5,9,12,21,18】
* 【32,23,37,26,45,34】
* 【50,48,61,52,73,66】
* 三个小块,然后将要找的数据去和每一个小块的最大值去比较
* 如果比这个块的最大值小,就说明这个数据在这个块中
* 然后在获取这个块的开始索引和结束索引,遍历这个块里的数据
* 比较块里的数据是否与要找的数据相同
*
*/
public class blockSearch {
public static void main(String[] args) {
//将数据分块
// int[] arr ={16,5,9,12,
// 21,18,
// 32,23, 37,26,45,34,
// 50,48,61,52,73,66};
//分完块之后
int[] arr ={16,5,9,12,21,18,
32,23, 37,26,45,34,
50,48,61,52,73,66};
int num = 16;
//之后创建块对象
numsBlock block1 = new numsBlock(0,21,5);
numsBlock block2 = new numsBlock(6,45,11);
numsBlock block3 = new numsBlock(12,73,17);
//将块添加到数组中存储起来
numsBlock[] blocks = {block1,block2,block3};
//确定要找的数据在那个块中
int indexBlocks = getIndexBlocks(blocks, num);
//找到索引之后获取该块的对象,并遍历数组
for(int i = blocks[indexBlocks].getStartIndex();i <= blocks[indexBlocks].getEndIndex();i++){
if(num == arr[i]){
System.out.println(i);
return;
}
}
System.out.println("没有找到");
}
//创建一个方法用于获取要找的数据在那个块中
public static int getIndexBlocks(numsBlock[] blocks,int num){
//遍历块中将num与每个块中的最大值比较,如果比最大值小说明在这个块中
for (int i = 0; i < blocks.length; i++) {
if(num < blocks[i].getMax()){
return i;
}
}
return -1;
}
}
class numsBlock{
//创建一个类记录每个块的开始索引,结束索引,块里的最大值
private int startIndex;
private int max;
private int endIndex;
public numsBlock() {
}
public numsBlock(int startIndex, int max, int endIndex) {
this.startIndex = startIndex;
this.max = max;
this.endIndex = endIndex;
}
public int getStartIndex() {
return startIndex;
}
public void setStartIndex(int startIndex) {
this.startIndex = startIndex;
}
public int getMax() {
return max;
}
public void setMax(int max) {
this.max = max;
}
public int getEndIndex() {
return endIndex;
}
public void setEndIndex(int endIndex) {
this.endIndex = endIndex;
}
}
4.冒泡排序
/*
* 冒泡排序:
* 相邻两数进行比较,即第i位与i+1位数进行比较,i所对应的数比i+1大则两数互换位置
* 比如
* {3,5,2,1,4}
* 3和5比,3比5小,不换位置,然后5和2比,5比2大,换位置,数组变为{3,2,5,1,4}
* 依次这样比下去,有n个数,就比n-1次
* 比完之后,最后一位数一定最大
* 下一次比较的时候就不用比这个数了,即只需要比n-1-1次了
* 这样的比较一共要比n-1轮
* 所以可以嵌套循环,外层循坏i表示比较的轮数n-1,内层循坏j表示比较的次数n-1-i
*
* */
public class bubbleSort {
public static void main(String[] args) {
int [] arr = {3,5,2,1,4};
//外层循坏表示循环轮数
for (int i = 0; i < arr.length-1; i++) {
//内层循坏表示循坏的次数,每进行一轮比较,比较的次数就-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;
}
}
}
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
5.插入排序
/*
* 插入排序
* */
public class insertSort {
public static void main(String[] args) {
int[] arr = {3,44,38,5,47,15,36,26,89,12,65,98,6,4,8};
//定义一个开始索引表示从那个索引开始是无序的
int startIndex = -1;
//遍历数组,判断从那个索引开始是无序的
for (int i = 0; i < arr.length-1; i++) {
if(arr[i] > arr[i+1]){
startIndex = i+1;
break;
}
}
//得到开始索引之后,用开始索引之后的数据跟开始索引之前的数据进行从右到左的比较
//取出开始无序的数组
for (int i = startIndex; i < arr.length; i++) {
//定义一个数用于存储进行插入的那个数的索引,避免直接对索引进行操作造成顺序混乱
int j = i;
//定义一个循环表示要插入的那个数去和有序数组进行比较,从有序数组右边开始依次比较,比它左边的值小就交换位置
while(j > 0&&arr[j] < arr[j-1]){
int temp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = temp;
//交换位置完毕之后,索引变为交换位置处的索引,即前一位的索引,再进行下一次循环
j--;
}
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
}
}
图解:![](https://img-blog.csdnimg.cn/44b89d3d62c541bc863c33c8e0788f1b.jpeg)
6.快速排序
/*
*快速排序:运用递归
* */
public class quickSort {
public static void main(String[] args) {
int[] arr = {6,1,2,7,9,3,4,5,10,8};
quickSort(arr,0, arr.length-1);
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
}
public static void quickSort(int[] arr , int s, int e){
int start = s;
int end = e;
if(start > end)return;
int baseData = arr[s];
while(start != end){
//end从后到前找比基准数小的,找到之后停在那个数那里
while(true){
if(start >= end||arr[end] < baseData)
break;
end--;
}
//start从前到后找比基准数大的,找到之后停在那个数那里
while(true){
if(end <= start||arr[start] > baseData){
break;
}
start++;
}
//然后end和start对应的数据交换位置
int temp = arr[end];
arr[end] = arr[start];
arr[start] = temp;
}
//基准数据归位,保证前边的数据比它小,后边的数据比它大
int temp = arr[s];
arr[s] = arr[start];
arr[start] = temp;
//运用递归
//将基准数据左边的进行排序
quickSort(arr,s,start-1);
//将基本数据右边的进行排序
quickSort(arr,start+1,e);
}
}