Qual é a diferença entre "recursão" e "auto-referência"?

8

Os artigos da Wikipedia são avançados demais para eu entender. Alguém poderia me dar uma explicação simples, por favor?

skullpatrol
fonte
2
eles não são termos realmente comparáveis. recursionrefere-se a uma função que se chama enquanto que self-referencese refere a um objeto que se refere a si mesmo.
Jakob Weisblat 4/13/13
2
@GerryMyerson, seria correto dizer que a recursão se chama; enquanto a auto-referência se refere a si mesma?
skullpatrol
1
@skullpatrol essencialmente sim, mas sinto que você está perdendo uma diferença fundamental - eles não podem se aplicar ao mesmo tipo de coisa.
Jakob Weisblat
1
não. A referência própria refere-se a um objeto que se refira (consulte o artigo da wikipedia sobre OOP), em que recursão se refere a uma função, ou método, e não a um objeto.
Jakob Weisblat
4
@ Jake223 Eu sei de onde você é, mas você também pode dizer que uma estrutura como uma lista vinculada é definida recursivamente (a definição tem um caso base e uma etapa recursiva), e não há dúvida de que funções recursivas são autorreferenciais .
Caleb

Respostas:

14

O contexto dos dois termos é geralmente diferente.

A auto-referência está no contexto dos dados - você tem um tipo de dados que contém uma referência a algo do mesmo tipo.

A recursiva está no contexto do código - você tem uma função ou procedimento que se chama.

Exemplo:

def factorial(n):
if n == 1:
    return 1
else:
    return n * factorial(n-1)
jmoreno
fonte
Aqui estão as duas definições de tags no Stack Overflow: A recursão na ciência da computação é um método de solução de problemas em que a solução para um problema depende de soluções para instâncias menores do mesmo problema. Auto-referência é a capacidade de um programa (ou sentença lógica) se referir a si mesmo, direta ou indiretamente.
skullpatrol
E para tags, isso parece certo. Você não quer entrar em caixas de canto estranhas para uma tag. E provavelmente é sobre o nível em que você deseja pensar agora também.
jmoreno
10

Aqui está uma função recursiva (em C):

unsigned int fibonacci(unsigned int n)
{
    unsigned int result = 1;

    if (n > 1)
        result = fibonacci(n - 1) + fibonacci(n - 2);

    return result;
}

Essas duas chamadas para fibonacci()dentro da fibonacci()função são chamadas recursivas .

Aqui está uma estrutura de dados auto-referencial :

struct ListNode {
    char *data;
    struct ListNode *next;
}

O primeiro elemento,, dataé apenas um ponteiro para algum tipo de dado. O segundo elemento,, nexté um ponteiro para outra ListNodeestrutura. Se você tiver duas ou mais ListNodeestruturas, poderá definir o nextponteiro de uma para o endereço de outra, e assim por diante, e então terá uma lista vinculada . A estrutura é auto-referencial porque a definição da estrutura se refere a si mesma. Se você quiser ficar realmente louco, você pode fazer o seguinte:

struct ListNode *node = malloc(sizeof(struct ListNode));
node->data = someString;
node->next = node;

Agora você tem um tipo diferente de auto-referência - não é apenas a definição struct ListNodeque se refere a si mesma ... você definiu o nextponteiro nodepara apontar para nodesi mesmo. Esta é uma lista vinculada circular que contém apenas um elemento. Bonito, mas não muito útil. Menciono isso porque é um tipo de auto-referência, mas não é o que as pessoas geralmente querem dizer quando falam sobre tipos de dados auto-referenciais.

Caleb
fonte
1
É correto dizer que a recursão é um caso especial de auto-referência em que o objeto que está sendo referido (ou chamado) é uma função?
Skullpatrol
2
Claro, você poderia dizer que uma chamada recursiva é uma forma de auto-referência. Às vezes, os termos são quase intercambiáveis, embora não com relação ao código. Por exemplo, a maioria das pessoas chamaria "GNU" de "acrônimo recursivo" porque significa "GNU não é Unix", mas ninguém diria que você estava errado se o chamasse de "acrônimo auto-referencial".
Caleb
@ Caleb Este não é um exemplo particularmente bom, porque List é um tipo de dados recursivo . Então você está realmente mostrando outro exemplo de recursão!
Andrés F.
@AndresF. Você pode dar um exemplo de uma estrutura de dados autorreferencial que não é um tipo de dados recursivo? Fontes como essa e essa usam o termo 'auto-referencial' para estruturas como listas vinculadas, enquanto outras usam 'recursiva'. Se minha resposta falha em fazer uma distinção clara entre os termos, é porque os termos não são exatamente sinônimos, mas têm um significado muito próximo.
Caleb
@ Caleb Opa, desculpe. Se você está dizendo que eles têm um significado muito próximo, concordamos e eu o entendi mal!
Andres F.
6

Espera-se que as recursões, principalmente as úteis, sejam encerradas após certo número de procedimentos, no sentido de que há algum valor inicial. a menos que você tenha uma recursão ruim que é inútil.

As auto-referências, por si só, não são exatamente recursões, mas podem ser mostradas como recursivas, caso em que geralmente nunca terminam.


fonte
5
Se você definir recursão como uma construção sendo transportada por uma relação bem fundamentada, o fato de uma recursão não terminar corresponderá a uma sequência decrescente infinita - e, portanto, a "recursão" auto-referencial não é de todo uma recursão. É muito parecido com o modo como um algoritmo é necessário para parar em algum momento.
5
E a afirmação: "Esta frase tem cinco palavras". É auto-referencial, mas não vejo nenhuma recursão ininterrupta. Também não acho que a recursão geralmente envolva auto-referência. Se você compilar uma função C recursiva no código de máquina binário, o código da máquina não terá nenhuma auto-referência. Eu acho que o máximo que você pode dizer é que uma auto-referência final é uma maneira possível de definir uma recursão.
2
Sim, esta minha explicação não é de forma alguma perfeita. Estou apenas tentando simplificar no caso "OP está tentando interpretar algumas referências próprias como recorrências". Não quero dizer que auto-referências são sempre recursões sem fim.
É correto dizer que a recursão é um caso especial de auto-referência em que o objeto que está sendo referido (ou chamado) é uma função?
skullpatrol
5

Recursão implica ação.

Exemplos:

  • uma função que se chama
  • uma regex executando uma correspondência * ou + (ou seja, repetitiva)

Tecnicamente, a recursão deve ter um estado de saída, mas não é um requisito.

A auto-referência implica estrutura.

Ex. Um método de instância que faz referência ao objeto ao qual está anexado.

Evan Plaice
fonte
2

A recursão requer algo para processar através da chamada do mesmo processo (geralmente com parâmetros diferentes). Mesmo que você frequentemente use funções e essas funções se autodenominam, elas tecnicamente entram em uma nova etapa que, por acaso, parece com o local de onde elas vieram.

Auto-referência significa que algo se refere a si mesmo. As classes podem ser autorreferenciais usando this, mas isso não é significativamente recursivo.

Telastyn
fonte
Portanto, a recursão requer um processo através da chamada do mesmo processo, enquanto a auto-referência é a "chamada de si mesma"?
skullpatrol
@skullpatrol - no. A auto-referência não exige que se chame o que é sempre.
Telastyn
Portanto, a recursão requer um processo através da chamada do mesmo processo, enquanto a auto-referência é a "referência de si mesma"?
skullpatrol