常用算法

66 阅读2分钟

1.冒泡排序

原理:比较相邻元素,将最大的元素交换到右边。时间复杂度为O(n^2)。

fun test() {
    bubbleSort(intArrayOf(12,3,54,67,87,98,9,67,45,34))
}

private fun bubbleSort(array: IntArray){
    for (i in 0 until array.size-1){
        for (j in 0 until array.size-1-i){
            if (array[j]>array[j+1]){
                var temp=array[j]
                array[j]=array[j+1]
                array[j+1]=temp
            }
        }
    }
    Log.e("测试", "test: ================${Gson().toJson(array)}")
}

2.快速排序

原理:用数组的第一个数作为基准数据,然后将所有比它小的数都放到它左边,所有比它大的数都放到它右边,这个过程称为一趟快速排序。值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。时间复杂度为O(nlogn)。

fun test() {
    var arr= intArrayOf(4,7,6,5,3,2,8,1)
    quickSort(arr,0,7);
    Log.e("测试", "test: ================${Gson().toJson(arr)}")
}

fun quickSort(arr: IntArray,startIndex:Int,endIndex:Int){
    //递归结束条件为startIndex大于或等于endIndex
    if(startIndex>=endIndex){
        return;
    }
    //得到基准元素位置
    var pIndex=partition(arr,startIndex,endIndex);
    //根据基准元素分两部分进行递归排序
    quickSort(arr,startIndex,pIndex-1);
    quickSort(arr,pIndex+1,endIndex);
}

fun partition(arr: IntArray,startIndex:Int,endIndex:Int):Int{
    var p=arr[startIndex];//基准元素(可取随机位置)
    var l=startIndex//左指针
    var r=endIndex//右指针
    while(l!=r){
        //控制右指针向左移动,找到小于基准元素的那个数
        while((l<r)&&(arr[r]>p)){
            r--;
        }
        //控制左指针向右移动,找到大于基准元素的那个数
        while((l<r)&&(arr[l]<=p)){
            l++;
        }
        //交换l指针和r指针所指的元素
        if(l<r){
            var tmp=arr[l];
            arr[l]=arr[r];
            arr[r]=tmp;
        }
    }
    //交换基准元素和重合点的元素
    arr[startIndex]=arr[l];
    arr[l]=p;
    return l;
}

3.选择排序

原理:遍历元素找到一个最小(或最大)的元素,把它放在第一个位置,然后再在剩余元素中找到最小(或最大)的元素,把它放在第二个位置,依次下去,完成排序。时间复杂度为O(n^2)。

fun test() {
    selectSort(intArrayOf(12, 3, 54, 67, 87, 98, 9, 67, 45, 34))
}

private fun selectSort(array: IntArray) {
    for (i in 0 until array.size - 1) {
        //用来记录最小值的索引位置,默认为i
        var minIndex = i
        for (j in i + 1 until array.size) {
            if (array[j] < array[minIndex]){
                minIndex=j// 遍历 i+1~length 的值,找到其中最小值的位置
            }
        }
        // 交换当前索引 i 和最小值索引 minIndex 两处的值
        if (i!=minIndex){
            var temp=array[i]
            array[i]=array[minIndex]
            array[minIndex]=temp
        }
        // 执行完一次循环,当前索引 i 处的值为最小值,直到循环结束即可完成排序
    }
    Log.e("测试", "test: ================${Gson().toJson(array)}")
}

4.插入排序

原理:将未排序的元素插入到已排序序列的正确位置。时间复杂度为O(n^2)。

fun test() {
    var arr= intArrayOf(4,7,6,5,3,2,8,1)
    insertionSort(arr)
}

fun insertionSort(array: IntArray){
    var n=array.size
    for (i in 1 until n){
        var key=array[i]
        var j=i-1
        while (j>=0&&array[j]>key){
            array[j+1]=array[j]
            j--
        }
        array[j+1]=key
    }
    Log.e("测试", "test: ================${Gson().toJson(array)}")
}

5.二分法查找

原理:在有序序列中查找目标元素,每次查找都将序列缩小一半。时间复杂度为O(logn)。

fun test(){
    Log.e("ceshi", "test: ===============${binarySearch(intArrayOf(1, 3, 5, 6, 7,12, 54),7)}")
}

fun binarySearch(nums: IntArray,target:Int):Int{
    var left=0
    var right=nums.size-1
    var mid=(left+right).shr(1)
    while (left<=right){
        if (target<=nums[mid]){
            right=mid-1
        }else{
            left=mid+1
        }
        mid=(left+right).shr(1)
    }
    return left
}