Gnome排序算法

Gnome排序(地精排序),起初由Hamid
Sarbazi-Azad 于2000年提出,并被称为stupid排序,后来被Dick
Grune描述并命名为“地精排序”,作为一个排序算法,和插入排序类似,除了移动一个元素到最终的位置,是通过交换一系列的元素实现,就像冒泡排序一
样。概念上十分简单,不需要嵌套循环。时间复杂度为O(n2),但是如果初始数列基本有序,时间复杂度将降为O(n)。实际上Gnome算法可以和插入排序算法一样快。平均运行时间为O(n2).

Gnome排序算法总是查找最开始逆序的一对相邻数,并交换位置,基于交换两元素后将引入一个新的相邻逆序对,并没有假定当前位置之后的元素已经有序.

本文地址:http://www.cnblogs.com/archimedes/p/gnome-sort-algorithm.html,转载请注明源地址。

下面gnome排序算法的伪代码,使用0起始索引数组:

procedure gnomeSort(a[])
    pos := 1
    while pos < length(a)
        if (a[pos] >= a[pos-1])
            pos := pos + 1
        else
            swap a[pos] and a[pos-1]
            if (pos > 1)
                pos := pos - 1
            end if
        end if
    end while
end procedure

实例

给定一个无序数组, a = [5, 3, 2, 4], gnome排序将在while循环中执行如下的步骤.  "current position"采用加粗黑体:

当前数组 操作
[5, 3, 2, 4] a[pos] < a[pos-1], 交换:
[3, 5, 2, 4] a[pos] >= a[pos-1],  pos自增:
[3, 5, 2, 4] a[pos] < a[pos-1], 交换并且pos > 1, pos自减:
[3, 2, 5, 4] a[pos] < a[pos-1], 交换并且pos <= 1, pos自增:
[2, 3, 5, 4] a[pos] >= a[pos-1],  pos自增:
[2, 3, 5, 4] a[pos] < a[pos-1], 交换并且pos > 1, pos自减:
[2, 3, 4, 5] a[pos] >= a[pos-1], pos自增:
[2, 3, 4, 5] a[pos] >= a[pos-1], pos自增:
[2, 3, 4, 5] pos == length(a), 完成.

C代码如下:

// Completed on 2014.10.9 10:01
// Language: C99
//
// 版权所有(C)codingwu   (mail: oskernel@126.com)
// 博客地址:http://www.cnblogs.com/archimedes/

#include<stdio.h>
#include<stdbool.h>
void swap(int *a, int *b)   //交换两元素的值
{
    int t;
    t = *a;
    *a = *b;
    *b = t;
}

void printArray(int a[], int count)   //打印数组元素
{
    int i;
    for(i = 0; i < count; i++)
        printf("%d ",a[i]);
    printf("\n");
}

void gnome_sort(int *a, int len)   //gnome排序算法
{
    int pos = 1;
    while(pos < len) {
        if(a[pos] >= a[pos - 1]) {
            pos++;
        } else {
            swap(&a[pos], &a[pos - 1]);
            if(pos > 1) pos--;
        }
    }
}

int main(void)
{
    int a[] = {3, 5, 4, 6, 9, 7, 8, 0, 1};
    int n = sizeof(a) / sizeof(*a);
    printArray(a, n);
    gnome_sort(a, n);
    printArray(a, n);
    return 0;
}

优化:

gnome算法还可以通过引入一个变量,用于存储每次返回到数组前面的位置来进行优化。采用这样的优化,gnome排序将成为一个变种插入排序,下面优化后gnome排序算法的伪代码,使用0起始索引数组:

procedure optimizedGnomeSort(a[])
    pos := 1
    last := 0
    while pos < length(a)
        if (a[pos] >= a[pos-1])
            if (last != 0)
                pos := last
                last := 0
            end if
            pos := pos + 1
        else
            swap a[pos] and a[pos-1]
            if (pos > 1)
                if (last == 0)
                    last := pos
                end if
                pos := pos - 1
            else
                pos := pos + 1
            end if
        end if
    end while
end procedure

C代码如下:

// Completed on 2014.10.9 10:31
// Language: C99
//
// 版权所有(C)codingwu   (mail: oskernel@126.com)
// 博客地址:http://www.cnblogs.com/archimedes/

#include<stdio.h>
#include<stdbool.h>
void swap(int *a, int *b)   //交换两元素的值
{
    int t;
    t = *a;
    *a = *b;
    *b = t;
}

void printArray(int a[], int count)   //打印数组元素
{
    int i;
    for(i = 0; i < count; i++)
        printf("%d ",a[i]);
    printf("\n");
}
void optimizedGnome_Sort(int *a, int len)   //优化后的gnome排序
{
    int last, pos;
    last = 0; pos = 1;
    while(pos < len) {
        if(a[pos] >= a[pos - 1]) {
            if(last != 0) {
                pos = last;
                last = 0;
            }
            pos++;
        } else {
            swap(&a[pos], &a[pos - 1]);
            if(pos > 1) {
                if(last == 0)
                    last = pos;
                pos--;
            } else {
                pos++;
            }
        }
    }
}
int main(void)
{
    int a[] = {3, 5, 4, 6, 9, 7, 8, 0, 1};
    int n = sizeof(a) / sizeof(*a);
    printArray(a, n);
    optimizedGnome_Sort(a, n);
    printArray(a, n);
    return 0;
}
时间: 2024-09-04 15:33:25

