gnome应该是最简单排序的排序算法吧!Gnome Sort,这是该算法的作者命名的,O(n*n)时间复杂度,O(1)空间复杂度,属于稳定的排序算法。算法的思想是每趟循环找到第一个逆序的元素,把它和在它前面的已排序的元素逐个进行比较、交换,有点像插入排序。

void gnomeSort(int a[],int len)
{
int i=;
while(i<len)
{
if(a[i-]<=a[i])
{
i++;
}
else
{
int tmp=a[i-];a[i-]=a[i];a[i]=tmp;
i--;
}
}
}

The simplest sort algorithm is not Bubble Sort..., it is not Insertion Sort..., it's Gnome Sort!

Gnome Sort is based on the technique used by the standard Dutch Garden Gnome (Du.: tuinkabouter). Here is how a garden gnome sorts a line of flower pots. Basically, he looks at the flower pot next to him and the previous one; if they are in the right order he steps one pot forward, otherwise he swaps them and steps one pot backwards. Boundary conditions: if there is no previous pot, he steps forwards; if there is no pot next to him, he is done.

—Dick Grune (该算法发明人的话)

该算法优化,wikipedia有说明:http://en.wikipedia.org/wiki/Gnome_sort

The gnome sort may be optimized by introducing a variable to store the position before traversing back toward the beginning of the list. This would allow the "gnome" to teleport back to his previous position after moving a flower pot. With this optimization, the gnome sort would become a variant of the insertion sort. The animation in the introduction to this topic takes advantage of this optimization.

Here is pseudocode for an optimized gnome sort using a zero-based array:

算法优化 gnome2:地精在回头检查花盘顺序前记下当前位置,整理完就瞬间转移到之前位置的下一个位置。瞬间转移,很强大。

void gnomeSortOpt(int a[],int len)
{
int i=;
int prevPosition=-;
while(i<len)
{
if(a[i-]<=a[i])
{
if(prevPosition==-)
{
i++;
}
else
{
// After traverse backward, go to the position next to the previous
i=prevPosition+;
prevPosition=-;
}
}
else
{
if(prevPosition==-) //记住现在的位置 Mark the Gnome's previous position before traverse backward
{
prevPosition=i;
}
int tmp=a[i-];a[i-]=a[i];a[i]=tmp;
i--;
}
}
}

Gnome sort version 2类似插入排序,不断把列表后面待排序的元素插入到列表前面已排序的部分中,但类似于冒泡排序那样比较并交换相邻元素。因此其算法复杂度与插入排序相当,但比插入排序需要更多的复制操作(用于交换相邻元素)。

Gnome sort version 3,搬了无数花盘后,地精想到一个新方法。如果交换相邻两个花盘,每次要搬花盘三次(复制三次),如果先拿起来当前位置的花盘(temp=data[i]),就有空位给其他花盘移动,每次只搬一次花盘(复制一次,data[i]=data[i-1])。这次地精先拿一个花盘在手(temp),如果手中花盘(temp)应放到上一个花盘(i-1)前面,就用脚(地精一般不高,脚够长吗?^_^)将上一个花盘(i-1)踢到当前位置(i),然后拿着花盘(temp)走到上一个位置(i=i-1),重复此过程。

void gnomeSortOpt2(int a[],int len)
{
int i=;
int prevPosition=-;
int tmp;
while(i<len)
{
if(a[i-]<=a[i])
{
if(prevPosition==-)
{
i++;
}
else
{
a[i]=tmp;
i=prevPosition+;
prevPosition=-;
}
tmp=a[i];
}
else
{
if(prevPosition==-)
{
prevPosition=i;
} a[i]=a[i-]; i--;
}
}
}

Gnome sort version 3已经和插入排序一样了,呵呵。

地精排序最显著的特点是代码只有一层循环,原版算法代码极短,但效率不高;改进后相当于插入排序的变种,不过条件判断多了,代码比标准的插入排序长。
以类似方式,选择排序,冒泡排序也可以改成一层循环。
在简单的基于比较的排序中(不包括快速排序,归并排序,堆排序等),插入排序总体性能不错,建议作为首选;而选择排序有最少的元素复制次数,当元素复制代价较大时(如存储介质的写入速度比读取速度慢很多)是个好选择。
另外,只做部分的选择排序,就成了选择第n小元素的选择算法。正如部分的快速排序成了quickselect选择算法。

http://en.wikipedia.org/wiki/Selection_algorithm

转自:http://blog.csdn.net/winark/article/details/5918944

