简体   繁体   English

这个排序算法是什么? 有没有更有效的方法?

[英]What is this sorting algorithm? And is there a more efficient way?

I wrote this algorithm while learning about O(N) algorithms, and after the last question I posted moments ago, I was wondering if theres a similar algorithm that already exists as well.我在学习O(N)算法时编写了这个算法,在我刚刚发布的最后一个问题之后,我想知道是否也存在类似的算法。

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

/*algorithm designed by hoholee12*/

typedef struct{
    int val;
    int dup;
} duplicates;

int ScoopSort(int* arr, int size, int buf){

    //subarr buffer size
    buf += size;

    int* bigarr = malloc(size * sizeof(int));
    duplicates* subarr = malloc(buf * sizeof(duplicates));
    //subarr init: O(N)
    for (int i = 0; i < buf; i++) {
        subarr[i].val = INT_MIN;
        subarr[i].dup = 0;
    }

    //will always have biggest number of section
    int lastsize = INT_MIN;

    //big loop(until all elements are scooped: O(count of 'diff bigger than size'))
    int j = 0;
    int loopcount = 0;
    while (1){

        //min check per iteration: O(N)
        int min = INT_MAX;
        for (int i = 0; i < size; i++){
            if (min > arr[i] && arr[i] > lastsize) min = arr[i];
        }

        //initval per iteration
        int initval = min - 1;

        //follow index: incr dup
        for (int i = 0; i < size; i++){
            int val = arr[i] - min;
            if (val < buf && val >= 0){
                subarr[val].val = arr[i];
                subarr[val].dup++;
            }
        }

        //scoop subarr to bigarr: O(N)
        for (int i = 0; i < buf; i++){
            if (subarr[i].val > initval){
                for (int x = 0; x < subarr[i].dup; x++) bigarr[j++] = subarr[i].val;
                subarr[i].dup = 0;
                if (lastsize < subarr[i].val) lastsize = subarr[i].val;
            }
        }

        loopcount++;

        //break on all scooped
        if (j >= size) break;
    }

    //copy back: O(N)
    for (int i = 0; i < size; i++) arr[i] = bigarr[i];


    free(subarr);
    free(bigarr);

    return loopcount;

}

int test2(){
#define ARRSIZE 1000000
    int* arr = malloc(ARRSIZE * sizeof(int));
    srand(time(NULL));

    for (int i = 0; i < ARRSIZE; i++){
        arr[i] = rand() *(RAND_MAX + 1) + rand();
    
    }

    //printf("before: ");
    //for (int i = 0; i < ARRSIZE; i++) printf("%d ", arr[i]);
    //printf("\n");

    time_t start = time(NULL);
    int result = ScoopSort(arr, ARRSIZE, 0);
    time_t end = time(NULL);

    //printf("after: ");
    for (int i = 0; i < ARRSIZE; i++) printf("%d ", arr[i]);

    printf("\nlooped %d time(s).\ntook %d second(s).", result, end - start);

    free(arr);
    return 0;
}

int test1(){
    //3 0 3 2 6 3 1 4 1 7
    int arr[10] = { 8, 3, 4, 9, 4, 3, 9, 5, 4, 0 };
    srand(time(NULL));

    printf("before: ");
    for (int i = 0; i < 10; i++) printf("%d ", arr[i]);
    printf("\n");

    time_t start = time(NULL);
    int result = ScoopSort(arr, 10, 0);
    time_t end = time(NULL);

    printf("after: ");
    for (int i = 0; i < 10; i++) printf("%d ", arr[i]);

    printf("\nlooped %d time(s).\ntook %d second(s).", result, end - start);

    return 0;
}

int main(){
    test2();

    return 0;
}

in short, it is somewhat of a count sort mixed with bucket sort for limited memory.简而言之,对于有限的 memory,它有点像计数排序与桶排序的混合。 so still O(N^2) but probably faster than the last one..所以仍然是 O(N^2) 但可能比上一个更快..

I went from the last question -> count sort + insertion sort -> to this.我从最后一个问题 -> 计数排序 + 插入排序 -> 到这个。 I am also wondering if theres still a more efficient way (except for hashing).我也想知道是否还有更有效的方法(散列除外)。

test results:试验结果:

size = 10000000, rand() short int range: size = 10000000, rand() 短整数范围:

quicksort: took 12 seconds快速排序:耗时 12 秒

above: 1 loop, took 0 seconds上图:1 个循环,耗时 0 秒

size = 10000000, rand() int range: size = 10000000, rand() int 范围:

quicksort: took 8 seconds快速排序:耗时 8 秒

above: 108 loops, took 21 seconds上图:108 个循环,耗时 21 秒

its good enough for small values since its basically a counting sort, but for big values not so much.它对于小值来说已经足够好了,因为它基本上是一种计数排序,但对于大值来说就不是那么多了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM