A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Árvores de Busca. 2 Uma árvore que suporta eficientes operações de busca, inclusão e exclusão é chamada de árvore de busca. A árvore é usada para armazenar.

Apresentações semelhantes


Apresentação em tema: "Árvores de Busca. 2 Uma árvore que suporta eficientes operações de busca, inclusão e exclusão é chamada de árvore de busca. A árvore é usada para armazenar."— Transcrição da apresentação:

1 Árvores de Busca

2 2 Uma árvore que suporta eficientes operações de busca, inclusão e exclusão é chamada de árvore de busca. A árvore é usada para armazenar um conjunto finito de chaves obtidas de um conjunto totalmente ordenado de chaves K. Cada nó da árvore contém um ou mais chaves e todas as chaves na árvore são únicas, sem duplicação. A diferença entre uma árvore comum e uma árvore de busca é que, nesta última, as chaves não aparecem em nós arbitrários. Existe um critério de ordenação de dados que determina aonde cada chave pode figurar na árvore em relação às demais. Serão apresentadas as árvores de busca: de M caminhos (M-Way) binárias.

3 3 Binary Search Tree (BST) Definição (Árvore de busca M-way) Uma árvore de busca M-way T é um conjunto finito de chaves. Ou o conjunto é vazio, T = ; ou o conjunto é constituído de n sub árvores M-way T 1, T 2,..., T n-1, e n-1 chaves, k 1, k 2,..., k n-1, T = {T 0,k 1, T 1, k 2,..., k n-1, T n-1 } aonde 2 n M, tal que as chaves e os nós satisfaçam às seguintes propriedades de ordenação de dados: As chaves em cada nó são distintas e ordenadas, i.e., k i

4 4 Exemplo de árvore de busca M-Way

5 5 Binary Search Tree (BST) Definição (Árvore Binária de Busca) A Árvore Binária de Busca T é um conjunto finito de chaves. Ou o conjunto é vazio, T = ; ou o conjunto consiste da raiz r e exatamente duas Árvores Binárias de Busca T L e T R, T={r,T L,T R }, tais que as seguintes propriedades sejam satisfeitas: 1. Todas as chaves contidas na sub árvore da esquerda, T L, são menores do que r. 2. Todas as chaves contidas na sub árvore da direita, T R, são maiores do que r.

6 6 Exemplo de árvore binária de busca

7 7 Busca em Árvores de Busca M-Way Busca do objeto x inicia na raiz Se a raiz estiver vazia a busca falha As chaves contidas na raiz são examinadas para verificar se o objeto buscado está presente Se o objeto não estiver presente três casos podem ocorrer: Objeto buscado é menor do que k 1 a busca prossegue em T 0 ; Objeto buscado é maior do que k n-1 a busca prossegue em T n-1 ; Existe um i tal que k i < x < k i+1 a busca prossegue em T i

8 8 Busca em Árvores Binárias de Busca Semelhante à busca em árvores de busca M-Way Apenas cada nó só possui um objeto e duas sub árvores

9 9 Árvore Binária Perfeita Definição (Árvore Binária Perfeita) A Árvore Binária Perfeita de altura h 0 é um árvore binária T={r,T L,T R } com as propriedades: 1. Se h=0, então T L = e T R =. 2. Caso contrário, h>0, caso no qual ambos T L e T R são Árvores Binárias Perfeitas de altura h -1.

10 Implementação Java

11 11 Implementação de Árvores de Busca

12 12 Interface SearchTree // pgm10_01.java public interface SearchTree extends Tree, SearchableContainer { Comparable findMin (); Comparable findMax (); }

13 13 Classe BinarySearchTree // pgm10_02.java public class BinarySearchTree extends BinaryTree implements SearchTree { //... }

