常见的查找和排序算法
一、三大查找算法
1、顺序查找
public static boolean shunxu(int[] array,int target){
if(array.length==0)return false;
for (int i = 0; i < array.length; i++) {
if(array[i]==target) return true;
}
return false;
}
2、折半查找
非递归
public static boolean zheban(int[] array,int target) {
int low = 0,high = array.length-1;
while(low <= high) {
int mid = (low + high)/2;
if(array[mid] == target) return true;
else if(array[mid] < target) low = mid + 1;
else high = mid -1 ;
}
return false;
}
递归
public static int zhebanSort(int[] array,int low,int high,int target){
//判断异常情况
if(array.length<=0) return -1;
if(low>high) return -1;
//计算数组mid值然后递归
int mid = (low+high)/2;
if(array[mid] == target) return mid;
else if(array[mid] > target) return zhebanSort(array,low,mid-1,target);
else return zhebanSort(array,mid+1,high,target);
}
3、哈希查询
public static void main(String[] arsg) {
int[] array = new int[]{1,2,3,4,5};
List<Integer> list = new ArrayList<>();
for (int i = 0; i < array.length; i++) list.add(array[i]);
boolean b = list.contains(0);
System.out.println(b);
}
二、七大排序算法
1、SelectionSort 选择算法(最小值升上来)
public static void SelectionSort(int[] array) {
for(int i=0;i<array.length-1;i++) { //每次选择最小值升上来i的位置,前面n-1个升上来,意味着最后一个不用升了,所以array.length-1要减1
int min = i; //min变量保存该趟比较过程中,最小元素所对应的索引
for(int j=i;j< array.length-1;j++) { //趟比较,将该元素与其后的元素逐个比较
if (array[j] < array[min]) min = j; //如果后面的元素小,将后面元素的索引极为最小值的索引
}
int temp = array[i]; //交换i与最小值
array[i] = array[min];
array[min] = temp;
}
}
2、BubbleSort 冒泡算法(最大值沉下去)
public static void BubbleSort(int[] array) {
for(int i=0;i< array.length-1;i++) { //外层循环控制 排序趟数
for(int j=0;j< array.length-1-i;j++) { //内层循环控制 交换次数 (PS:array.length-1-i是因为已经排好的最大值不需要比较了)
if(array[j] > array[j+1]) {
int temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
}
3、InsertSort插入排序
public static void insertSort(int[] array) {
//插入排序的假设是第一个元素已经排好序,从因此从i=1开始
for (int i = 1; i < array.length; i++) {
int insertNode = array[i]; //insertNode为要插入的结点
int j = i - 1; //从前面已经排好序的序列遍历
while(j>=0 && insertNode < array[j]){ //找到比insertNode小的结点,然后插入到他后面
array[j+1] = array[j]; //所有比insertNode大的结点,全部往后移
j--;
}
array[j+1] = insertNode; //当上面循环结束之后j是比insertNode小的结点,因此要把insertNode插入到他的后面
}
}
4、QuickSort 快速排序
public static void qsort(int[] a, int l, int r) {
if (l < r) { //注意这个条件很容易出错
int temp = quicksort(a, l, r); //拿到基准值
qsort(a, l, temp - 1); //再递归遍历基准值左边
qsort(a, temp + 1, r); //再递归遍历基准值右边
}
}
public static int quicksort(int[] a, int l, int r) {
int temp = a[l]; //temp为上面存放的基准值
while (l < r) {
while (l < r && a[r] > temp) r--; //找到右边比基准值小的索引
if (l < r) a[l++] = a[r]; //这里后面不需要++,注意了
while (l < r && a[l] <= temp) l++; //找到左边比基准值小的索引
if (l < r) a[r--] = a[l]; //这里后面不需要++,注意了
}
a[l] = temp; //当循环结束,说明左右指针相等,指向中间的值,把基准值插入到最中间
return l; //返回基准值的索引
}
5、归并排序
public static void mergeSort(int[] array, int left, int right, int[] temp) {
if (left < right) { // 记得这个判断条件啊,很容器异常
int mid = (left + right) / 2;
mergeSort(array, left, mid, temp); //向左递归分解
mergeSort(array, mid + 1, right, temp); //向右递归分界
merge(array, left, mid, right, temp); //合并
}
}
public static void merge(int[] array, int left, int mid, int right, int[] temp) {
int i = left; //左边有序序列的初始索引
int j = mid + 1; //右边有序序列的初始索引
int t = 0; //指向temp数组的当前索引
while (i <= mid && j <= right) {
if (array[i] > array[j]) {
temp[t++] = array[j++];
} else {
temp[t++] = array[i++];
}
}
//把有剩余数据的一边的数据全部依次填充到temp中
while (i <= mid) temp[t++] = array[i++];
while (j <= right) temp[t++] = array[j++];
//将temp数组中的数据拷贝到arr数组中去
t = 0;
int temp_left = left;
while (temp_left <= right) { //这里记得加=号,不然容易起出错
array[temp_left++] = temp[t++];
}
}
6、桶排序
public class bucketSort {
public static void main(String[] args) {
int[] array = new int[]{1, 1, 0, 0, 213, 123, 23, 2312312, -11232, -23};
tongSort(array);
System.out.println(Arrays.toString(array));
}
public static void tongSort(int[] array) {
//找到数组中最小值和最大值
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for (int i = 0; i < array.length; i++) {
min = Math.min(min, array[i]);
max = Math.max(max, array[i]);
}
//新建桶,并把数组中放入桶中
int[] tongArray = new int[max - min + 1];
for (int i = 0; i < array.length; i++) {
tongArray[array[i] - min]++;
}
//把桶中元素取出来
int k = 0;
for (int i = 0; i < tongArray.length; i++) {
while (tongArray[i] > 0) {
array[k++] = i + min; //注意这里是要把减去的min偏移量加回来
tongArray[i]--;
}
}
}
}
7、堆排序
https://blog.csdn.net/TaylorSwiftiiln/article/details/119865970
public static void heapSort(int[] array) {
//调整成大顶堆,即从最后一个非叶子结点开始,交换它与比它大的子结点
for (int i = array.length / 2 - 1; i >= 0; i--) {
adjustHeap(array, i, array.length);
}
//交换堆顶和末尾元素的值,交换后调整成大顶堆
for (int i = array.length - 1; i > 0; i--) {
int temp = array[0];
array[0] = array[i];
array[i] = temp;
adjustHeap(array, 0, i);
}
}
public static void adjustHeap(int[] array, int index, int length) {
//记录当前元素
int temp = array[index];
//i是index的左子节点2,i = i * 2 + 1是一直从左子节点的路径往下找
for (int i = index * 2 + 1; i < length; i = i * 2 + 1) {
//如果右节点比左节点大,则指针指向右节点
if (i + 1 < length &&array[i+1] > array[i]) {
i++;
}
//如果遇到比当前节点大,就让当前节点等于大的值
if(array[i]>temp) {
array[index] = array[i];
index = i;
}else {
break;
}
}
//让最后的末尾元素等于一开始的当前节点
array[index] = temp;
}