Li recentemente que é possível ter matrizes que não precisam ser inicializadas, ou seja, é possível usá-las sem ter que gastar algum tempo tentando definir cada membro com o valor padrão. ou seja, você pode começar a usar a matriz como se ela tivesse sido inicializada pelo valor padrão sem precisar inicializá-la. (Desculpe, não me lembro onde li isso).
Por exemplo, por que isso pode ser surpreendente:
Digamos que você está tentando modelar um pior caso hashtable (para cada um insert / pesquisa de exclusão /) de inteiros no intervalo .[ 1 , n 2 ]
Você pode alocar uma matriz de tamanho bits e usar bits individuais para representar a existência de um número inteiro na hashtable. Nota: alocar memória é considerado tempo O ( 1 ) .
Agora, se você não precisou inicializar essa matriz, qualquer sequência das operações say nesta hashtable é agora o pior caso O ( n ) .
Portanto, você tem uma implementação de hash "perfeita", que para uma sequência de operações usa Θ ( n 2 ) de espaço, mas é executada em O ( n ) tempo!
Normalmente, espera-se que seu tempo de execução seja pelo menos tão ruim quanto o uso de espaço!
Nota: O exemplo acima pode ser usado para uma implementação de um conjunto esparso ou matriz esparsa, portanto, não é apenas de interesse teórico, suponho.
Então a questão é:
Como é possível ter uma matriz como estrutura de dados que nos permita pular a etapa de inicialização?
fonte
Respostas:
Esse é um truque muito geral, que pode ser usado para outros fins que não o hash. Abaixo, dou uma implementação (em pseudo-código).
Deixe três vetores não inicializados , P e V de tamanho n cada. Nós os usaremos para realizar as operações solicitadas por nossa estrutura de dados. Também mantemos uma variávelA P V n . As operações são implementadas da seguinte forma:pos
A matriz simplesmente armazena os valores que são passados pelo procedimento s e t . As matrizes V eA set V funcionam como certificados que podem dizer se uma determinada posição em A foi inicializada.P A
Observe que a cada momento os elementos em variando de 0 a p o s - 1, são inicializados. Estamos, portanto, pode usar com segurança esses valores como um certificado para os valores inicializados em A . Para cada posição i em A que é inicializada, há um elemento correspondente no vetor P cujo valor é igual a i . Isso é apontado por V [ i ] . Portanto, se olharmos para o elemento correspondente, P [ V [ i ] ] e seu valor é iP 0 pos−1 A i A P i V[i] P[V[i]] i , sabemos que foi inicializado (já que P nunca mente, porque todos os elementos que estamos considerando são inicializados). Da mesma forma, se A [ i ] não for inicializado, V [ i ] poderá apontar para uma posição em P fora do intervalo 0 .. p o s - 1 , quando tivermos certeza de que não foi inicializado ou apontar para uma posição dentro desse intervalo. Mas este P [ j ] em particular corresponde a uma posição diferente em A e, portanto,A[i] P A[i] V[i] P 0..pos−1 P[j] A , então sabemos que A [ i ] não foi inicializado.P[j]≠i A[i]
É fácil ver que todas essas operações são feitas em tempo constante. Além disso, o espaço utilizado é para cada um dos vetores e O ( 1 ) para a variável p o s , portanto O ( n ) no total.O(n) O(1) pos O(n)
fonte