美文网首页
1.1-交换排序-冒泡

1.1-交换排序-冒泡

作者: 梦即是幻 | 来源:发表于2016-08-01 17:09 被阅读38次

参考链接

基本思想

以从小到大排序举例

  1. 从第一个元素开始依次比较数组相邻2个数,直到N-i,如果前面的元素大于后面的元素,就将二个元素交换
  2. �i加1并重复步骤1,这样每次最大的元素就会被放到末尾
  3. 直到最后只剩前2个数做比较
初态 第1趟 第2趟 第3趟 第4趟 第5趟 第6趟 第7趟
 49   38   38   38    38   13   13   13
 38   49   49   49    13   27   27   27 
 65   65   65   13    27   38   38
 97   76   13   27    49   49
 76   13   27   49    49
 13   27   49   65
 27   49   76 
 49   97

算法的实现

// MARK: - 最基本的冒泡排序
extension Array where Element: Comparable {
    mutating func bubbleSort1() {
        /*
         1. 整个排序过程共进行n-1趟
         2. 每次循环,会找出最大的元素,放到末尾
         3. 循环了多少次,末尾就有多少元素已经排好序了,内循环只需遍历前面未排好的元素
         */
        let totalLoop = count - 1
        
        for loopCount in 0 ..< totalLoop {
            //只需遍历前面未排好的元素
            for current in 0 ..< totalLoop - loopCount {
                let next = current + 1
                //比较相邻的2个元素,并把较大的元素往后面放
                if self[current] > self[next] {
                    swap(&self[current], &self[next])
                }
            }
            print(self)
        }
    }
}

冒泡排序算法的改进

定义一个标志性变量exchange,表示某一趟排序过程中是否有数据交换,如果没有,则说明数据已经按要求排列好,可立即结束排序

mutating func bubbleSortBetter1() {
        
        /*
         1. 整个排序过程共最多进行n-1趟,当没有元素交换时,就已经全部排好序了
         2. 每次循环,会找出最大的元素,放到末尾
         3. 循环了多少次,末尾就有多少元素已经排好序了,内循环只需遍历前面未排好的元素
         
         可以相对减少循环总次数
         */
        let totalLoop = count - 1
        for loopCount in 0 ..< totalLoop {
             var sorted = true
            
            for current in 0 ..< totalLoop - loopCount {
                let next = current + 1
                //比较相邻的2个元素,并把较大的元素往后面放
                if self[current] > self[next] {
                    swap(&self[current], &self[next])
                    sorted = false//这次循环进行了数据交换,说明没排好序
                }
            }
            print(self)
            //如果进行某一趟排序时并没有进行数据交换,则说明数据已经按要求排列好,可立即结束排序
            if sorted { break }
        }
    }

再做进一步的优化。如果有100个数的数组,仅前面10个无序,后面90个都已排好序且都大于前面10个数字,那么在第一趟遍历后,最后发生交换的位置必定小于10,且这个位置之后的数据必定已经有序了,记录下这位置,第二次只要从数组头部遍历到这个位置就可以了。

mutating func bubbleSortBetter2() {
        
        /*
         1. unSortedIndex记录每趟排序中最后一次进行交换的位置。
         2. 每次循环,只会对0~unSortedIndex进行比较,并找出最大的元素,放到末尾
         3. 当没有元素交换时,表示已经排好序,所以整个排序过程共最多进行n-1趟
         
         可以在上面基础上再相对减少循环总次数
         */
        var unSortedIndex = count - 1
        var sorted = false
        
        while !sorted {
            //如果进行某一趟排序时并没有进行数据交换,则说明数据已经按要求排列好,可立即结束排序
            sorted = true
            
            //每次循环,只会对0~unSortedIndex进行比较
            for current in 0 ..< unSortedIndex {
                let next = current + 1
                //比较相邻的2个元素,并把较大的元素往后面放
                if self[current] > self[next] {
                    swap(&self[current], &self[next])
                    unSortedIndex = current //记录每趟排序中最后一次进行交换的位置
                    sorted = false
                }
            }
            print(self)
        }
    }

传统冒泡排序中每一趟排序操作只能找到一个最大值或最小值,我们考虑利用在每趟排序中进行正向和反向两遍冒泡的方法一次可以得到两个最终值(最大者和最小者) , 从而使排序趟数几乎减少了一半。

但总次数其实是一样的,有个卵用,不实现了

相关文章

  • 1.1-交换排序-冒泡

    参考链接 交换排序:冒泡排序(Bubble Sort) 白话经典算法系列之一 冒泡排序的三种实现 基本思想 以从小...

  • 排序算法之交换排序

    利用交换数据元素的位置进行排序的方法称为交换排序。常见的交换排序方法有冒泡排序和快速排序。 1. 冒泡排序 1.1...

  • 【数据结构】【C#】019-交换类排序:🌓冒泡排序(稳定)(重要

    交换排序:冒泡排序 ( 相邻比序法 )(稳定) 冒泡排序是一种简单的交换类排序方法,它是通过相邻的数据元素的交换,...

  • 冒泡排序

    冒泡排序,属于内部排序中的交换排序。

  • iOS - 冒泡排序

    Demo_github 冒泡排序 冒泡排序(Bubble Sort)是一种交换排序。两两比较待排序的关键字,并交换...

  • 排序算法

    排序算法 冒泡排序 选择排序 直接插入排序 希尔排序 堆排序 归并排序 快速排序 冒泡排序 冒泡排序是一种交换排序...

  • 排序算法

    冒泡排序(优化) 冒泡排序的概念:冒泡排序是一种交换排序,它的基本思想是:两两比较相邻记录的关键字,如果反序则交换...

  • 交换排序法

    交换排序法是指借助于数据元素之间的相互交换进行排序的一种方法。冒泡排序与快速排序法都属于交换排序法。 冒泡排序法的...

  • 排序算法

    冒泡排序 选择排序 元素交换的方式

  • 11种排序总结

    以下是个人总结的各类排序代码:一:非线性排序(适合大n排序):1.交换-冒泡: 1.交换-冒泡优化版(在之后的排序...

网友评论

      本文标题:1.1-交换排序-冒泡

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