14 14 Classe Association public class Association extends AbstractObject { protected Comparable key; protected Object value; //... } // só aparece por causa de getKey

15 15 Métodos da Classe Association public class Association extends AbstractObject { protected Comparable key; protected Object value; public Association (Comparable key, Object value) { this.key = key; this.value = value; } public Association (Comparable key) { this (key, null); } public Comparable getKey () { return key; } public Object getValue () { return value; } //... }

16 16 Métodos da Classe BinarySearchTree getLeftBST getRightBST find findMin insert attachKey balance withdraw

17 17 Métodos getLeftBST e getRightBST // pgm10_03.java public class BinarySearchTree extends BinaryTree implements SearchTree { private BinarySearchTree getLeftBST() { return (BinarySearchTree) getLeft(); } private BinarySearchTree getRightBST() { return (BinarySearchTree) getRight(); } //... }

18 18 Método find // pgm10_04.java public class BinarySearchTree extends BinaryTree implements SearchTree { public Comparable find (Comparable object) { if(isEmpty()) return null; int diff = object.compare((Comparable) getKey()); if(diff == 0) return (Comparable) getKey(); else if(diff < 0) return getLeftBST().find(object); else return getRightBST().find(object); }

19 19 Método findMin public Comparable findMin () { if(isEmpty()) return null; else if(getLeftBST().isEmpty()) return (Comparable) getKey(); else return getLeftBST().findMin(); } //...

20 20 Inserção de itens em BST A inclusão de nós em árvores de busca deve ser precedida de uma operação de busca. Esta operação indica se o nó buscado já existe na árvore e, em caso de não existência, o local aonde deve ser feita a inclusão. Convém lembrar que uma busca sempre termina em folha e os nós a incluir serão incluídos como filhos da folha aonde se encerrou a busca.

21 21 Método insert (1) // pgm10_05.java public class BinarySearchTree extends BinaryTree implements SearchTree { public void insert (Comparable object) { if(isEmpty()) attachKey (object);

22 22 Método insert (2) else { int diff = object.compare((Comparable) getKey()); if(diff == 0) throw new IllegalArgumentException( chave duplicada"); if(diff < 0) getLeftBST().insert(object); else getRightBST().insert(object); } balance(); }

23 23 Métodos attachKey e balance public void attachKey (Object object) { if(!isEmpty()) throw new InvalidOperationException(); key = object; left = new BinarySearchTree(); right = new BinarySearchTree(); } protected void balance() {}

24 24 Remoção de itens em BST A exclusão de nós em árvores de busca pode configurar um de 3 casos. Se o nó não tiver filhos pode ser excluído sem exigir ajustamento da árvore. Se o nó a excluir tiver apenas uma sub árvore, este nó pode ser excluído e deve ser substituído por seu filho único. Se o nó a excluir tiver mais de um filho, para que ele possa ser excluído, deve ser substituído por seu antecessor ou seu sucessor em ordem infixa. O nó substituto deve ser excluído da sua posição gerando outro processo de exclusão. Considerando o caso do sucessor em ordem infixa, o nó a ser excluído deve ser substituído pelo nó obtido alcançando-se o nó mais à esquerda da sub árvore direita do nó a excluir.

25 25 Remoção de itens em BST Remoção do nó (4) folha em BST Remoção do nó (1) não folha em BST

26 26 Método withdraw (1) // pgm10_06.java public class BinarySearchTree extends BinaryTree implements SearchTree { public void withdraw (Comparable object) { if(isEmpty()) throw new IllegalArgumentException( "objeto não encontrado"); int diff = object.compare ((Comparable) getKey()); if(diff == 0) { if(!getLeftBST().isEmpty()) { Comparable max = getLeftBST().findMax(); key = max; getLeftBST().withdraw(max); }

27 27 Método withdraw (2) else if(!getRightBST().isEmpty()) { Comparable min = getRightBST().findMin(); key = min; getRightBST().withdraw(min); } else detachKey(); } else if(diff < 0) getLeftBST().withdraw(object); else getRightBST().withdraw(object); balance(); } //... }

28 Árvores de Busca AVL

29 29 Conceito de AVL Adelson-Velskii e Landis propuseram as condições de balanceamento para uma árvore binária que recebeu como sigla suas iniciais. Definição (Condição de equilíbrio AVL) Uma árvore binária vazia é AVL balanceada. Uma árvore binária não-vazia, T={r,T L,T R }, é AVL balanceada se tanto T L quanto T R forem AVL balanceadas e |h L - h R |<=1 aonde h L é a altura of T L e h R é a altura of T R.

30 Implementação de árvores AVL

31 31 Classe AVLTree // pgm10_07.java public class AVLTree extends BinarySearchTree { protected int Height; //... }

32 32 Construtor // pgm10_08.java public class AVLTree extends BinarySearchTree { protected int Height; public AVLTree() { Height = -1; } //... }

33 33 Métodos getHeight, adjustHeight e getBalanceFactor public int getHeight () { return Height; } protected void adjustHeight() { if(isEmpty()) Height = -1; else Height = 1 + Math.max(left.getHeight(), right.getHeight()); } protected int getBalanceFactor() { if(isEmpty()) return 0; else return left.getHeight() - right.getHeight(); }

34 34 Inserção de itens em Árvores AVL 1 o. Passo – Inserir o item 2 o. Passo – Balancear a árvore

35 35 Balanceamento de Árvores AVL O balanceamento de árvores AVL é feito por operações chamadas de rotações, que podem ser: Rotações simples (LL e RR) Rotações duplas (LR e RL)

36 36 Rotações simples A rotação LL ocorre quando um nó (B) tem a sub árvore da esquerda maior do que a da direita e seu filho da esquerda (A) tem sub árvore da esquerda maior do que a da direita A rotação RR ocorre quando um nó (B) tem a sub árvore da direita maior do que a da esquerda e seu filho da direita (A) tem sub árvore da direita maior do que a da esquerda

37 37 Rotações duplas A rotação LR ocorre quando um nó (C) tem a sub árvore da esquerda maior do que a da direita e seu filho da esquerda (A) tem sub árvore da direita maior do que a da esquerda. Aplica-se uma rotação RR a A seguida de uma rotação LL aplicada a C. A rotação RL ocorre quando um nó (C) tem a sub árvore da direita maior do que a da esquerda e seu filho da direita (A) tem sub árvore da esquerda maior do que a da direita. Aplica-se uma rotação LL a A seguida de uma rotação RR aplicada a C.

38 38 Rotação Simples LL

39 39 Propriedades das rotações simples Existem três propriedades importantes da rotação LL: 1. A rotação não destrói a propriedade de ordenação de dados e, portanto, o resultado ainda é uma árvore de busca. A sub árvore A L permanece entre os nós A e B, e a sub árvore B R fica à direita do nó B. 2. Após a rotação tanto A quanto B são AVL balanceadas. Os nós A e B ficam com fator de balanceamento igual a zero. 3. Após a rotação a árvore permanece com a altura original. A inclusão do item não aumenta a altura da árvore.

40 40 Rotações Duplas

41 41 Balanceamento de árvores AVL Os desbalanceamentos e as rotações de equilíbrio correspondentes podem ser enquadrados em seis categorias, ou casos, adiante descritos. O ancestral mais novo, desbalanceado, do novo nó inserido é y a. Seu filho na direção do desbalanceamento é s. Os sufixos l e r representam filho mais velho e filho mais novo, respectivamente:

42 42 Categorias de rotações 1o caso: O novo nó é incluído na sub árvore esquerda da sub árvore esquerda do nó y a. Este caso tem solução chamada de rightrotation ou rotação LL 2o caso: O novo nó é incluído na sub árvore direita da sub árvore direita do nó y a. Este caso tem solução chamada de leftrotation ou rotação RR 3 o caso: O novo é incluído na sub árvore esquerda da sub árvore direita do filho mais velho de y a (rotação LR) 4 o caso: O novo nó é incluído na sub árvore direita da sub árvore direita do filho mais velho de y a (LR) 5 o caso: O novo nó é incluído na sub árvore direita da sub árvore esquerda do filho mais novo de y a (RL) 6 o caso: O novo nó incluído na sub árvore esquerda da sub árvore esquerda do filho mais novo de y a (RL)

43 43 Rotação LL

44 44 Rotação LL

45 45 Rotação RR

46 46 Rotação RR

47 47 Rotação LR

48 48 Rotação LR

49 49 Rotações LR e RL

50 50 Rotação LR

51 51 Rotação RL

52 52 Classe AVLTree public class AVLTree extends BinarySearchTree { protected int Height; //... }

53 53 Métodos height, getHeight e getBalanceFactor (1) public class AVLTree extends BinarySearchTree { protected int height; public AVLTree() { height = -1; } public int getHeight() { return height; } protected void adjustHeight() { if(isEmpty()) height = -1; else height = 1 + Math.max (left.getHeight(), right.getHeight()); }

54 54 Métodos height, getHeight e getBalanceFactor (2) protected int getBalanceFactor() { if(isEmpty()) return 0; else return left.getHeight() - right.getHeight(); } //... }

55 55 Método doLLRotation (1) // pgm10_09.java public class AVLTree extends BinarySearchTree { protected int Height; protected void doLLRotation() { if(isEmpty()) throw new InvalidOperationException(); BinaryTree tmp = right; right = left; left = right.left; right.left = right.right; right.right = tmp;

56 56 Método doLLRotation (2) Object tmpObj = key; key = right.key; right.key = tmpObj; getRightAVL().adjustHeight(); adjustHeight(); } //... }

57 57 Método doRRRotation (1) public class AVLTree extends BinarySearchTree { protected int Height; protected void doRRRotation() { if(isEmpty()) throw new InvalidOperationException(); BinaryTree tmp = left; left = right; right = left.right; left.right = left.left; left.left = tmp;

58 58 Método doRRRotation (2) Object tmpObj = key; key = left.key; left.key = tmpObj; getLeftAVL().adjustHeight(); adjustHeight(); } //... }

59 59 Método doLRRotation // pgm10_10.java public class AVLTree extends BinarySearchTree { protected int Height; protected void doLRRotation() { if(isEmpty()) throw new InvalidOperationException(); getLeftAVL().doRRRotation(); doLLRotation(); } //... }

60 60 Método doRLRotation public class AVLTree extends BinarySearchTree { protected int Height; protected void doRLRotation() { if(isEmpty()) throw new InvalidOperationException(); getRightAVL().doLLRotation(); doRRRotation(); } //... }

61 61 Método balance (1) // pgm10_11.java public class AVLTree extends BinarySearchTree { protected int Height; protected void balance() { adjustHeight(); if(getBalanceFactor() > 1) { if(getLeftAVL().getBalanceFactor() > 0) doLLRotation(); else doLRRotation(); }

62 62 Método balance (2) else if(getBalanceFactor() < -1) { if(getRightAVL().getBalanceFactor() < 0) doRRRotation(); else doRLRotation(); } //... }

63 63 Método attachKey // pgm10_12.java public class AVLTree extends BinarySearchTree { protected int Height; public void attachKey(Object object) { if(!isEmpty()) throw new InvalidOperationException(); key = object; left = new AVLTree(); right = new AVLTree(); Height = 0; } //... }

64 Remoção de itens de Árvores AVL

65 65 Método detachKey // pgm10_13.java public class AVLTree extends BinarySearchTree { protected int Height; public Object detachKey() { Height = -1; return super.detachKey(); } //... }

66 Árvores de Busca de Múltiplos caminhos

67 67 Implementação

68 68 Classe MwayTree: Métodos construtor e getM // pgm10_14.java public class MWayTree extends AbstractTree implements SearchTree { protected Comparable key[]; protected MWayTree subtree[]; public MWayTree(int m) { if(m < 2) throw new IllegalArgumentException(grau inválido"); key = new Comparable[m]; subtree = new MWayTree[m]; } int getM() { return subtree.length; } //... }

69 69 Travessia em ordem infixa de árvores binárias de busca Travessias infixas de árvores binárias são da forma: Percorrer a sub árvore da esquerda Visitar a raiz Percorre a sub árvore da direita Isto corresponde a, em uma travessia infixa de uma árvore binária de busca, visitar a todos os registros armazenados na árvore em ordem

70 70 Travessia em ordem infixa Travessias infixas não são definidas para árvores N-arias Em árvores de busca M-Way a travessia infixa é definida como a visita a todos os registros armazenados na árvore em ordem

71 71 Travessia de um nó de uma árvore de busca M-Way Percorrer a sub árvore T 0 Visitar o objeto k 1 Percorrer a sub árvore T 1 Visitar o objeto k 2 Percorrer a sub árvore T 2. Visitar o objeto k n-1 Percorrer a sub árvore T n-1

72 72 Método depthFirstTraversal (1) // pgm10_15.java public class MWayTree extends AbstractTree implements SearchTree { protected Comparable key[]; protected MWayTree subtree[]; public void depthFirstTraversal (PrePostVisitor visitor) { if(!isEmpty()) { for(int i = 0; i <= count + 1; ++i) {

73 73 Método depthFirstTraversal (2) if(i >= 2) visitor.postVisit(key[i - 1]); if(i >= 1 && i <= count) visitor.inVisit(key[i]); if(i <= count - 1) visitor.preVisit(key[i + 1]); if(i <= count) subtree[i].depthFirstTraversal(visitor); }

74 Busca linear de itens em Árvores M-Way

75 75 Método find (1) // pgm10_16.java public class MWayTree extends AbstractTree implements SearchTree { protected Comparable key[]; protected MWayTree subtree[]; public Comparable find(Comparable object) { if(isEmpty()) return null; int i;

76 76 Método find (2) for(i = count; i > 0; --i) { int diff = object.compare(key[i]); if(diff == 0) return key[i]; if(diff > 0) break; } return subtree[i].find(object); } //... }

77 Inclusão de itens

78 78 Método insert (1) // pgm10_18.java public void insert (Comparable object) { if(isEmpty()) { subtree[0] = new MWayTree(getM()); key[1] = object; subtree[1] = new MWayTree(getM()); count = 1; } else { int index = findIndex(object); if(index != 0 && object.isEQ(key[index])) throw new IllegalArgumentException (chave duplicada");

79 79 Método insert (2) if(!isFull()) { for(int i = count; i > index; --i) { key[i + 1] = key[i]; subtree[i + 1] = subtree[i]; } key[index + 1] = object; subtree[index + 1] = new MWayTree(getM()); ++count; } else subtree[index].insert(object); }

80 Remoção de itens

81 81 Método withdraw (1) public void withdraw (Comparable object) { if(isEmpty()) throw new IllegalArgumentException ("objeto não encontrado"); int index = findIndex(object); if(index != 0 && object.isEQ(key[index])) { if(!subtree[index - 1].isEmpty()) { Comparable max = subtree[index - 1].findMax(); key[index] = max; subtree[index - 1].withdraw(max); } else

82 82 Método withdraw (2) if(!subtree[index].isEmpty()) { Comparable min = subtree[index].findMin(); key[index] = min; subtree[index].withdraw(min); } else { --count; int i; for(i = index; i <= count; ++i) { key[i] = key[i + 1]; subtree[i] = subtree[i + 1]; }

83 83 Método withdraw (3) key[i] = null; subtree[i] = null; if(count == 0) subtree[0] = null; } else subtree[index].withdraw(object); }

84 Implementação C++

85 85 Implementação de Árvores de Busca

86 86 Definição da Classe SearchTree // pgm10_01.cpp class SearchTree : public virtual Tree, public virtual SearchableContainer { public: virtual Object& FindMin() const = 0; virtual Object& FindMax() const = 0; };

87 87 Definição da Classe BST // pgm10_02.cpp class BST : public BinaryTree, public SearchTree { protected: virtual void AttachKey(Object&); virtual Object& DetachKey(); virtual void Balance(); public: BST& Left() const; BST& Right() const; //... };

88 88 Funções da Classe BinarySearchTree left right find findMin insert attachKey withdraw detachKey

89 89 Definições da Função Membro Left e Rigth da Classe BST // pgm10_03.cpp BST& BST::Left() const { return dynamic_cast (BinaryTree::Left ()); } BST& BST::Right() const { return dynamic_cast (BinaryTree::Right ()); }

90 90 Definições da Função Membro Find e FindMin da Classe BST (1) // pgm10_04.cpp Object& BST::Find(Object const& object) const { if(IsEmpty ()) return NullObject::Instance(); int const diff = object.Compare(*key); if(diff == 0) return *key; else if(diff < 0) return Left().Find(object); else return Right().Find(object); }

91 91 Definições da Função Membro Find e FindMin da Classe BST (2) Object& BST::FindMin() const { if(IsEmpty ()) return NullObject::Instance(); else if(Left().IsEmpty()) return *key; else return Left().FindMin(); }

92 92 Inserção de itens em BST A inclusão de nós em árvores de busca deve ser precedida de uma operação de busca. Esta operação indica se o nó buscado já existe na árvore e, em caso de não existência, o local aonde deve ser feita a inclusão. Convém lembrar que uma busca sempre termina em folha e os nós a incluir serão incluídos como filhos da folha aonde se encerrou a busca.

93 93 Definições da Função Membro Insert, AttachKey e Balance da Classe BST (1) // pgm10{ _05.cpp void BST::Insert(Object& object) { if(IsEmpty ()) AttachKey(object); else int const diff = object.Compare(*key); if(diff == 0) throw invalid_argument(chave duplicada"); if(diff < 0) Left().Insert(object); else Right().Insert(object); } Balance(); }

94 94 Definições da Função Membro Insert, AttachKey e Balance da Classe BST (2) void BST::AttachKey(Object& object) { if(!IsEmpty ()) throw domain_error("operação inválida"); key = &object; left = new BST(); right = new BST(); } void BST::Balance() {}

95 95 Remoção de itens em BST A exclusão de nós em árvores de busca pode configurar um de 3 casos. Se o nó não tiver filhos pode ser excluído sem exigir ajustamento da árvore. Se o nó a excluir tiver apenas uma sub árvore, este nó pode ser excluído e deve ser substituído por seu filho único. Se o nó a excluir tiver mais de um filho, para que ele possa ser excluído, deve ser substituído por seu antecessor ou seu sucessor em ordem infixa. O nó substituto deve ser excluído da sua posição gerando outro processo de exclusão. Considerando o caso do sucessor em ordem infixa, o nó a ser excluído deve ser substituído pelo nó obtido alcançando-se o nó mais à esquerda da sub árvore direita do nó a excluir.

96 96 Remoção de itens em BST Remoção do nó (4) folha em BST Remoção do nó (1) não folha em BST

97 97 Definições da Função Membro Withdraw e DetachKey da Classe BST (1) // pgm10_06.cpp void BST::Withdraw(Object& object) { if(IsEmpty ()) throw invalid_argument("objeto não encontrado"); int const diff = object.Compare(*key); if(diff == 0) { if(!Left().IsEmpty()) { Object& max = Left().FindMax(); key = &max; Left().Withdraw(max); }

98 98 Definições da Função Membro Withdraw e DetachKey da Classe BST (2) else if(!Right().IsEmpty()) { Object& min = Right().FindMin(); key = &min; Right().Withdraw(min); } else DetachKey(); } else if(diff < 0) Left().Withdraw(object); else Right().Withdraw(object); Balance(); }

99 99 Definições da Função Membro Withdraw e DetachKey da Classe BST (3) Object& BST::DetachKey() { if(!IsLeaf ()) throw domain_error("operação inválida"); Object& result = *key; delete left; delete right; key = 0; left = 0; right = 0; return result; }

100 Implementação de árvores AVL

101 101 Conceito de AVL Adelson-Velskii e Landis propuseram as condições de balanceamento para uma árvore binária que recebeu como sigla suas iniciais. Definição (Condição de equilíbrio AVL) Uma árvore binária vazia é AVL balanceada. Uma árvore binária não-vazia, T={r,T L,T R }, é AVL balanceada se tanto T L quanto T R forem AVL balanceadas e |h L - h R |<=1 aonde h L é a altura of T L e h R é a altura of T R.

102 Implementação de árvores AVL

103 103 Definição da Classe AVLTree (1) // pgm10_07.cpp class AVLTree : public BST { protected: int height; int BalanceFactor() const; void AdjustHeight(); void LLRotation(); void LRRotation(); void RRRotation(); void RLRotation(); void AttachKey(Object&); Object& DetachKey(); void Balance();

104 104 Definição da Classe AVLTree (2) public: AVLTree(); int Height() const; AVLTree& Left() const; AVLTree& Right() const; };

