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

很早之前便听说过地精排序的名字,今天自己看来一下,发现这是一种非常简单而且有趣的排序算法。

为什么叫地精排序?

地精排序在2000年由Dr. Hamid Sarbazi-Azad 提出的时候被称作 stupid sort,可见其思想的简单性。后来,这个算法被Dick Grune 描述成地精排序Gnome sort。

故事背景:

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

大意就是有一个地精(一种荷兰的花园地精 tuinkabouter https://nl.wikipedia.org/wiki/Tuinkabouter在排列一排花盘。他从前至后的排列,如果相邻的两个花盘顺序正确,他向前一步;如果花盘顺序错误,他后退一步,直到所有的花盘的顺序都排列好。

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

这就是萌萌的gnome(tuinkabouter)

算法思想

这个算法可以看作是冒泡排序的简化版。冒泡排序的思想是不断交换反序对,使得最大的元素浮出水面,而地精排序在发现反序对时,把它往回按,直到排好序,再向前继续走。

c++实现

地精排序只需要一重循环,非常简单,也解释了为什么一开始会被叫做stupid。

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

这里要注意,当i为0时,说明回到了起点,此时需要向前移动。

地精排序的优化

地精在发现反序对时,会用一块石头标记处当前的位置,然后把反序的花盘往回交换。当这个花盘找到了正确的位置之后,地精会瞬间移动回石头标记的位置上。在这种情况下,地精排序成为了一种插入排序。

地精排序的分析

最好情况下,序列是已经排好的,时间复杂度是O(n),最坏情况下,序列式反序的,时间复杂度是O(n^2),与冒泡排序相同。

上一篇:【纯干货】SVN使用时应注意的那些事


下一篇:【ASP.NET MVC】MVC概述