鸡尾酒排序

鸡尾酒排序这个名字听起来很文艺,其实就是双向冒泡排序,它是冒泡排序的一种变形。冒泡排序是往一个方向冒泡,鸡尾酒排序则是先向一个方向,然后向另一个方向,来回冒泡。

原理

鸡尾酒排序的基本原理也是通过不断交换相邻的两个元素来让小的元素越来越靠前,大的元素越来越靠后。步骤如下:假设有n个元素,

  • 先考虑内层循环。
  1. 比较第一个和第二个元素,若第一个大,则交换,否则不交换;
  2. 比较第二个和第三个元素,若第二个大,则交换,否则不交换;
  3. 比较第三个和第四个元素,若第三个大,则交换,否则不交换;
  4. 以此类推,直到最后一个元素。此时最大的元素会被交换到最后。
  5. 比较第(n-1)个和第(n-2)个元素,若第(n-2)个大,则交换,否则不交换;
  6. 比较第(n-2)个和第(n-3)个元素,若第(n-3)个大,则交换,否则不交换;
  7. 比较第(n-3)个和第(n-4)个元素,若第(n-4)个大,则交换,否则不交换;
  8. 以此类推,直到第一个元素。此时最小的元素会被交换到最前。

这样经过内层循环一遍之后,最大的元素会被交换到最后,同时最小的元素会被交换到最前。

  • 再考虑外层循环。外层循环的每一次,内层循环会走一遍。第一遍的时候内层循环有n个元素,第一遍走完,第二遍的时候就只有(n-2)个元素了,以此类推,直到没有元素。

实现

按照这个原理我们来用代码实现。这时问题又来了:是否可以像冒泡排序一样,也不需要另外开辟空间,直接在原址上排序呢?答案同样是可以。因为只需要两个元素的交换操作,不需要额外的空间。

下面就是用C语言实现的代码。

  • 要排序的数组a有n个元素。
  • 用begin和end来指示内层循环所需进行的范围,冒一次泡,就调整一下下次冒泡范围。