105 105 Definições da Função Membro Height, AdjustHeight e BalanceFactor e do Construtor da Classe AVLTree (1) // pgm10_08.cpp AVLTree::AVLTree() : BST(), height(-1) {} int AVLTree::Height() const { return height; } void AVLTree::AdjustHeight() { if(IsEmpty ()) height = -1; else height = Max(left->Height(), right->Height()) + 1; }

106 106 Definições da Função Membro Height, AdjustHeight e BalanceFactor e do Construtor da Classe AVLTree (2) int AVLTree::BalanceFactor() const { if(IsEmpty ()) return 0; else return left->Height() - right->Height(); }

107 107 Definição da Função Membro LLRotation da Classe AVLTree // pgm10_09.cpp void AVLTree::LLRotation() { if(IsEmpty ()) throw domain_error(r otação inválida "); BinaryTree* const tmp = right; right = left; left = Right().left; Right().left = Right().right; Right().right = tmp; Object* const tmpObj = key; key = Right().key; Right().key = tmpObj; Right().AdjustHeight(); AdjustHeight(); }

108 108 Definição da Função Membro LRRotation da Classe AVLTree // pgm10_10.cpp void AVLTree::LRRotation() { if(IsEmpty ()) throw domain_error(" r otação inválida"); Left().RRRotation(); LLRotation(); }