Gnome排序算法的相关文章

PHP 四种基本排序算法的代码实现(1)

许多人都说算法是程序的核心,算法的好坏决定了程序的质量.作为一个初级phper,虽然很少接触到算法方面的东西.但是对于基本的排序算法还是应该掌握的,它是程序开发的必备工具.这里介绍冒泡排序,插入排序,选择排序,快速排序四种基本算法,分析一下算法的思路. 前提:分别用冒泡排序法,快速排序法,选择排序法,插入排序法将下面数组中的值按照从小到大的顺序进行排序. $arr(1,43,54,62,21,66,32,78,36,76,39); 1. 冒泡排序 思路分析:在要排序的一组数中,对当前还未排好的序

常用的各种排序算法

//常用的排序算法 #include <iostream> using namespace std; typedef int ElemType; /* 1.插入排序 (1)直接插入排序算法 算法思想:将等排序列划分为有序与无序两部分,然后再依次将无序部分插入到已经有序的部分,最后 就可以形成有序序列. 操作步骤如下: 1)查找出元素L(i)在表中的插入位置K: 2)将表中的第K个元素之前的元素依次后移一个位置: 3)将L(i)复制到L(K). 时间复杂度为:O(n^2) */ void Ins

各种排序算法汇总

目录 简介 交换排序 冒泡排序 快速排序 插入排序 直接插入排序 希尔排序 选择排序 简单选择排序 堆排序 归并排序 基数排序 总结 简介 排序是计算机内经常进行的一种操作,其目的是将一组"无序"的记录序列调整为"有序"的记录序列.分内部排序和外部排序.若整个排序过程不需要访问外存便能完成,则称此类排序问题为内部排序.反之,若参加排序的记录数量很大,整个序列的排序过程不可能在内存中完成,则称此类排序问题为外部排序.内部排序的过程是一个逐步扩大记录的有序序列长度的过程

九大排序算法总结

排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存. 常见的内部排序算法有:插入排序.希尔排序.选择排序.冒泡排序.归并排序.快速排序.堆排序.基数排序等. 算法一:插入排序 插入排序是一种最简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入. 算法步骤 1)将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当

内部排序算法:基数排序

基本思想 基数排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较.由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数. 基数排序可以采用两种方式: LSD(Least Significant Digital):从待排序元素的最右边开始计算(如果是数字类型,即从最低位个位开始). MSD(Most Significant Digital):从待排序元素的最左边开始计算(如果是数字类型,即从最高位开始). 我们以L

桶排序算法

桶排序 (Bucket sort)或所谓的箱排序,是一个排序算法,工作的原理是将数组分到有限数量的桶子里.每个桶子再个别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序).桶排序是鸽巢排序的一种归纳结果.当要被排序的数组内的数值是均匀分配的时候,桶排序使用线性时间(Θ(n)).但桶排序并不是比较排序,他不受到 O(n log n) 下限的影响. 本文地址:http://www.cnblogs.com/archimedes/p/bucket-sort-algorithm.html

python实现的希尔排序算法实例

  本文实例讲述了python实现希尔排序算法的方法.分享给大家供大家参考.具体如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 def shellSort(items): inc = len(items) / 2 while inc: for i in xrange(len(items)): j = i temp = items[i] while j >= inc and items[j-inc] > temp: items[j] = items[j - inc]

常见的五类排序算法图解和实现(多关键字排序:基数排序以及各个排序算法的总结)

基数排序思想 完全不同于以前的排序算法,可以说,基数排序也叫做多关键字排序,基数排序是一种借助"多关键字排序"的思想来实现"单关键字排序"的内部排序算法. 两种方式: 1.最高位优先,先按照最高位排成若干子序列,再对子序列按照次高位排序 2.最低位优先:不必分子序列,每次排序全体元素都参与,不比较,而是通过分配+收集的方式. 多关键字排序 例:将下表所示的学生成绩单按数学成绩的等级由高到低排序,数学成绩相同的学生再按英语成绩的高低等级排序.        第一个关键

JavaScript版几种常见排序算法分享

说明 ·  每个浏览器测试得出的数据会不一样.比如我用chrome 测试 一般快速排序都会最快,IE 则根据数组长度有可能希尔最快. ·  不要用太大数据去测试冒泡排序(浏览器崩溃了我不管) 个人理解 ·  冒泡排序:最简单,也最慢,貌似长度小于7最优 ·  插入排序: 比冒泡快,比快速排序和希尔排序慢,较小数据有优势 ·  快速排序:这是一个非常快的排序方式,V8的sort方法就使用快速排序和插入排序的结合 ·  希尔排序:在非chrome下数组长度小于1000,希尔排序比快速更快 ·  系统