zoukankan      html  css  js  c++  java
  • 数据结构杂谈(二)简单有趣的地精排序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 = 0;
        while (i < n) 
        {
            if (i == 0 || ar[i - 1] <= ar[i]) 
                i++;
            else 
            {
                int tmp = ar[i]; 
                ar[i] = ar[i - 1];
                ar[--i] = tmp;
            }
        }
    }

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

    地精排序的优化

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

    地精排序的分析

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

  • 相关阅读:
    各种模板
    HNOI2019总结
    WC2019游记
    THUSC2017 Day1题解
    NOIP2018联赛总结
    LOJ2557. 「CTSC2018」组合数问题
    NOI2018游记
    bzoj4671: 异或图
    sg函数小结
    [NOI2011]Noi嘉年华
  • 原文地址:https://www.cnblogs.com/yatesxu/p/5402127.html
Copyright © 2011-2022 走看看