109 109 Definição da Função Membro Balance da Classe AVLTree // pgm10_11.cpp void AVLTree::Balance() { AdjustHeight(); if(abs(BalanceFactor ()) > 1) { if(BalanceFactor() > 0) { if(Left().BalanceFactor() > 0) LLRotation(); else LRRotation(); } else { if(Right().BalanceFactor() < 0) RRRotation(); else RLRotation(); }

110 110 Definições das Função Membro AttachKey e DetachKey da Classe AVLTree // pgm10_12.cpp void AVLTree::AttachKey(Object& object) { if(!IsEmpty ()) throw domain_error("operação inválida"); key = &object; left = new AVLTree(); right = new AVLTree(); height = 0; } Object& AVLTree::DetachKey() { height = -1; return BST::DetachKey (); }

111 111 Definição da Classe MWayTree // pgm10_13.cpp class MWayTree : public SearchTree { protected: unsigned int const m; unsigned int numberOfKeys; Array key; Array subtree; unsigned int FindIndex(Object const&) const; public: MWayTree(unsigned int); ~MWayTree(); Object& Key(unsigned int) const; MWayTree& Subtree(unsigned int) const; //... };

112 112 Definição da Função Membro DepthFirstTraversal da Classe MWayTree // pgm10_14.cpp void MWayTree::DepthFirstTraversal( PrePostVisitor& visitor) const { if(!IsEmpty ()) { for(int i = 0; i <= numberOfKeys + 1; ++i) { if(i >= 2) visitor.PostVisit(*key [i - 1]); if(i >= 1 && i <= numberOfKeys) visitor.Visit(*key [i]); if(i <= numberOfKeys - 1) visitor.PreVisit(*key [i + 1]); if(i <= count) subtree[i]->DepthFirstTraversal (visitor); } }

