No, I do not believe. You need extra space to be able to "sort" the data in O (n) by assigning to buckets, or you need to sort a place that will not be O (n).
Of course, there are always tricks if you can make certain assumptions. For example, if N < 64Kyour integers are 32 bits wide, you can multiplex the space needed for the count array on top of the current array.
In other words, use the lower 16 bits to store the values in the array, and then use the upper 16 bits for your array, where you simply store the counter of the values corresponding to the index.
, N == 8. , 8 , 8, . (), .
0 1 2 3 4 5 6 7 <- index
(0)7 (0)6 (0)2 (0)5 (0)3 (0)3 (0)7 (0)7
O (n), :
for idx = 0 to N:
array[array[idx] % 16] += 16
, 7. , 16 7, . modulo , , , .
, :
0 1 2 3 4 5 6 7 <- index
(0)7 (0)6 (1)2 (2)5 (0)3 (1)3 (1)7 (3)7
, int (array[X] / 16), X.
, . , , , , : -)
, , X, O (N). . , , N 8, , 8. ( , :
0 1 2 3 4 5 6 7 <- index
(0) (0) (1) (2) (0) (1) (1) (3)
, , - , , 8.
- 0 8 ( ).
- 1 7. 0 x 3, .
- 2 6. 1 x 1,
(2,6). - 3 5. 2 x 1,
(3,5). - 4, , . , 4s, , . , , , ( ,
m) 1 + 2 + 3 + ... + m-1. , m(m-1)/2.
, , , .
,
a b c d e f g h <- identifiers
7 6 2 5 3 3 7 7
:
(2,6) (3,5) (3,5)
(c,b) (e,d) (f,d) <- identifiers
8.
:
#include <stdio.h>
int arr[] = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 4, 4, 4, 4};
#define SZ (sizeof(arr) / sizeof(*arr))
static void dumpArr (char *desc) {
int i;
printf ("%s:\n Indexes:", desc);
for (i = 0; i < SZ; i++) printf (" %2d", i);
printf ("\n Counts :");
for (i = 0; i < SZ; i++) printf (" %2d", arr[i] / 100);
printf ("\n Values :");
for (i = 0; i < SZ; i++) printf (" %2d", arr[i] % 100);
puts ("\n=====\n");
}
. :
int main (void) {
int i, j, find, prod;
dumpArr ("Initial");
for (i = 0; i < SZ; i++) {
arr[arr[i] % 100] += 100;
}
, :
dumpArr ("After bucket sort");
// Now do pairings.
find = 8;
for (i = 0, j = find - i; i <= j; i++, j--) {
if (i == j) {
prod = (arr[i]/100) * (arr[i]/100-1) / 2;
if (prod > 0) {
printf ("(%d,%d) %d time(s)\n", i, j, prod);
}
} else {
if ((j >= 0) && (j < SZ)) {
prod = (arr[i]/100) * (arr[j]/100);
if (prod > 0) {
printf ("(%d,%d) %d time(s)\n", i, j, prod);
}
}
}
}
return 0;
}
:
Initial:
Indexes: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Counts : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Values : 3 1 4 1 5 9 2 6 5 3 5 8 9 4 4 4 4
=====
After bucket sort:
Indexes: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Counts : 0 2 1 2 5 3 1 0 1 2 0 0 0 0 0 0 0
Values : 3 1 4 1 5 9 2 6 5 3 5 8 9 4 4 4 4
=====
(2,6) 1 time(s)
(3,5) 6 time(s)
(4,4) 10 time(s)
, , , .