Segundo a Wikipedia, uma pilha :
é o último tipo de dados abstratos e estrutura de dados linear (LIFO).
Enquanto uma matriz :
é uma estrutura de dados que consiste em uma coleção de elementos (valores ou variáveis), cada um identificado por pelo menos um índice ou chave de matriz.
Tanto quanto eu entendo, eles são bastante semelhantes. Então, quais são as principais diferenças? Se eles não são os mesmos, o que uma matriz pode fazer que uma pilha não pode e vice-versa?
data-structures
array
stack
Dinâmico
fonte
fonte
Respostas:
Bem, certamente você pode implementar uma pilha com uma matriz. A diferença está no acesso. Em uma matriz, você tem uma lista de elementos e pode acessar qualquer um deles a qualquer momento. (Pense em um monte de blocos de madeira dispostos em uma fileira.)
Mas em uma pilha, não há operação de acesso aleatório; há apenas
Push
,Peek
ePop
, todos os quais lidam exclusivamente com o elemento no topo da pilha. (Pense nos blocos de madeira empilhados verticalmente agora. Você não pode tocar em nada abaixo do topo da torre ou ela cairá.)fonte
Em uma pilha pura, as únicas operações permitidas são
Push
,Pop
e,Peek
mas em termos práticos, isso não é exatamente verdade. Ou melhor, aPeek
operação geralmente permite que você olhe para qualquer posição da pilha, mas o problema é que ela é relativa à única extremidade da pilha.Então, como outros já disseram, uma matriz é de acesso aleatório e tudo é referenciado no início da matriz .
Em uma pilha, você só pode adicionar / remover no final de trabalho da pilha, mas você ainda tem acesso aleatório, mas é referenciado ao final de trabalho . Essa é a diferença fundamental.
Por exemplo, quando você passa parâmetros em uma pilha para uma função, o receptor não precisa exibir os parâmetros para vê-los. Ele apenas empurra variáveis locais na pilha e faz referência a todas as variáveis e parâmetros locais com base em um deslocamento do ponteiro da pilha. Se você estivesse usando apenas uma matriz, como o receptor saberia onde procurar por seus parâmetros? Quando o chamado é concluído, ele exibe suas variáveis locais, pressiona um valor de retorno, retorna o controle para o chamador e o chamador exibe o valor de retorno (se houver) e, em seguida, os parâmetros da pilha. O bom é que ele funciona, não importa o quão aninhado você esteja em suas chamadas de função (supondo que você não fique sem espaço na pilha).
Esse é um uso / implementação específico, mas ilustra a diferença: a matriz é sempre referenciada desde o início, mas as pilhas são sempre referenciadas em alguma posição final de trabalho.
Uma possível implementação de uma pilha é uma matriz mais um índice para lembrar onde está o final de trabalho.
fonte
Eu acho que a maior confusão que está acontecendo aqui é a implementação versus estruturas básicas de dados.
Na maioria (linguagens mais básicas), uma matriz representa um conjunto de elementos de tamanho fixo que você pode acessar em um determinado momento. O fato de você ter vários elementos como esse não diz nada sobre como ele deve ser usado (e, francamente, um computador não sabe / se importa com o uso, contanto que você não viole o uso).
Uma pilha é uma abstração usada para representar dados que devem ser tratados de uma certa maneira. Este é um conceito abstrato, porque apenas diz que precisa ter alguma sub-rotina / método / função que possa ser adicionada ou removida da parte superior, enquanto os dados abaixo da parte superior não são tocados. É sua escolha usar uma matriz dessa maneira.
Você pode criar uma pilha com muitos tipos diferentes de estruturas de dados: matrizes (com algum tamanho máximo), matrizes dinâmicas (podem crescer quando estiver sem espaço) ou listas vinculadas. Pessoalmente, acho que uma lista vinculada representa as restrições de uma pilha da melhor maneira possível, pois você precisa se esforçar um pouco para ver as coisas além do primeiro elemento e é muito fácil adicionar à frente e remover da frente.
Então você pode usar uma matriz para criar uma pilha, mas elas não são equivalentes
fonte
A pilha deve ser capaz de inserir elementos na pilha e empurrá-los da pilha, daí o motivo pelo qual normalmente possui métodos
Pop()
ePush()
A responsabilidade da matriz é obter / definir o elemento em um índice especificado
fonte
Você pode recuperar um item de qualquer índice de uma matriz A \.
Com uma pilha, você pode recuperar um item no meio da pilha A, usando outra pilha: B.
Você continua tirando o item superior de A e colocando-o em B até chegar ao item desejado de A, depois coloca os itens de B novamente no topo da pilha A.
Portanto, para dados que exigem a capacidade de recuperar um índice arbitrário, é mais difícil trabalhar com a pilha.
Na situação em que você deseja o comportamento "último a entrar, primeiro a sair", uma pilha fornecerá menos sobrecarga que uma matriz.
fonte
Eu não chegaria ao ponto de dizer que eles são "muito parecidos".
Uma matriz é usada para armazenar coisas que serão acessadas posteriormente sequencialmente ou através do índice. A estrutura de dados não implica nenhum tipo de método de acesso (FIFO, LIFO, FILO, etc ...), mas pode ser usada dessa maneira, se você quiser.
Uma pilha é uma maneira de rastrear as coisas conforme elas são geradas. Um método de acesso é implícito / necessário, dependendo do tipo de pilha criada. Uma pilha de quadros seria um exemplo LIFO. Isenção de responsabilidade - posso estar misturando minha taxonomia de estrutura de dados aqui e uma pilha pode realmente permitir apenas o LIFO. Caso contrário, seria um tipo diferente de fila.
Então, eu poderia usar uma matriz como uma pilha (embora não desejasse), mas não posso usar uma pilha como uma matriz (a menos que eu trabalhe muito nisso).
fonte
Os dados em uma matriz podem ser acessados por uma chave ou índice. Os dados em uma pilha podem ser acessados quando são retirados da parte superior da pilha. Isso significa que acessar dados de uma matriz é fácil se você conhece seu índice. Acessar dados de uma pilha significa que você deve continuar aparecendo elementos até encontrar o que estava procurando, o que significa que o acesso a dados pode demorar mais tempo.
fonte
Uma matriz é da perspectiva dos programadores, fixa no local e no tamanho, você sabe onde está e onde está a coisa toda. Você tem acesso a tudo isso.
Com uma pilha, você fica sentado em uma das extremidades, mas não tem idéia do tamanho ou do quão longe pode ir com segurança. Seu acesso a ele é limitado à quantia que você alocou, muitas vezes você nem sabe se, ao alocar a quantia que queria, se tivesse acabado de bater no heap ou no espaço do programa. Sua visão de uma pilha é uma pequena matriz que você alocou, o tamanho que você queria, você tem controle e pode ver. Sua parte não é diferente de uma matriz. A diferença é que sua matriz está presa a uma extremidade de outra matriz por razões de argumento e terminologia, das quais você não tem visibilidade, não tem idéia de quão grande ou pequeno, e você não pode tocá-la sem causar danos. Uma matriz, a menos que global, é geralmente implementada na pilha de qualquer maneira, portanto, a matriz e a pilha compartilham o mesmo espaço pela duração dessa função.
Se você deseja entrar no lado do hardware, é claro que é específico do processador, mas geralmente a matriz é baseada em um ponto / endereço de partida conhecido, o tamanho é conhecido pelo compilador / programador e os endereços são computados, às vezes, usando o endereçamento de deslocamento de registro (carrega um valor do endereço definido por esse valor de registro base mais esse valor de registro de deslocamento, da mesma forma que quando compilado, poderia ser um deslocamento imediato, não necessariamente baseado em registro, depende do processador, é claro) que na montagem se assemelha a acessar uma matriz em código de alto nível. Da mesma forma, com a pilha, se disponível, você pode usar o registro ou o endereçamento de deslocamento imediato, geralmente usando um registro especial, o próprio ponteiro da pilha ou um registro reservado pelo compilador / programador a ser usado para acessar o quadro da pilha para esse função. E para alguns processadores, funções especiais de acesso à pilha são usadas e / ou necessárias para acessar a pilha. Você tem instruções push e pop, mas elas não são usadas com a frequência que você imagina e realmente não se aplicam a essa pergunta. Para alguns processadores, push e pop são aliases de instruções que podem ser usadas com qualquer registrador, em qualquer lugar, não apenas com o ponteiro da pilha na pilha, removendo ainda mais o push e pop de serem relacionados a esta pergunta.
fonte