Olá Gisele, tudo bem com você?
quando você usa o próximo, fica celula.proximo, isso é uma propriedade?
Sim!, veja que no código de criação da classe Celula
temos:
def __init__(self):
self.conteudo = conteudo
self.proximo = None
O próximo tá armazenando o valor que eu inseri? Sempre ouço falar de referência nesse caso tbm é assim, se sim, quando a referência é utilizada?
Então hahahah, é justamente ai que está a referência!
O proximo
não armazena o valor que você inseriu, e sim uma referência para a pŕoxima célula
Vou te explicar com base nos seus exemplos:
Esse primeiro de javascript eu procurei a classe:
class LinkedListNode {
constructor(data) {
this.data = data;
this.next = null;
}
}
Veja que tanto nosso em python
quanto em javascript temos o this.next
que será utilizado para armazenar uma referência, que por padrão começa como null
ou None
Temos a primeira inserção:
const head = new LinkedListNode(12);
Então temos um objeto assim:
Endereço na memoria: 100
head: {
data: 12,
next: null,
}
Após isso temos a segunda inserção:
head.next = new LinkedListNode(99);
Ou seja vamos criar um novo objeto com:
Endereco na Memoria: 500
{
data: 99,
next: null
}
E como estamos atribuindo esse objeto a head.next
, teremos agora:
Endereço na memoria: 100
head: {
data: 12,
next: 500,
}
Então provavelmente aqui que há a confusão, estamos sempre armazenando uma referência na memória de onde está o próximo objeto, e por fim a ultima inserção:
head.next.next = new LinkedListNode(37);
Podemos ler isso como: Vá para o objeto que head.next
referencia, ou seja, pegue o endereço de memória que está armazenado em next
e vá para lá, chegando lá teremos um novo objeto, pegue o valor de next
e coloque o endereço de um novo elemento que iremos criar:
Endereco na memoria: 600
{
data: 37,
next: null,
}
Como head.next
aponta para o endereço de memória 500, e sabemos que la temos o nosso (99) :
Endereco na Memoria: 500
{
data: 99,
next: 600
}
Agora temos algo parecido com isso:
100 500 600
[ Valor: 12] -----------> [ Valor: 99] ----------> [Valor: 37]
[Prox: 500] | Prox: 600 | | Prox: null |
Se eu usar celula.proximo.proximo, eu vou para o terceiro item da lista? Se sim, porque acontece isso? Qual a diferença do python para o C que usa ponteiros nesse caso?
Sim, você irá porque o fluxo será o seguinte:
- Celula é a raiz da nossa lista ligada (ex: 12)
- Celula.proximo é uma referência para o endereço de memória 500 que é a segunda Celula ( 99)
- Celula.proximo.proximo é ir para o endereço de memória 500 e de lá pega ro
proximo
que também é uma referência na memóra ( Prox: 600) que nos leva a um objeto do tipo Celula com valor 37
Em relação a diferença de Python para C, com a estrutura de dados não muda nada, a única coisa é o processo de codificar, onde temos que identificar que estamos passando um endereço na memória, ou que estamos querendo acessar um endereço de memória
Com python e muitas linguagens orientadas a objetos esse processo de referenciar que é um endereço de memória é automático, quando dizemos que celula.proximo = new Celula(valor)
, para nós não pode ser tão claro quanto em C
mas de fato o que estamos colocando em celula.proximo
é um endereço da memória que aponta para o objeto que criamos :)
Outra coisa, porque no final o novo nó aponta para o head? Tá atribuindo o valor do novo item para o head? Isso que eu não consigo entender.
Vamos pegar aquele exemplo que trabalhei acima, e supor que temos uma função adicionaNoComeco
, igual na aula :)
Veja que nesses exemplos esse head
indica a cabeça da lista, ou seja, o primeiro elemento, e vou inserir agora mais um:
adicionaNoComeco( new LinkedListNode(50))
A primeira coisa que temos é que o nosso head
da lista Ligada, que no exemplo da aula é o inicio
, vale o endereço de memória 100 que é o objeto com valor 12
Então o primeiro passo é fazer é criar o novo objeto:
endereço na memoria: 850
{
data: 50,
prox: null,
}
Entretanto dizemos que esse objeto aponta para o valor de head
, então:
endereço na memoria: 850
{
data: 50,
prox: 100,
}
E agora já que meu objeto novo está referenciando o que era o primeiro elemento da lista, eu posso trocar o valor de head
, e atribuir para ele o endereço da memória dessa nova célula :)
{
head: 850
}
E agora temos corretamente:
head: 850
[ End: 850 | Valor: 50 | Prox: 100 ] -> [ End: 100 | Valor: 12 | Prox: 500] -> [End: 100 | Valor: 99 | Prox: 600] -> [End: 600 | Valor: 37 | Prox: Nulll]
Conseguiu compreender? Qualquer coisa estou a disposição :)
Abraços e Bons Estudos!