美文网首页
排序(持续更新)

排序(持续更新)

作者: ZYiDa | 来源:发表于2019-11-22 16:49 被阅读0次

本文的图片来源于冰狼爱魔


一、简单选择排序

1、思路

假设有x个数需要排序

1、将第n个数与[n+1,x)范围内的数进行循环比较和交换,当n>n+1对应的数时,交换两个数;
2、重复1中的过程,直至这x个数循环结束,即n = x-1,此时得到升序排序的结果。

2、实现
/**
 * 选择排序--简单选择排序
 * */
val disorder:ArrayList<Int> = arrayListOf(-3,3,1,-1,2,0,7,0,5)
fun SelecteionSort(){
    for (i in 0 until disorder.size){//循环1
        var minValue = disorder[i]
        for (j in (i+1) until disorder.size){//循环2
            var value = disorder[j]
            if (minValue > value){//交换值
                val tmp = minValue
                minValue = value
                disorder[j] = tmp
            }
        }
        disorder[i] = minValue
    }
    print("排序结果:${disorder.toString()}")
}

fun main(args:Array<String>){
    print("排序耗时:${CodeRunTime {
        SelecteionSort()
    }} ms \n")
    print("排序结果:$disorder \n")
}
排序耗时:3 ms
排序结果:[-3, -1, 0, 0, 1, 2, 3, 5, 7] 
3、时间和空间复杂度

时间复杂度:O(n^2)
空间复杂度:O(1)


二、直接插入排序

1、思路

1、将currentcurrent-1比较,如果current-1>current,将current-1往后移动一个位置;
2、同时将current索引往前移动一个位置,继续开始1中的比较;
3、重复1-2中的过程,直至current达到数据开始端结束循环,将最初的currentValue插入到现在的位置;
4、循环1-3中的过程,直至current到达排序数据顶端,排序完成。

2、实现
/**
 * 直接插入排序
 * 必须满足至少有两个元素
 * */
private val disorderList:ArrayList<Int> = arrayListOf(1,6,3,5,7,6,2,1,4,9,0,-1,-3)

fun InsertSort(disorder: ArrayList<Int>){
    if (disorder.size < 2){
        return
    }
    for (i in 1 until disorder.size){
        var current = i
        val currentValue = disorder[current]
        //1、将current与current-1比较,如果current-1>current,将current-1往后移动一个位置
        //2、同时将current索引往前移动一个位置,继续开始1中的比较
        while (current >= 1 && disorder[current - 1] > currentValue){
            disorder[current] = disorder[current - 1]
            current -= 1
        }
        //3、重复1-2中的过程,直至current达到数据开始端结束循环,将最初的currentValue插入到现在的位置
        disorder[current] = currentValue
    }
    print("**$disorder**\n")
}
**[-3, -1, 0, 1, 1, 2, 3, 4, 5, 6, 6, 7, 9]**

Process finished with exit code 0
3、时间和空间复杂度

时间复杂度:O(n^2)
空间复杂度:O(1)


三、冒泡排序

1、思路

一共有x个数据需要排序

1、将ii+1进行比较,如果i>i+1,则交换位置;
2、重复1中的过程,直至到达数据顶端;
3、从i+1开始,重复1-2中的过程,直至到达数据顶端,即i到达x-1的位置,结束循环。此时既是以升序方式排序的结果。

图片来自
2、实现
/**
 * 冒泡排序
 * 循环1控制着每次循环的起点
 * 循环2控制着每次循环的终点
 * */
fun BubbleSort(disorder: ArrayList<Int>){
    for (i in 0 until disorder.size-1){//循环1
        for (j in 0 until disorder.size-i-1){//循环2
            if (disorder[j+1] < disorder[j]){
                val tmp = disorder[j]
                disorder[j] = disorder[j+1]
                disorder[j+1] = tmp
            }
        }
    }
    print("**$disorder**\n")
}
**[-3, -1, 0, 1, 1, 2, 3, 4, 5, 6, 6, 7, 9]**

Process finished with exit code 0
3、时间和空间复杂度

时间复杂度:O(n^2)
空间复杂度:O(1)


四、快速排序

1、思路

1、在数组中选择一个基准数pivot,一般选择第一个数作为pivot
2、将数组中大于基准数的,移动到基准数右边;小于基准数的,移动到基准数左边;
3、对基准数两边的数组子集分别重复1-2中的过程,直至每个新的数组子集中只含有一个元素。

快速排序采取“分治”的思想。分治就是将无序数组按照需求分割成若干子集进行操作,然后合并递归是实现分治的重要方式。

2、实现

private val disorder:ArrayList<Int> = arrayListOf(-3,3,1,-1,2,0,7,0,5)


/**
 * @param left 数据集从左开始查找的索引标记
 * @param right 数据集从右往左开始查找的索引标记
 * @param dataSource left和right要查找的数据集,也是排序的数据集
 * */
fun QuickSort(left:Int,right:Int,dataSource:ArrayList<Int>){
    //当left == right时表明最后需要排序的数据子集中只含有一个元素,就不用继续循环排序了
    //当left < right时表明数据集中还有需要移动的数据
    //所以,选择 left > right 这个作为递归出口
//    print("Left:$left -- Right:$right \n")
    if (left <= right){
        val pivotKey = partition(left, right, dataSource)
        QuickSort(left,pivotKey-1,dataSource)
        QuickSort(pivotKey+1,right, dataSource)
    }else{
        return
    }
}

/**
 * @description 分割排序数组并进行移动
 * @param left 数据集从左开始查找的索引标记
 * @param right 数据集从右往左开始查找的索引标记
 * @param dataSource 需要进行二分--分割的数据集
 * @return 下一次排序的基准数对应的索引
 * */
private fun partition(left:Int,right:Int,dataSource:ArrayList<Int>):Int{
    //左哨兵
    var left = left
    //右哨兵
    var right = right
    //基准值 标杆值
    val pivotValue = dataSource[left]

    //当left和right还没有相遇
    while (left != right){
        //先移动right,当dataSource[right] >= pivotValue时,略过,继续移动
        while (left < right && dataSource[right] >= pivotValue){
            right -= 1
        }
        //当dataSource[right] < pivotValue时,将此时right对应的值移动到此时left的位置
        dataSource[left] = dataSource[right]

        //接着开始移动left,当dataSource[left]<pivotValue时,略过,继续移动
        while (left < right && dataSource[left] < pivotValue){
            left += 1
        }
        //当dataSource[left]>=pivotValue时,将此时此时left对应的值移动到right的位置
        dataSource[right] = dataSource[left]
    }

    //此时left和right相遇,完成一次循环,将基准值移动到对应位置
    dataSource[left] = pivotValue
    return left
}

fun main(args:Array<String>){
    print("运行时间:${CodeRunTime {
        QuickSort(0, disorder.size-1, disorder)
    }} ms \n")
    print("排序后的结果:$disorder \n")
}
排序耗时:1 
排序结果:[-3, -1, 0, 0, 1, 2, 3, 5, 7]

暂时这么多,后续会补充其它的,以及对上面几个算法的手绘图解。

相关文章

网友评论

      本文标题:排序(持续更新)

      本文链接:https://www.haomeiwen.com/subject/ajqqwctx.html