Estrutura de dados e algoritmos - árvore
A árvore representa os nós conectados por arestas. Discutiremos árvore binária ou árvore de busca binária especificamente.
Árvore binária é uma estrutura de dados especial usada para fins de armazenamento de dados. Uma árvore binária tem uma condição especial de que cada nó pode ter no máximo dois filhos. Uma árvore binária tem os benefícios de uma matriz ordenada e uma lista vinculada, pois a pesquisa é tão rápida quanto em uma matriz classificada e as operações de inserção ou exclusão são tão rápidas quanto em uma lista vinculada.
Termos importantes
A seguir estão os termos importantes com respeito à árvore.
Path - Caminho se refere à sequência de nós ao longo das bordas de uma árvore.
Root- O nó no topo da árvore é denominado raiz. Existe apenas uma raiz por árvore e um caminho do nó raiz para qualquer nó.
Parent - Qualquer nó, exceto o nó raiz, tem uma borda ascendente para um nó chamado pai.
Child - O nó abaixo de um determinado nó conectado por sua borda para baixo é chamado de nó filho.
Leaf - O nó que não possui nenhum nó filho é denominado nó folha.
Subtree - Subárvore representa os descendentes de um nó.
Visiting - A visita se refere à verificação do valor de um nó quando o controle está no nó.
Traversing - Atravessar significa passar pelos nós em uma ordem específica.
Levels- O nível de um nó representa a geração de um nó. Se o nó raiz está no nível 0, então seu próximo nó filho está no nível 1, seu neto está no nível 2 e assim por diante.
keys - A chave representa um valor de um nó com base no qual uma operação de pesquisa deve ser realizada para um nó.
Representação da árvore de busca binária
A árvore de pesquisa binária exibe um comportamento especial. O filho esquerdo de um nó deve ter um valor menor que o valor de seu pai e o filho direito do nó deve ter um valor maior que seu valor pai.
Vamos implementar árvore usando objeto de nó e conectá-los por meio de referências.
Nó de Árvore
O código para escrever um nó de árvore seria semelhante ao que é fornecido a seguir. Ele tem uma parte de dados e referências a seus nós filho esquerdo e direito.
struct node {
int data;
struct node *leftChild;
struct node *rightChild;
};
Em uma árvore, todos os nós compartilham uma construção comum.
Operações básicas de BST
As operações básicas que podem ser realizadas em uma estrutura de dados de árvore de pesquisa binária são as seguintes -
Insert - Insere um elemento em uma árvore / cria uma árvore.
Search - Pesquisa um elemento em uma árvore.
Preorder Traversal - Atravessa uma árvore de forma pré-encomenda.
Inorder Traversal - Percorre uma árvore de maneira ordenada.
Postorder Traversal - Percorre uma árvore de maneira pós-ordem.
Devemos aprender a criar (inserir em) uma estrutura de árvore e pesquisar um item de dados em uma árvore neste capítulo. Aprenderemos sobre os métodos de travessia de árvores no próximo capítulo.
Operação de inserção
A primeira inserção cria a árvore. Depois, sempre que um elemento for inserido, primeiro localize seu local apropriado. Comece a pesquisar a partir do nó raiz e, em seguida, se os dados forem menores que o valor-chave, procure o local vazio na subárvore esquerda e insira os dados. Caso contrário, pesquise o local vazio na subárvore certa e insira os dados.
Algoritmo
If root is NULL
then create root node
return
If root exists then
compare the data with node.data
while until insertion position is located
If data is greater than node.data
goto right subtree
else
goto left subtree
endwhile
insert data
end If
Implementação
A implementação da função de inserção deve ser semelhante a esta -
void insert(int data) {
struct node *tempNode = (struct node*) malloc(sizeof(struct node));
struct node *current;
struct node *parent;
tempNode->data = data;
tempNode->leftChild = NULL;
tempNode->rightChild = NULL;
//if tree is empty, create root node
if(root == NULL) {
root = tempNode;
} else {
current = root;
parent = NULL;
while(1) {
parent = current;
//go to left of the tree
if(data < parent->data) {
current = current->leftChild;
//insert to the left
if(current == NULL) {
parent->leftChild = tempNode;
return;
}
}
//go to right of the tree
else {
current = current->rightChild;
//insert to the right
if(current == NULL) {
parent->rightChild = tempNode;
return;
}
}
}
}
}
Operação de Pesquisa
Sempre que um elemento deve ser pesquisado, comece a pesquisar a partir do nó raiz e, em seguida, se os dados forem menores que o valor-chave, procure o elemento na subárvore esquerda. Caso contrário, procure o elemento na subárvore certa. Siga o mesmo algoritmo para cada nó.
Algoritmo
If root.data is equal to search.data
return root
else
while data not found
If data is greater than node.data
goto right subtree
else
goto left subtree
If data found
return node
endwhile
return data not found
end if
A implementação deste algoritmo deve ser semelhante a esta.
struct node* search(int data) {
struct node *current = root;
printf("Visiting elements: ");
while(current->data != data) {
if(current != NULL)
printf("%d ",current->data);
//go to left tree
if(current->data > data) {
current = current->leftChild;
}
//else go to right tree
else {
current = current->rightChild;
}
//not found
if(current == NULL) {
return NULL;
}
return current;
}
}
Para saber mais sobre a implementação da estrutura de dados da árvore de pesquisa binária, clique aqui .