113 113 Definição (Linear Search) da Função Membro Find da Classe MWayTree // pgm10_15.cpp Object& MWayTree::Find(Object const& object) const { if(IsEmpty ()) return NullObject::Instance(); unsigned int i = numberOfKeys; while(i > 0) { int const diff = object.Compare(*key[i]); if(diff == 0) return *key[i]; if(diff > 0) break; --i; } return subtree[i]->Find(object); }

114 114 Definições (Binary Search) da Função FindIndex e Find da Classe MWayTree (1) // pgm10_16.cpp unsigned int MWayTree::FindIndex(Object const& object) const { if(IsEmpty ()) throw domain_error(" operação inválida "); if(object < *key[1]) return 0; unsigned int left = 1; unsigned int right = numberOfKeys; while(left < right) { int const middle = (left + right + 1) / 2; if(object >= *key[middle]) left = middle; else right = middle - 1U; } return left; }

115 115 Definições (Binary Search) da Função FindIndex e Find da Classe MWayTree (2) Object& MWayTree::Find(Object const& object) const { if(IsEmpty ()) return NullObject::Instance(); unsigned int const index = FindIndex(object); if(index != 0 && object == *key[index]) return *key[index]; else return subtree[index]->Find(object); }

116 116 Definição da Função Membro Insert da Classe MWayTree (1) // pgm10_17.cpp void MWayTree::Insert(Object& object) { if(IsEmpty ()) { subtree[0] = new MWayTree(m); key[1] = &object; subtree[1] = new MWayTree(m); numberOfKeys = 1; } else { unsigned int const index = FindIndex(object); if(index != 0 && object == *key[index]) throw invalid_argument(chave duplicada"); if(numberOfKeys < m - 1U) {

