安卓系列之算法知识点:排序算法(一)

180 阅读2分钟

理论知识

「排序算法」对数据进行排序(从小到大,从大到小等)的过程中使用的算法,主要是为了能够节省空间,缩小耗时等目的。
「稳定性」判断条件为相同元素是否会更换位置。

冒泡排序

定义

重复元素列表,然后依次比较两个相邻的元素,如果顺序错误就交换位置,直到没有相邻元素需要交换。

代码

/**
  * 冒泡排序
  * 排序前:[2,5,8,4,1,7,9,3,6]
  * 排序后:[1,2,3,4,5,6,7,8,9]
  */
fun bubbleSort(numArray: IntArray): IntArray {
    for (index in 1 until numArray.size) {
        var flag = true
        for (i in 0 until numArray.size - index) {
            if (numArray[i] > numArray[i + 1]) {
                val temp = numArray[i]
                numArray[i] = numArray[i + 1]
                numArray[i + 1] = temp
                flag = false
            }
        }
        Log.e("bubbleSort===", numArray.contentToString())
        if (flag) break
    }
    return numArray
}

//运行结果
bubbleSort===: [254178369]
bubbleSort===: [241573689]
bubbleSort===: [214536789]
bubbleSort===: [124356789]
bubbleSort===: [123456789]
bubbleSort===: [123456789]

推导过程

冒泡.png

特性

时间复杂度空间复杂度稳定性
O(n^2)O(1)稳定

选择排序

定义

不断从待排的元素列表中选出最小(或最大)的一个元素,放到已顺序排列(从小到大或者从大到小)的列表后面一位,直到全部元素都排列完成。

代码

/**
  * 选择排序
  * 排序前:[2,5,8,4,1,7,9,3,6]
  * 排序后:[1,2,3,4,5,6,7,8,9]
  */
fun selectSort(numArray: IntArray): IntArray {
    for (i in numArray.indices) {
        var minIndex = i
        var j = i + 1
        while (j in numArray.indices) {
            if (numArray[j] < numArray[minIndex]) {
                minIndex = j
            }
            j++
        }
        if (i != minIndex) {
            val temp = numArray[i]
            numArray[i] = numArray[minIndex]
            numArray[minIndex] = temp
        }
        Log.e("selectSort===", numArray.contentToString()+"==="+i)
    }
    return numArray
}

//运行结果
selectSort===: [1, 5, 8, 4, 2, 7, 9, 3, 6]===0
selectSort===: [1, 2, 8, 4, 5, 7, 9, 3, 6]===1
selectSort===: [1, 2, 3, 4, 5, 7, 9, 8, 6]===2
selectSort===: [1, 2, 3, 4, 5, 7, 9, 8, 6]===3
selectSort===: [1, 2, 3, 4, 5, 7, 9, 8, 6]===4
selectSort===: [1, 2, 3, 4, 5, 6, 9, 8, 7]===5
selectSort===: [1, 2, 3, 4, 5, 6, 7, 8, 9]===6
selectSort===: [1, 2, 3, 4, 5, 6, 7, 8, 9]===7
selectSort===: [1, 2, 3, 4, 5, 6, 7, 8, 9]===8

推导过程

选择排序.png

特性

时间复杂度空间复杂度稳定性
O(n^2)O(1)不稳定

插入排序

定义

将待排序元素插入到已排序的有序表中,从而得到一个新的有序表。

代码

/**
  * 插入排序
  * 排序前:[2,5,8,4,1,7,9,3,6]
  * 排序后:[1,2,3,4,5,6,7,8,9]
  */
fun insertSort(numArray: IntArray): IntArray {
    for (i in 1 until numArray.size) {
        val tmpInt = numArray[i]
        var j = i
        while (j > 0 && tmp < numArray[j - 1]) {
            numArray[j] = numArray[j - 1]
            j--
        }
        if (j != i) {
            numArray[j] = tmp
        }
        Log.e("insertSort===", numArray.contentToString() + "===" + i)
    }
    return numArray
}

//运行结果
insertSort===: [2, 5, 8, 4, 1, 7, 9, 3, 6]===1
insertSort===: [2, 5, 8, 4, 1, 7, 9, 3, 6]===2
insertSort===: [2, 4, 5, 8, 1, 7, 9, 3, 6]===3
insertSort===: [1, 2, 4, 5, 8, 7, 9, 3, 6]===4
insertSort===: [1, 2, 4, 5, 7, 8, 9, 3, 6]===5
insertSort===: [1, 2, 4, 5, 7, 8, 9, 3, 6]===6
insertSort===: [1, 2, 3, 4, 5, 7, 8, 9, 6]===7
insertSort===: [1, 2, 3, 4, 5, 6, 7, 8, 9]===8

推导过程

插入排序.png

特性

时间复杂度空间复杂度稳定性
O(n^2)O(1)稳定

归并排序

定义

分治法的思维,将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。

代码

/**
  * 归并排序
  * 排序前:[2,5,8,4,1,7,9,3,6]
  * 排序后:[1,2,3,4,5,6,7,8,9]
  */
fun mergeSort(numArray: IntArray, left: Int, right: Int): IntArray {
    if (left == right) return intArrayOf(numArray[left])

    val mid: Int = left + (right - left) / 2
    //左有序数组
    val leftArr = mergeSort(numArray, left, mid)
    //右有序数组
    val rightArr = mergeSort(numArray, mid + 1, right)
    //新有序数组
    val newNum = IntArray(leftArr.size + rightArr.size)

    var m = 0
    var i = 0
    var j = 0
    while (i < leftArr.size && j < rightArr.size) {
        newNum[m++] = if (leftArr[i] <= rightArr[j]) leftArr[i++] else rightArr[j++]
    }
    while (i < leftArr.size) newNum[m++] = leftArr[i++]
    while (j < rightArr.size) newNum[m++] = rightArr[j++]
    Log.e("mergeSort===", newNum.contentToString())
    return newNum
}

//运行结果
mergeSort===: [25]
mergeSort===: [258]
mergeSort===: [14]
mergeSort===: [12458]
mergeSort===: [79]
mergeSort===: [36]
mergeSort===: [3679]
mergeSort===: [123456789]

推导过程

归并排序.png

特性

时间复杂度空间复杂度稳定性
O(n*log n)O(n)稳定

希尔排序

定义

又名缩小增量排序,把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至 1 时,整个文件恰被分成一组,算法便终止。这里的增量可以理解成步长。

代码

/**
  * 希尔排序
  * 排序前:[2,5,8,4,1,7,9,3,6]
  * 排序后:[1,2,3,4,5,6,7,8,9]
  */
fun shellSort(numArray: IntArray): IntArray {
    var gap = numArray.size / 2
    while (1 <= gap) {
        for (i in gap until numArray.size) {
            var j = i - gap
            val tmp = numArray[i]
            while (j >= 0 && tmp < numArray[j]) {
                numArray[j + gap] = numArray[j]
                j -= gap
            }
            numArray[j + gap] = tmp
        }
        gap /= 2
        Log.e("shellSort===", numArray.contentToString() + "===" + gap)
    }
    return numArray
}

//运行结果
shellSort===: [158327946]===step:4
shellSort===: [132465879]===step:2
shellSort===: [123456789]===step:1

推导过程

希尔排序.png

特性

时间复杂度空间复杂度稳定性
O(n*log n)O(1)不稳定

项目 github 地址

github.com/ElaineTaylo…]

具体写法在项目的 DifferentSort 文件中

若帅哥美女对该系列文章感兴趣,可微信搜索公众号(木子闲集)关注更多更新文章哦,谢谢~