Radix sort negative integers problem

with positive integers it works just fine, but with negative it doesn't. Does anyone know why is that so and what i need to fix to get it working with negative ones too?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <bits/stdc++.h>
using namespace std;

int DajNajveci(int niz[], int n)
{
  int najveci = niz[0];
  for (int i = 1; i < n; i++)
    if (niz[i] > najveci)
      najveci = niz[i];
  return najveci;
}
void brojacSort(int niz[], int duzina, int pozicija)
{
  const int najveci = 10;
  int izlazna[duzina];
  int brojac[najveci];

  for (int i = 0; i < najveci; ++i)//sabira i + 1 nakon izvrsavanja
    brojac[i] = 0;

  for (int i = 0; i < duzina; i++)
    brojac[(niz[i] / pozicija) % 10]++;

  for (int i = 1; i < najveci; i++)
    brojac[i] += brojac[i - 1];

  for (int i = duzina - 1; i >= 0; i--)
  {
    izlazna[brojac[(niz[i] / pozicija) % 10] - 1] = niz[i];
    brojac[(niz[i] / pozicija) % 10]--;
  }

  for (int i = 0; i < duzina; i++)
    niz[i] = izlazna[i];
}
void radixsort(int niz[], int duzina)
{
  int najveci = DajNajveci(niz, duzina);

  for (int pozicija = 1; najveci / pozicija > 0; pozicija *= 10)
    brojacSort(niz, duzina, pozicija);
}
void IspisiNiz(int niz[], int duzina)
{

  for (int i = 0; i < duzina; i++)
    cout << niz[i] << " ";
  cout << endl;
}
int main()
{
  int niz[] = {-1011, -1010, 1101 };
  int n = sizeof(niz) / sizeof(niz[0]);
  radixsort(niz, n);
  IspisiNiz(niz, n);
}


Last edited on
Maybe something like this.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <bits/stdc++.h>
using namespace std;

void radixSort(int a[], int n) {
    const int Base = 10, Size = Base * 2 - 1;
    auto output = new int[n];

    for (int pos = 1; ; pos *= Base) {
        int counter[Size]{};

        bool done = true;
        for (int i = 0; i < n; i++) {
            int d = a[i] / pos;
            ++counter[d % Base + Size / 2];
            done &= (d == 0);
        }
        if (done)
            break;

        for (int i = 1; i < Size; i++)
            counter[i] += counter[i - 1];

        for (int i = n; i-- > 0; )
            output[--counter[a[i] / pos % Base + Size / 2]] = a[i];

        for (int i = 0; i < n; i++)
            a[i] = output[i];
    }

    delete[] output;
}

void print(int *a, int n) {
    for (int i = 0; i < n; i++)
        cout << a[i] << ' ';
    cout << '\n';
}

void check(int *a, int n) {
    for (int i = 1; i < n; i++)
        if (a[i] < a[i - 1]) {
            printf("bad\n");
            break;
        }
}

int main() {
    int a[] = {5, -354, -123, 42, -634, -5321, 249};
    int n = sizeof a / sizeof *a;
    radixSort(a, n);
    print(a, n);
    check(a, n);
}

Last edited on
thanks a lot
if you never need it, negative addressing IS legal, but you need to ensure you have set up the memory as you need it to work, which means having a pointer in the middle of a block you own.

eg
int x[102]; //bigger than needed for quick example without thinking about it
int *ip = &x[51]; //split it, -50 to 50 should be usable,
ip[-10] = 100; //ok.

Topic archived. No new replies allowed.