117 117 Definição da Função Membro Insert da Classe MWayTree (2) for(unsigned int i = numberOfKeys; i > index; --i) { key[i + 1] = key[i]; subtree[i + 1] = subtree[i]; } key[index + 1] = &object; subtree[index + 1] = new MWayTree(m); ++numberOfKeys; } else subtree[index]->Insert(object); }

118 118 Definição da Função Membro Withdraw da Classe MWayTree (1) // pgm10_18.cpp void MWayTree::Withdraw(Object& object) { if(IsEmpty ()) throw invalid_argument("objeto não encontrado"); unsigned int const index = FindIndex(object); if(index != 0 && object == *key[index]) { if(!subtree[index - 1U]->IsEmpty()) { Object& max = subtree[index - 1U]->FindMax(); key[index] = &max; subtree[index - 1U]->Withdraw(max); }

119 119 Definição da Função Membro Withdraw da Classe MWayTree (2) else if(!subtree[index]->IsEmpty()) { Object& min = subtree[index]->FindMin(); key[index] = &min; subtree[index]->Withdraw(min); } else { --numberOfKeys; delete subtree[index]; for(unsigned int i = index; i <= numberOfKeys; ++i) { key[i] = key[i + 1]; subtree[i] = subtree[i + 1]; }

120 120 Definição da Função Membro Withdraw da Classe MWayTree (3) if(numberOfKeys == 0) delete subtree[0]; } else subtree[index]->Withdraw(object); }

