Você pode pensar em algum motivo específico pelo qual a exclusão geralmente é significativamente mais difícil de implementar do que a inserção para muitas (a maioria?) Estruturas de dados?
Exemplo rápido: listas vinculadas. A inserção é trivial, mas a exclusão tem alguns casos especiais que tornam significativamente mais difícil. Árvores de pesquisa binária com auto balanceamento, como AVL e Vermelho-preto, são exemplos clássicos de implementação de exclusão dolorosa.
Eu gostaria de dizer que tem a ver com a maneira como as pessoas pensam: é mais fácil para nós definir as coisas de forma construtiva, o que leva muito a inserções fáceis.
algorithms
data-structures
Leo Brito
fonte
fonte
pop
,extract-min
?Respostas:
É mais do que apenas um estado de espírito; existem razões físicas (ou seja, digitais) pelas quais a exclusão é mais difícil.
Quando você exclui, deixa um buraco onde costumava estar. O termo técnico para a entropia resultante é "fragmentação". Em uma lista vinculada, isso exige que você "remova" o nó removido e desaloque a memória que está usando. Em árvores binárias, causa desequilíbrio da árvore. Nos sistemas de memória, ela faz com que a memória não seja usada por algum tempo se os blocos recém-alocados forem maiores que os blocos deixados para trás pela exclusão.
Em resumo, a inserção é mais fácil porque você escolhe onde deseja inserir. A exclusão é mais difícil, porque você não pode prever com antecedência qual item será excluído.
fonte
Por que é mais difícil excluir do que inserir? As estruturas de dados são projetadas mais com a inserção em mente do que com a exclusão, e com razão.
Considere isso - para excluir algo de uma estrutura de dados, ele deve estar lá em primeiro lugar. Portanto, você precisa adicioná-lo primeiro, o que significa que, no máximo, você tem tantas exclusões quanto inserções. Se você otimizar uma estrutura de dados para inserção, terá a garantia de obter pelo menos o mesmo benefício que se tivesse sido otimizado para exclusão.
Além disso, de que serve a exclusão seqüencial de cada elemento? Por que não chamar uma função que a limpa de uma só vez (possivelmente apenas criando uma nova)? Além disso, as estruturas de dados são mais úteis quando na verdade contêm algo. Portanto, o caso de ter tantas exclusões quanto inserções, na prática, não será muito comum.
Quando você otimiza algo, deseja otimizar as coisas que mais fazem e que levam mais tempo. No uso normal, a exclusão de elementos de uma estrutura de dados ocorre com menos frequência do que a inserção.
fonte
k
de elementos rapidamente: inverter a entrada de classificação e mesclar com o vetor existente -O(k log k + n)
. Então você tem uma estrutura com inserção bastante complicada, mas consumir os principaisu
elementos é trivial e rápido. Basta pegar por últimou
e mover o final do vetor. No entanto, se alguém precisar de algo assim, eu serei amaldiçoado. Espero que isso ao menos reforce seu argumento.Não é mais difícil.
Com listas duplamente vinculadas, quando você insere, alocará memória e, em seguida, vinculará à cabeça ou ao nó anterior e à cauda ou ao nó seguinte. Ao excluir, você desvinculará exatamente da mesma e liberará memória. Todas essas operações são simétricas.
Isso pressupõe que, nos dois casos, você tenha o nó para inserir / excluir. (E, no caso da inserção, que você também tem o nó para inserir antes, de certa forma, a inserção pode ser considerada um pouco mais complicada.) Se você estiver tentando excluir, não tendo o nó a excluir, mas a carga útil do nó, é claro que você terá que pesquisar primeiro na lista a carga útil, mas isso não é uma falha de exclusão, é?
Com árvores balanceadas, o mesmo se aplica: uma árvore geralmente precisa ser balanceada imediatamente após uma inserção e também imediatamente após uma exclusão. É uma boa idéia tentar ter apenas uma rotina de balanceamento e aplicá-la após cada operação, independentemente de se tratar de uma inserção ou exclusão. Se você está tentando implementar uma inserção que sempre deixa a árvore equilibrada e também uma exclusão que sempre a deixa equilibrada, sem que os dois compartilhem a mesma rotina de equilíbrio, você está desnecessariamente complicando sua vida.
Em suma, não há razão para que um seja mais difícil que o outro, e se você estiver descobrindo que é, é possível que você seja vítima da tendência (muito humana) de achar mais natural pensar de forma construtiva e subtraída, o que significa que você pode estar implementando a exclusão de uma maneira mais complicada do que precisa. Mas isso é uma questão humana. Do ponto de vista matemático, não há problema.
fonte
Em termos de tempo de execução, observando a comparação da complexidade de tempo das operações da estrutura de dados na Wikipedia, observe que as operações de inserção e exclusão têm a mesma complexidade. A operação de exclusão perfilada é excluída por índice, onde você tem uma referência ao elemento de estrutura a ser excluído; inserção é por item. O tempo de execução mais longo para exclusão na prática é porque você geralmente tem um item para excluir e não seu índice, portanto, você também precisa de uma operação de localização. A maioria das estruturas de dados na tabela não exige uma localização adicional para uma inserção porque a posição da veiculação não depende do item ou a posição é determinada implicitamente durante a inserção.
Quanto à complexidade cognitiva, há uma resposta na pergunta: casos extremos. A exclusão pode ter mais do que inserção (isso ainda não foi estabelecido no caso geral). No entanto, pelo menos alguns desses casos extremos podem ser evitados em determinados projetos (por exemplo, ter um nó sentinela em uma lista vinculada).
fonte
Além de todos os problemas mencionados, há integridade referencial de dados envolvida. Para criar a estrutura de dados mais adequada, como bancos de dados em SQL, a integridade referencial da Oracle é muito importante.
Para garantir que você não o destrua acidentalmente, muitas coisas diferentes foram inventadas.
Por exemplo, cascata ao excluir, que não apenas exclui o que você tenta excluir, mas também aciona a limpeza dos dados relacionados.
Isso limpa o banco de dados a partir de dados indesejados e mantém intacta a integridade dos dados.
Por exemplo, você tem tabelas com pais e tipos como registros relacionados na segunda tabela.
Onde pai é a tabela principal. Se você não tiver integridade referencial reforçada, poderá excluir todos os registros de qualquer tabela e, posteriormente, não saberia como obter informações completas da família, pois possui dados na tabela filho e nada na tabela pai.
É por isso que a verificação de integridade referencial não permite excluir o registro da tabela pai até que os registros da tabela filho sejam limpos.
E é por isso que na maioria das fontes de dados é mais difícil excluir dados.
fonte