• 数据结构&算法实践—【排序|交换排序】鸡尾酒排序


    转载请注明出处:http://blog.csdn.net/wklken

    回主目录


    排序>>交换排序>>鸡尾酒排序

    List:

    0.概念+伪代码+示例分析

    1.鸡尾酒排序实现

    2.Question


    o start

    基本概念:

    维基百科http://zh.wikipedia.org/wiki/%E9%B8%A1%E5%B0%BE%E9%85%92%E6%8E%92%E5%BA%8F


    伪代码:

    function cocktail_sort(A: list[1..n]){
         for i from 0 to n/2{
             for f from i to (n-i-2){
                 if(A[a] > A[a+1])
                    swap(A[a],A[a+1])
             }
             for b from  (n-i-2) to (i+1){
                  if(A[b] < A[b-1])
                    swap(A[b],A[b-1]
             }
         }
    }

    鸡尾酒排序是冒泡排序的变种——双向冒泡排序

    从伪代码可以看到,每一轮循环,从前到后一次正向冒泡,之后从后往前再进行一次逆向冒泡(每一轮存在两个数被排序)

    可以看到的表现是两边先排序好,逐渐向中间有序

    示例:

    ->[50, 10, 30, 20, 60, 40, 1]   

    -> [10, 30, 20, 50, 40, 1, 60]  第一轮正向

    -> [1, 10, 30, 20, 50, 40, 60]  第一轮逆向

    -> [1, 10, 20, 30, 40, 50, 60]  第二轮正向

    -> [1, 10, 20, 30, 40, 50, 60]  第二轮逆向,无交换,结束  


    详细比较过程:

    [50, 10, 30, 20, 60, 40, 1]

    第一轮     正向
    l->r  cmp 50 10
    change [10, 50, 30, 20, 60, 40, 1]
    l->r  cmp 50 30
    change [10, 30, 50, 20, 60, 40, 1]
    l->r  cmp 50 20
    change [10, 30, 20, 50, 60, 40, 1]
    l->r  cmp 50 60
    l->r  cmp 60 40
    change [10, 30, 20, 50, 40, 60, 1]
    l->r  cmp 60 1
    change [10, 30, 20, 50, 40, 1, 60]

    第一轮    逆向
    r->l  cmp 1 40
    change [10, 30, 20, 50, 1, 40, 60]
    r->l  cmp 1 50
    change [10, 30, 20, 1, 50, 40, 60]
    r->l  cmp 1 20
    change [10, 30, 1, 20, 50, 40, 60]
    r->l  cmp 1 30
    change [10, 1, 30, 20, 50, 40, 60]
    r->l  cmp 1 10
    change [1, 10, 30, 20, 50, 40, 60]


    [1, 10, 30, 20, 50, 40, 60]

    第二轮 正向
    l->r  cmp 10 30
    l->r  cmp 30 20
    change [1, 10, 20, 30, 50, 40, 60]
    l->r  cmp 30 50
    l->r  cmp 50 40
    change [1, 10, 20, 30, 40, 50, 60]

    第二轮 逆向
    r->l  cmp 40 30
    r->l  cmp 30 20
    r->l  cmp 20 10

    [1, 10, 20, 30, 40, 50, 60] (上一轮逆向无交换,结束排序)
    [1, 10, 20, 30, 40, 50, 60]


    本数组共比较18次,而使用带标志冒泡排序需要21次


    1. start

    实现代码

    def cocktail_sort(l):
        size = len(l)
        sign = 1  #用于判断上轮排序是否存在数据交换
        for i in range(size / 2):
            if sign:
                sign = 0
                #正向,冒泡   从   i 到    对称的位置-1
                for j in range(i, size - 1 - i):
                    if l[j] > l[j + 1]:
                        l[j], l[j + 1] = l[j + 1], l[j]
                #逆向,冒泡  从正向排完最大数的前一个开始,到  i
                for k in range(size - 2 - i, i, -1):
                    if l[k] < l[k - 1]:
                        l[k], l[k - 1] = l[k - 1], l[k]
                        sign = 1  #若是逆向存在交换,代表还没排序完成,否则,排序完成
            else:
                break
        print l


    改换成while

    def cocktail_sort2(l):
        size = len(l)
        sign = 1  #用于判断上轮排序是否存在数据交换
        i = 0
        while sign:
           sign = 0
           for j in range(i, size - 1 - i):
               if l[j] > l[j + 1]:
                   l[j], l[j + 1] = l[j + 1], l[j]
           for k in range(size - 2 - i, i, -1):
               if l[k] < l[k - 1]:
                   l[k], l[k - 1] = l[k - 1], l[k]
                   sign = 1  #若是逆向存在交换,代表还没排序完成,否则,排序完成
           i += 1
    

    也可以维护一个bottom和top,每次bottom+1,top-1


    2 start

    A.鸡尾酒排序概念,过程描述?

    B.最差,平均,最优 时间复杂度?

       最差=平均=O(n^2)  最优=O(n)

    C.空间复杂度?

    D.是否是稳定排序?

    E.存在什么方法可以更优化

    F.适用场景,什么情况下最优,什么情况下最差?


    -----------------------------------------  END -------------------------------------------------

    p.s.维基百科的动态排序图很赞&坑爹好几种排序无中文描述,只能啃英文版的百科了,到时候一块贴了



    Meet so Meet. C plusplus I-PLUS....
  • 相关阅读:
    常用开发技巧系列(三)
    快速排序OC、Swift版源码
    一步一步学习SignalR进行实时通信_8_案例2
    一步一步学习SignalR进行实时通信_7_非代理
    一步一步学习SignalR进行实时通信_6_案例
    一步一步学习SignalR进行实时通信_5_Hub
    一步一步学习SignalR进行实时通信_4_Hub
    一步一步学习SignalR进行实时通信_3_通过CORS解决跨域
    一步一步学习SignalR进行实时通信_2_Persistent Connections
    一步一步学习SignalR进行实时通信_1_简单介绍
  • 原文地址:https://www.cnblogs.com/iplus/p/4464643.html
Copyright © 2020-2023  润新知