总结常用几种算法(java)

在这里插入图片描述

冒泡排序

主要思想:是首先将一个一个挨着比较,将最大的放在后面,每一次遍历,都保证最后一个值最大。

public static void bubbleSort(int[] arr){
        //冒泡排序
        int len=arr.length;
        for(int i=1;i<len;i++){
            for(int j=0;j<len-i;j++){
                if(arr[j]>arr[j+1]){
                    swap(arr,j,j+1);
                }
            }
        }
    }

插入排序

主要思想:将未排序的元素,逐个插入到已排序的里面
每次检索下个元素n,前面0到n-1的元素都已排好序,要做的是,将n插入到已排好序的里面
在里插入图片描述

public static void insertSort(int[] array){
        //插入排序
        int i,j,temp;
        for(i=1;i<array.length;i++) {
            temp=array[i];
            for(j=i-1;j>=0;j--) {
                if(temp>array[j]) {
                    break;
                }else {
                    array[j+1]=array[j];
                }
            }
            array[j+1]=temp;
        }

    }

选择排序

主要思想:每次令i为最小值的下标,然后去循环后面元素(因为前面i-1个元素都已排好序),找到剩下元素的最小值下标,拿到了当前i和最小值下标,就进行交换,具有不稳定性。

public static void selectSort(int[] arr){
        //选择排序
        for(int i = 0; i < arr.length-1; i++){
            int min = i;
            for(int j = i+1; j <arr.length;j++){
                if(arr[j]<arr[min]){
                    min = j;
                }
            }
            if(min!=i){
                swap(arr, i, min);
            }
        }
    }

快速排序(分治思想)

主要思想,简单来说就是随意设定一个基础值base,然后小于base的放左边,大于base的放右边,分成的两个部分,也用同样思想,都取出一个新的base,小的放左边,大的放右边,最后放下去,就会排好序了。
其中关键点,给一个数组进行快排,都使用双游标left和right,左++,右–,遍历完所有元素,使其可以小的放左,大的放右,具体实现回顾,参考代码,自己手写,每次回顾一定快速记住。

public static void quikSort(int[] arr,int left,int right){
        //快速排序(分治思想)
        if(right<=left)return;
        int k=part(arr,left,right);
        quikSort(arr,left,k-1);
        quikSort(arr,k+1,right);
    }

private static int part(int[] arr, int left, int right) {

        int base=arr[left];
        while (left<right){
            //右边开始
            for(;arr[right]>base&&right>left;right--);
            if(right>left){
                arr[left]=arr[right];
                left++;
            }
            //左边
            for(;arr[left]<base&&right>left;left++);
            if(left<right){
                arr[right]=arr[left];
                right--;
            }

        }
        arr[left]=base;
        return left;
    }

归并排序

主要思想,是一直一直一分为二,直到分不开的时候,开始合并,每次合并都借助于一个新的数组temp,来存放合并且排好序的,然后将temp赋值给元素组其中合并的那一段,然后一段一段的赋上去,排序成功。
代码主要理解在于,合并的时候,其实数组a并没有拆开,只是理解上它被一分为二,然后使用(low,mid)(mid+1,high)将其分为两段来理解,然后设定双游标为i=low和j=mid+1;让他俩去取a中的元素做比较,然后赋值给Temp,就合并好一小段,总的来看,就成功了(理解理解!!)

在这里插入图片描述

public static int[] sort(int[] a,int low,int high){
        int mid = (low+high)/2;
        if(low<high){
            sort(a,low,mid);
            sort(a,mid+1,high);
            //左右归并
            merge(a,low,mid,high);
        }
        return a;
    }
     
    public static void merge(int[] a, int low, int mid, int high) {
        int[] temp = new int[high-low+1];
        int i= low;
        int j = mid+1;
        int k=0;
        // 把较小的数先移到新数组中
        while(i<=mid && j<=high){
            if(a[i]<a[j]){
                temp[k++] = a[i++];
            }else{
                temp[k++] = a[j++];
            }
        }
        // 把左边剩余的数移入数组 
        while(i<=mid){
            temp[k++] = a[i++];
        }
        // 把右边边剩余的数移入数组
        while(j<=high){
            temp[k++] = a[j++];
        }
        // 把新数组中的数覆盖nums数组
        for(int x=0;x<temp.length;x++){
            a[x+low] = temp[x];
        }
    }

堆排序

在这里插入图片描述
主要思想,首先弄懂二叉树基本定义
parent(i)=(i-1)/2
left_child(i)=2i+1
right_child(i)=2
i+1;理解不到这三条就不用看了
可以推导出性质:
最后一个叶子节点(没有子节点叫叶子节点)的索引为arr.length-1 。
最后一个非叶子节点索引为 (arr.lenght-1-1)/2
先看算法动画:
http://www.cs.usfca.edu/~galles/visualization/HeapSort.html
剩下算法参考:
https://blog.csdn.net/nrsc272420199/article/details/82559912
写的十分详细,简单易理解。
总的来说无非三点:
1.构造二叉树,由数组构成大根堆(父节点大于左右两个子节点),又叫做heapify
2.树的头节点就是最大数,将这个堆顶的数和堆底(最后一位)交换位置
3.重复步骤,一步一步将当前最大值从右往左排列出来
难点,大根堆原理和算法实现,参考上面引用博客吧,写的太好了。

猜你喜欢

转载自blog.csdn.net/weixin_43722571/article/details/99566034