Em vez de numeração simples, você pode distribuir os números por um intervalo grande (de tamanho constante), como número inteiro mínimo e máximo de um número inteiro da CPU. Então você pode continuar colocando os números "no meio" calculando a média dos dois números ao redor. Se os números ficarem muito lotados (por exemplo, você acabará com dois números inteiros adjacentes e não houver um número intermediário), poderá renumerar uma vez toda a ordem inteira, redistribuindo os números uniformemente no intervalo.
Obviamente, você pode ter a limitação de que todos os números dentro do intervalo da constante grande são usados. Em primeiro lugar, isso geralmente não é um problema, pois o tamanho inteiro em uma máquina é grande o suficiente para que, se você tivesse mais elementos, provavelmente não caberia na memória. Mas se for um problema, você pode simplesmente renumerá-los com um intervalo inteiro maior.
Se a ordem de entrada não for patológica, esse método poderá amortizar as renumerações.
Responder a consultas
Uma simples comparação de números inteiros pode responder à consulta (X<?Y).
O tempo de consulta seria muito rápido ( O(1)) se estiver usando números inteiros da máquina, pois é uma comparação inteira simples. Usar um intervalo maior exigiria números inteiros maiores e a comparação levariaO(log|integer|).
Inserção
Em primeiro lugar, você manteria a lista vinculada da ordem, demonstrada na pergunta. A inserção aqui, dados os nós para colocar o novo elemento no meio, seriaO(1).
Rotular o novo elemento geralmente seria rápido O(1)porque você calcularia o novo número facilmente, calculando a média dos números ao redor. Ocasionalmente, você pode ficar sem números "no meio", o que acionaria oO(n) procedimento de renumeração de tempo.
Evitando renumeração
Você pode usar flutuadores em vez de números inteiros; portanto, quando você obtém dois números inteiros "adjacentes", eles podem ser calculados como média. Assim, você pode evitar a renumeração ao enfrentar dois números inteiros: apenas divida-os ao meio. No entanto, eventualmente, o tipo de ponto flutuante ficará sem precisão e dois flutuadores "adacentes" não poderão ser calculados pela média (a média dos números circundantes provavelmente será igual a um dos números circundantes).
Da mesma forma, você pode usar um número inteiro "casa decimal", onde você mantém dois números inteiros para um elemento; um para o número e um para o decimal. Dessa forma, você pode evitar a renumeração. No entanto, o número inteiro decimal eventualmente excederá.
Usar uma lista de números inteiros ou bits para cada rótulo pode evitar completamente a renumeração; isso é basicamente equivalente ao uso de números decimais com comprimento ilimitado. A comparação seria feita lexicograficamente, e os tempos de comparação aumentarão para o comprimento das listas envolvidas. No entanto, isso pode desequilibrar a rotulagem; alguns rótulos podem exigir apenas um número inteiro (sem decimal), outros podem ter uma lista de comprimento longo (decimais longos). Isso é um problema e a renumeração também pode ajudar aqui, redistribuindo a numeração (aqui listas de números) uniformemente em um intervalo escolhido (intervalo aqui possivelmente significando o comprimento das listas) para que, após essa renumeração, as listas tenham o mesmo comprimento .
Este método é realmente usado neste algoritmo ( implementação , estrutura de dados relevante ); no decorrer do algoritmo, uma ordem arbitrária deve ser mantida e o autor usa números inteiros e renumeração para fazer isso.
Tentar manter os números torna seu espaço chave um pouco limitado. Pode-se usar seqüências de comprimento variável, usando a lógica de comparação "a" <"ab" <"b". Ainda há dois problemas a serem resolvidos A. As chaves podem se tornar arbitrariamente longas B. A comparação de chaves longas pode se tornar cara