Diferença entre for comum e for aprimorado

Eu estava escrevendo um algoritmo:

static void countingSort(int[] A, int maior){
    int[] aux = new int[maior+1];
    int[] resp = new int[A.length];
    
    for(int i = 0; i < A.length; i++){
        aux[A[i]]++;
    }
    //...

}

Eu quis substituir o for normal por:

for(int i: A){
aux[A[i]]++;
}

Entretanto tal alteração resulta em ArrayOutOfBounds. Alguém pode me explicar por que isso acontece? Eu já tinha usado esse segundo for várias vezes dessa maneira e só agora está apresentando essa diferença. Eu quero percorrer todo o array A, então não vejo o porque de dar problema;

Na primeira versao do for, você tem os indíces do array e acessa os elementos de A atráves do indíce: A[i]
Na segunda versao, ele já te automaticamente os elementos, ou seja, você pode usar o i diretamente: aux[i]

Esse seu algoritmo parece meio estranho pois você pode criar um array gigantesco dependendo dos valores contidos em A, pelo que entendi. Se você tiver um array como A = [1,10,1000000], seu array aux será criado com 1000001 posiçoes, é isso mesmo que quer?

Pela assinatura do metodo você deseja contar e ordenar um array passando um parametro para ordenação com chamado maior para ser ordenado. É isso?

Sim, é assim que funciona o algoritmo countingSort, não é?

maior é o maior elemento do array. Ele cria um array auxiliar com tamanho maior + 1 e vai contando ocorrência. Algo assim, mas ainda tá dando problema:

static void countingSort(int[] A, int maior) { //só funciona para números positivos
    int[] aux = new int[maior + 1]; //cria array auxiliar com tamanho maior + 1
    int[] resp = new int[A.length];
    //preenche aux com zeros (java já faz isso automaticamente)

    for (int i = 0; i < A.length; i++) {
        aux[A[i]]++;
    }
    
    for (int i = 1; i < aux.length; i++) {
        aux[i] += aux[i - 1];
    }

    for (int i = A.length - 1; i >= 0; i--) {
        resp[aux[A[i]]] = A[i];
        aux[A[i]]--;
    }

    for (int i = 0; i < A.length - 1; i++) {
        A[i] = resp[i];
    }
}

Sim é assim que se faz algoritmo counting sort!
Mas veja exemplo do site : https://felipepriuli.wordpress.com/2013/01/08/counting-sort/

`public static void ordena(int[] a, int m){
int n = a.length;

    int vetorAuxiliar[] = new int[m];
     
    //1ª - (Inicializar com zero)
    for(int i = 0; i < m; i++){
        vetorAuxiliar[i] = 0;
    }
     
    //2ª - Contagem das ocorrencias
    for(int i = 0; i < n; i++){
        vetorAuxiliar[a[i]]++;
    }

    //3ª - Ordenando os indices do vetor auxiliar
    int sum = 0;                
    for(int i = 1; i < m; i++){
        int dum = vetorAuxiliar[i];
        vetorAuxiliar[i] = sum;
        sum += dum;
    }       
    int vetorOrdenado[] = new int[n];
    for(int i = 0; i < n; i++){
        vetorOrdenado[vetorAuxiliar[a[i]]] = a[i];
        vetorAuxiliar[a[i]]++;
    }
     
    //4ª Retornando os valores ordenados para o vetor de entrada
    for (int i = 0; i < n; i++){
        a[i] = vetorOrdenado[i];
    }
}`

Você tem razao, nao conhecia esse algoritmo. Mas li agora que ele nao é recomendado para dados arbitrários como os que passei de exemplo!

Obrigado por responder! Já consegui, o meu problema nesse algoritmo era com o zero dos arrays. Como eu tava vendo esse algoritmo de ordenação em pseudocódigo, tava confundindo (lá começava em 1).