zoukankan      html  css  js  c++  java
  • Gnome排序

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

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

    Description

    下面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"采用加粗黑体:

    Current arrayAction to take
    [5, 3, 2, 4] a[pos] < a[pos-1], swap:
    [3, 5, 2, 4] a[pos] >= a[pos-1], increment pos:
    [3, 5, 2, 4] a[pos] < a[pos-1], swap and pos > 1, decrement pos:
    [3, 2, 5, 4] a[pos] < a[pos-1], swap and pos <= 1, increment pos:
    [2, 3, 5, 4] a[pos] >= a[pos-1], increment pos:
    [2, 3, 5, 4] a[pos] < a[pos-1], swap and pos > 1, decrement pos:
    [2, 3, 4, 5] a[pos] >= a[pos-1], increment pos:
    [2, 3, 4, 5] a[pos] >= a[pos-1], increment pos:
    [2, 3, 4, 5] pos == length(a), finished.

    C代码如下:

     1 #include<stdio.h>    
     2 #include<string.h>   
     3 #include<math.h>   
     4 #include<ctype.h>   
     5 #include<stdbool.h>
     6 #include<stdlib.h>
     7 #include<time.h>
     8 
     9 void swap(int *a, int *b)   //交换两元素的值
    10 {
    11     int t;
    12     t=*a;
    13     *a=*b;
    14     *b=t;
    15 }
    16 
    17 void printArray(int a[], int count)   //打印数组元素
    18 {
    19     int i;
    20     for(i=0; i<count; i++)
    21         printf("%d ",a[i]);
    22     printf("\n");
    23 }
    24 
    25 void gnome_sort(int *a, int len)   //gnome排序算法
    26 {
    27     int pos=1;
    28     while(pos<len)
    29     {
    30         if(a[pos]>=a[pos-1])
    31         {
    32             pos++;
    33         }
    34         else
    35         {
    36             swap(&a[pos],&a[pos-1]);
    37             if(pos>1)   pos--;
    38         }
    39     }
    40 }
    41 
    42 int main(void)   
    43 {
    44     int a[]={3, 5, 4, 6, 9, 7, 8, 0, 1};
    45     int n=sizeof(a)/sizeof(*a);
    46     printArray(a,n);
    47     gnome_sort(a,n);
    48     printArray(a,n);    
    49     return 0;
    50 }

    优化算法

    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代码如下:

    #include<stdio.h>    
    #include<string.h>   
    #include<math.h>   
    #include<ctype.h>   
    #include<stdbool.h>
    #include<stdlib.h>
    #include<time.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;
    }
  • 相关阅读:
    摄像头bug查找工作总结
    高通camera结构(摄像头基础介绍)
    什么是滤波器,滤波器是干嘛用的,IIR和FIR滤波器又是什么?(回答请简洁,别浪费大家时间)
    详解摄像头各个引脚的作用关系
    Camera帧率和AE的关系
    CMOS Sensor的调试经验分享
    VSYNC与HSYNC与PCLK与什么有关系
    PCLK怎么获得?
    高清摄像头MIPI接口与ARM处理器的连接
    常用正则
  • 原文地址:https://www.cnblogs.com/cpoint/p/3367358.html
Copyright © 2011-2022 走看看