地精排序(Gnome Sort) 算法的更多相关文章

  1. 数据结构杂谈(二)简单有趣的地精排序Gnome sort

    很早之前便听说过地精排序的名字,今天自己看来一下,发现这是一种非常简单而且有趣的排序算法. 为什么叫地精排序? 地精排序在2000年由Dr. Hamid Sarbazi-Azad 提出的时候被称作 s ...

  2. 地精排序Gnome Sort

    号称最简单的排序算法,只有一层循环,默认情况下前进冒泡,一旦遇到冒泡的情况发生就往回冒,直到把这个数字放好为止 直接看它排序的过程,待排数组[6 2 4 1 5 9] 先设计一个标识i=0然后从头开始 ...

  3. 转载 从最简单的vector中sort用法到自定义比较函数comp后对结构体排序的sort算法

    转载自:http://www.cnblogs.com/cj695/p/3863142.html sort函数在使用中非常好用,也非常简单,而且效率与冒泡或者选择排序不是一个数量级.本文就sort函数在 ...

  4. 【转】 从最简单的vector中sort用法到自定义比较函数comp后对结构体排序的sort算法

    sort函数在使用中非常好用,也非常简单,而且效率与冒泡或者选择排序不是一个数量级.本文就sort函数在vector中的用法分为sort函数入门用法与自定义comp比较函数比较结构体这两个最基本的功能 ...

  5. 从最简单的vector中sort用法到自定义比较函数comp后对结构体排序的sort算法

    sort函数在使用中非常好用,也非常简单,而且效率与冒泡或者选择排序不是一个数量级.本文就sort函数在vector中的用法分为sort函数入门用法与自定义comp比较函数比较结构体这两个最基本的功能 ...

  6. 【C++】从最简单的vector中sort用法到自定义比较函数comp后对结构体排序的sort算法

    sort函数在使用中非常好用,也非常简单,而且效率与冒泡或者选择排序不是一个数量级.本文就sort函数在vector中的用法分为sort函数入门用法与自定义comp比较函数比较结构体这两个最基本的功能 ...

  7. 跳跃空间(链表)排序 选择排序(selection sort),插入排序(insertion sort)

    跳跃空间(链表)排序 选择排序(selection sort),插入排序(insertion sort) 选择排序(selection sort) 算法原理:有一筐苹果,先挑出最大的一个放在最后,然后 ...

  8. [算法] 希尔排序 Shell Sort

    希尔排序(Shell Sort)是插入排序的一种,它是针对直接插入排序算法的改进.该方法又称缩小增量排序,因DL.Shell于1959年提出而得名. 希尔排序实质上是一种分组插入方法.它的基本思想是: ...

  9. 经典排序算法 - 高速排序Quick sort

    经典排序算法 - 高速排序Quick sort 原理,通过一趟扫描将要排序的数据切割成独立的两部分,当中一部分的全部数据都比另外一部分的全部数据都要小,然后再按此方法对这两部分数据分别进行高速排序,整 ...

随机推荐

  1. Java程序栈信息文件中的秘密(五)

    最近发现在使用jstack工具在导出Java应用的线程栈时有一个小小的窍门,比如Linux环境上有一个用户为appuser,假如以这个用户启动了一个Java进程B,如果想要导出进程B的线程栈,则必须切 ...

  2. BingMap的GeocodeService进行地理位置正向和反向检索--后台实现

    一.加入GeocodeService的Web服务引用 地理编码服务(GeocodeService)是以WCF技术公布的一个Web服务,地图编码服务提供了以一个有效的物理地址在地图上匹配其相应的地图地址 ...

  3. 【原创】移除RX filters在C118上面

    » 作者:LSX » 原创文章版权归作者所有,未经作者同意请保留以下声明. » 本文链接:http://blog.lishixin.net/?p=1318 » 转载请注明来源:LSX·Blog » & ...

  4. VC++ 编译过程

    一 前言 一开始编译C++代码的时候可能会对编译的错误觉得很难理解,搞不清楚究竟是哪里错了.了解编译过程,能够更好的处理编译错误. 二 名词解释 编译单元:当一个c或cpp文件在编译时,预处理器首先递 ...

  5. C#操作Office.word(一)

    该文章主要是讲述如何使用VS2010创建word文档,因为在项目中我们可能需要点击一个按钮把数据库中的项目表单或图片显示到word文档中,因此该文章主要分析如何使用VS2010创建word文档并填写相 ...

  6. 关于playframework2.5

    加入了很多新东西: 1.用akka streams 替换了大部分 iteratee-based async io,当然还有一些模块在用iteratees 2.java 的一些API 做了调整升级,以及 ...

  7. Linux下 保存 git账号密码

    一.通过文件方式 1.在~/下, touch创建文件 .git-credentials, 用vim编辑此文件,输入内容格式: touch .git-credentials vim .git-crede ...

  8. hdu 3333 Turing Tree

    题目链接 给n个数, m个询问, 每次询问输出区间内的数的和, 相同的数只计算一次. 数组里的数是>-1e9 <1e9, 可以把它离散以后用莫队搞... #include <iost ...

  9. Android开发中怎样调用系统Email发送邮件(多种调用方式)

    在Android中调用其他程序进行相关处理,几乎都是使用的Intent,所以,Email也不例外,所谓的调用Email,只是说Email可以接收Intent并做这些事情 我们都知道,在Android中 ...

  10. 不同服务器之间使用svn钩子post-commit同步代码遇到的证书认证问题.md

    遇到的问题,以下其他问题都是因解决这个问题引申出来的问题 VisualSVN hooks自动同步更新到web服务器 错误信息如下: Error validating server certificat ...