121 121 Definição da Classe BTree // pgm10_19.cpp class BTree : public MWayTree { BTree* parent; void InsertPair(Object&, BTree&); void AttachKey(unsigned int, Object&); void AttachSubtree(unsigned int, MWayTree&); Object& InsertKey(unsigned int, Object&); BTree& InsertSubtree(unsigned int, BTree&); void AttachLeftHalfOf(BTree const&); void AttachRightHalfOf(BTree const&, Object&, BTree&); public: BTree(unsigned int); BTree(unsigned int, BTree&); void Insert(Object&); void Withdraw(Object&); };

122 122 Definição da Função Membro Insert da Classe BTree (1) // pgm10_20.cpp void BTree::Insert(Object& object) { if(IsEmpty ()) { if(parent == 0) { AttachSubtree(0, *new BTree(m, *this)); AttachKey(1, object); AttachSubtree(1, *new BTree(m, *this)); numberOfKeys = 1; } else parent->InsertPair(object, *new BTree(m, *parent)); }

123 123 Definição da Função Membro Insert da Classe BTree (2) else { unsigned int const index = FindIndex(object); if(index != 0 && object == *key[index]) throw invalid_argument(chave duplicada"); subtree[index]->Insert(object); }

124 124 Definição da Função Membro InsertPair da Classe BTree (1) // pgm10_21.cpp void BTree::InsertPair(Object& object, BTree& child) { unsigned int const index = FindIndex(object); BTree& extraTree = InsertSubtree(index + 1, child); Object& extraKey = InsertKey(index + 1, object); if(++numberOfKeys == m) { if(parent == 0) { BTree& left = *new BTree(m, *this); BTree& right = *new BTree(m, *this); left.AttachLeftHalfOf(*this);

125 125 Definição da Função Membro InsertPair da Classe BTree (2) right.AttachRightHalfOf(*this, extraKey, extraTree); AttachSubtree(0, left); AttachKey(1, *key[(m + 1)/2]); AttachSubtree(1, right); numberOfKeys = 1; } else { numberOfKeys =(m + 1) / 2 - 1; BTree& right = *new BTree(m, *parent); right.AttachRightHalfOf(*this, extraKey, extraTree); parent->InsertPair(*key[(m + 1)/2], right); }


Carregar ppt "Árvores de Busca. 2 Uma árvore que suporta eficientes operações de busca, inclusão e exclusão é chamada de árvore de busca. A árvore é usada para armazenar."

Apresentações semelhantes


Anúncios Google