只有一重循环的排序——侏儒排序(Gnome Sort)
侏儒排序:从头(i=0)开始遍历元素,如果当前元素比前一个元素大(array[i]>array[i-1]),就把它跟前一个元素互换(Swap(a[i],a[i-1]))并继续检查它(i--),否则检查下一个元素(i++)。当i=length时结束排序。
该排序的神奇之处是只有一重循环,而且代码简单。但是一重循环不代表时间复杂度更小,它的时间复杂度依然是O(n^2),原因就在于代码里的i--起到了和二次循环相同的效果。
优点:
1. 最好情况下时间复杂度低——O(n),一个循环跑下来始终i++,非常顺利。
2. 排序稳定,只交换相邻元素的排序都是稳定的。
3. 额外空间使用少,只需要i(记录进度)和t(交换缓存)。如果比较元素是数字,t都能省掉(不使用临时变量交换两个数字)。
缺点:
效率低。我们对比侏儒排序和直接插入排序。会发现这二者的排序思想一模一样,但是插入排序有2处优化是侏儒排序没做到的:
a. 插入排序遇到不匹配位置的新元素时,把前面的元素挨个后移,然后把新元素直接插入到合适位置(如果位置移动k位,则赋值k+1次)。而侏儒排序是把新元素逐个和前一个元素作交换,一路换位到合适位置,这是典型的冒泡做法(如果位置移动k位,则赋值3*k次)。
b. 当一个元素好不容易从第10位冒泡到第1位的时候,那么此时前10位一定是有序序列。插入排序会直接从第11位继续处理,而侏儒排序只能从第2位继续处理,因为它不知道上个元素是从哪个位置走到第1位的,只好多走冤枉路。
下面是C#代码:
void GnomeSort(List<int> a)
{
int i = 0;
while (i < a.Count)
{
if (i == 0 || a[i - 1] <= a[i])
{
i++;
}
else
{
int t = a[i];
a[i] = a[i - 1];
a[i - 1] = t;
i--;
}
}
}
当然,我们可以通过打补丁的方式来优化它,不过如果这么做了,我们干嘛不直接使用直接插入排序呢?作为直接插入排序的劣质版,它基本上没有实用价值,但是通过研究它,我们就能知道为什么直接插入排序能在这一众O(n^2)排序中脱颖而出了。
只有一重循环的排序——侏儒排序(Gnome Sort)的更多相关文章
- 地精排序(Gnome Sort) 算法
gnome应该是最简单排序的排序算法吧!Gnome Sort,这是该算法的作者命名的,O(n*n)时间复杂度,O(1)空间复杂度,属于稳定的排序算法.算法的思想是每趟循环找到第一个逆序的元素,把它和在 ...
- 数据结构杂谈(二)简单有趣的地精排序Gnome sort
很早之前便听说过地精排序的名字,今天自己看来一下,发现这是一种非常简单而且有趣的排序算法. 为什么叫地精排序? 地精排序在2000年由Dr. Hamid Sarbazi-Azad 提出的时候被称作 s ...
- Hark的数据结构与算法练习之地精(侏儒)排序
算法说明 地精排序是交换排序的一种,它是冒泡排序的一种改良,我感觉和鸡尾酒排序挺像的. 不同之处是鸡尾酒排序是从小到大,然后再从大到小切换着排序的.而地精排序是上来先从小到大排序,碰到交换到再从大到小 ...
- 数组升序排序的方法Arrays.sort();的应用
package com.Summer_0421.cn; import java.util.Arrays; /** * @author Summer * 数组升序排序的方法Arrays.sort();应 ...
- 连续线性空间排序 起泡排序(bubble sort),归并排序(merge sort)
连续线性空间排序 起泡排序(bubble sort),归并排序(merge sort) 1,起泡排序(bubble sort),大致有三种算法 基本版,全扫描. 提前终止版,如果发现前区里没有发生交换 ...
- 排序--选择排序Selection Sort Java实现
基本原理 选择排序的简单原理:选择排序算法通过从未排序部分重复查找最小元素(考虑升序)并将其放在开头来对数组进行排序. 将数组两个子数组: 已排序子数组 未排序子数组 选择排序中每次循环都会从未排序子 ...
- 经典排序算法 – 插入排序Insertion sort
经典排序算法 – 插入排序Insertion sort 插入排序就是每一步都将一个待排数据按其大小插入到已经排序的数据中的适当位置,直到全部插入完毕. 插入排序方法分直接插入排序和折半插入排序两种, ...
- 两种应该掌握的排序方法--------1.shell Sort
先了解下什么都有什么排序算法 https://en.wikipedia.org/wiki/Sorting_algorithm http://zh.wikipedia.org/zh/%E6%8E%92% ...
- Python 列表排序方法reverse、sort、sorted详解
python语言中的列表排序方法有三个:reverse反转/倒序排序.sort正序排序.sorted可以获取排序后的列表.在更高级列表排序中,后两中方法还可以加入条件参数进行排序. reverse() ...
随机推荐
- 41-native关键字的理解
使用 native 关键字说明这个方法是原生函数,也就是这个方法是用 C/C++等非Java 语言实现的,并且被编译成了 DLL,由 java 去调用. (1)为什么要用 native 方法 java ...
- sql developer连接mysql数据库
1 首先打开sql developer ,选择上方菜单,工具(tools)--->首选项,如下图 2 数据库(database)--->第三方 JDBC驱动程序 ; “添加条目”,选择m ...
- win7(64位)使用DEBUG
win7 64位好像是不能直接打开DOS进行DEUBG的,于是查找相应解决方案 开始看其他人的帖子,写得语焉不详,后来一查,居然是抄百度的.....自己不觉得low吗... 参考百度经验的回答http ...
- 最全总结!聊聊 Python 发送邮件的几种方式
1. 前言 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很多已经做案例的人,却不知道如何去学习更加高深的知识.那么针对这三类人,我给大 ...
- java 接口二
一 接口的多实现 接口最重要的体现:解决多继承的弊端.将多继承这种机制在java中通过多实现完成了. interface Fu1 { void show1(); } interface Fu2 { v ...
- java 用集合完成随机点名器和库存管理案例
一 随机点名器 1.案例需求 随机点名器,即在全班同学中随机的找出一名同学,打印这名同学的个人信息. 我们来完成随机点名器,它具备以下3个内容: 存储所有同学姓名 总览全班同学姓名 随机点名其中一人, ...
- 2020-04-09:TCP的四次挥手中为什么要有TIME_WAIT状态?
TIME_WAIT状态存在有两个原因.<1>可靠终止TCP连接.如果最后一个ACK报文因为网络原因被丢弃,此时server因为没有收到ACK而超时重传FIN报文,处于TIME_WAIT状态 ...
- 程序流程结构——if语句
c语言支持最基本的三种运行结构: 顺序结构:程序按顺序执行,不发生跳转 选择结构:根据是否满足条件 ,有选择的执行相应功能 循环结构:依据条件是否满足,循环多次执行某段代码 #define _CRT_ ...
- ios 创建sdk与demo同一个工程
思路摘要: 步骤1:创建一个文件夹用来放该项目 步骤2:设置工程工作区间 步骤3: 创建广告sdk项目 步骤4:创建广告sdkDemo项目 步骤5:配置一些文件 步骤6:将sdk导入到demo中进行 ...
- nohup 命令的使用
nohup 命令的使用 1. nohup简介 nohup 命令运行由 Command参数和任何相关的 Arg参数指定的命令,忽略所有挂断(SIGHUP)信号.在注销后使用 nohup 命令运行后台中的 ...