[英]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:试验结果:
quicksort: took 12 seconds快速排序:耗时 12 秒
above: 1 loop, took 0 seconds上图:1 个循环,耗时 0 秒
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.