void cocktail_sort(int a[], int n)
{int i,tmp;int begin=0;int end=n-1;while(begin<end) {// swap the largest to the endfor(int i=begin; i<end; i++) {if(a[i]>a[i+1]) {tmp = a[i];a[i]= a[i+1];a[i+1] = tmp;}}end--;// swap the smallest to the beginningfor(int i=end; i>begin; i--) {if(a[i]<a[i-1]) {tmp = a[i];a[i]= a[i-1];a[i-1] = tmp;}}begin++;}
}

为了验证此函数的效果,加上了如下辅助代码,对3个数组进行排序,运行结果在最后,可见排序成功。

#include <stdio.h>
#include <stdlib.h>#define SIZE_ARRAY_1 5
#define SIZE_ARRAY_2 6
#define SIZE_ARRAY_3 20void cocktail_sort(int a[], int n);
void show_array(int a[], int n);void main()
{int array1[SIZE_ARRAY_1]={1,4,2,-9,0};int array2[SIZE_ARRAY_2]={10,5,2,1,9,2};int array3[SIZE_ARRAY_3];for(int i=0; i<SIZE_ARRAY_3; i++) {array3[i] = (int)((40.0*rand())/(RAND_MAX+1.0)-20);}printf("Before sort, ");show_array(array1, SIZE_ARRAY_1);cocktail_sort(array1, SIZE_ARRAY_1);printf("After sort, ");show_array(array1, SIZE_ARRAY_1);printf("Before sort, ");show_array(array2, SIZE_ARRAY_2);cocktail_sort(array2, SIZE_ARRAY_2);printf("After sort, ");show_array(array2, SIZE_ARRAY_2);printf("Before sort, ");show_array(array3, SIZE_ARRAY_3);cocktail_sort(array3, SIZE_ARRAY_3);printf("After sort, ");show_array(array3, SIZE_ARRAY_3);
}void show_array(int a[], int n)
{if(n>0)printf("This array has %d items: ", n);elseprintf("Error: array size should bigger than zero.\n");for(int i=0; i<n; i++) {printf("%d ", a[i]);}printf("\n");
}

运行结果:

Before sort, This array has 5 items: 1 4 2 -9 0
After sort, This array has 5 items: -9 0 1 2 4
Before sort, This array has 6 items: 10 5 2 1 9 2
After sort, This array has 6 items: 1 2 2 5 9 10
Before sort, This array has 20 items: 13 -4 11 11 16 -12 -6 10 -8 2 0 5 -5 0 18 16 5 8 -14 4
After sort, This array has 20 items: -14 -12 -8 -6 -5 -4 0 0 2 4 5 5 8 10 11 11 13 16 16 18

分析

时间复杂度

从代码可见,用了for和while两层循环,且每个循环都是 n 的量级,所以鸡尾酒排序的时间复杂度为 O(n^2)。

空间复杂度

因为鸡尾酒排序直接在原址进行,不需要另外的空间,所以空间复杂度是 O(1)。

排序算法-5-鸡尾酒排序相关推荐

  1. 十大经典排序算法之鸡尾酒排序

    package test;public class 鸡尾酒排序 {//如果左边大于右边则交换void Swap(int a[],int i,int j) {int temp=a[i];a[i]=a[j ...

  2. 鸡尾酒排序算法c语言源代码,排序算法之鸡尾酒排序

    5.3 鸡尾酒排序(Cocktail sort) 既然介绍了冒泡排序.就不得不说一下冒泡排序最为重要的一个变种--鸡尾酒排序(也称为定向冒泡排序).此算法与冒泡排序的不同之处在于鸡尾酒排序是双向进行的 ...

  3. 排序算法之鸡尾酒排序

    鸡尾酒排序 鸡尾酒排序其实冒泡排序的一种变形,或者说改进.又称为涟漪排序.单从鸡尾酒这个名字看不出来到底是如何实现排序. 常见的冒泡排序是始终是按一个方向来进行排序,找到最大或者最小值.而鸡尾酒排序则 ...

  4. 经典排序算法 - 鸽巢排序Pigeonhole sort

    经典排序算法 - 鸽巢排序Pigeonhole sort 原理类似桶排序,同样需要一个很大的鸽巢[桶排序里管这个叫桶,名字无所谓了] 鸽巢其实就是数组啦,数组的索引位置就表示值,该索引位置的值表示出现 ...

  5. 排序---初级排序算法(选择排序、插入排序和希尔排序)

    写在前面的话: 一枚自学Java和算法的工科妹子. 算法学习书目:算法(第四版) Robert Sedgewick 算法视频教程:Coursera  Algorithms Part1&2 本文 ...

  6. 函数模板案例_利用函数模板封装一个排序的函数,可以对不同数据类型数组进行排序 排序规则从大到小,排序算法为选择排序 分别利用char数组和int数组进行测试

    案例描述: 利用函数模板封装一个排序的函数,可以对不同数据类型数组进行排序 排序规则从大到小,排序算法为选择排序 分别利用char数组和int数组进行测试 #include <iostream& ...

  7. 排序算法之计数排序、基数排序和桶排序

    转自:http://www.cnblogs.com/ttltry-air/archive/2012/08/04/2623302.html 计数排序,基数排序,桶排序等非比较排序算法,平均时间复杂度都是 ...

  8. 排序算法 | 直接选择排序,算法的图解、实现、复杂度和稳定性分析

    排序算法 | 直接选择排序,算法的图解.实现.复杂度和稳定性分析 目录 1.直接选择排序的原理 2.图解直接选择排序 3.算法代码实现 4.算法复杂度分析.稳定性分析 直接选择排序 1.直接选择排序的 ...

  9. 排序算法:桶排序、计数排序、基数排序

    相关博客: 排序算法:冒泡排序.插入排序.选择排序.希尔排序 排序算法:归并排序.快速排序 排序算法:桶排序.计数排序.基数排序 排序算法:堆排序 十大排序算法小结 这篇博客将主要介绍三种时间复杂度是 ...

  10. JAVA排序算法之希尔排序

    基本介绍 希尔排序是希尔(Donald Shell)于 1959 年提出的一种排序算法.希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序. 希尔排序法基本思 ...

最新文章

  1. 基础知识——列表简介(二)
  2. PM-Summit 2019全球产品经理大会北京站即将开幕!
  3. C/C++在Android开发中的应用
  4. QT中封装的IP地址的widget
  5. utxo模型_什么是UTXO?简析账户/余额模型和UTXO模型
  6. kvm 调试内核方法
  7. 计算机组成原理 第五章 中央处理器
  8. 智慧城市要让市民有获得感
  9. DRF parser请求流程
  10. 教你玩转HelloWorld
  11. ubuntu14.04安装QQ
  12. 关于软件试用期功能实现-2018.1.24
  13. Map获取key值和value值
  14. 基于haar+adaboost的人脸检测、深度学习的人脸识别技术应用综述
  15. java文件加密解密实验报告_《网络信息安全技术》_实验报告_破译vigenamp#232;re_密码加密的密文...
  16. Google Chart API学习(二)
  17. 【@入口@】伏草惟存,文章精选系列导航
  18. 虚幻引擎图文笔记:调整网格的光照贴图分辨率(Light Map Res)改善光照烘焙质量
  19. Informatic PowerCenter 学习记录
  20. selenium抓取苏宁图书

热门文章

  1. 东南大学和华中科技大学计算机哪个好,中南大学、东南大学、华中科技大学,这三所学校到底哪个好?...
  2. dataframe 赋值
  3. 【OpenCV图像处理】十七、图像的导向滤波
  4. 通用权限管理系统组件 (GPM - General Permissions Manager) 不需要任何配置文件,程序都可以正常运行...
  5. 管理员账户没有系统维护权限处理办法
  6. 小波变换在信号去噪声中的使用
  7. python爬虫之b站视频下载(python学习笔记)
  8. RabbitMQ(Java操作工作队列-按劳分配方式)
  9. 【版本管理】软件项目版本号的命名规则及格式
  10. LeetCode 1155. 掷骰子的N种方法 每日一题