resumoLivro

download resumoLivro

of 49

Transcript of resumoLivro

  • 8/3/2019 resumoLivro

    1/49

    CAP.2 OPTIMIZAO DE DESEMPENHO

    2.1. IntroduoA sobrecarga de operadores em classes com alojamento dinmico (String, Bigint) que possamatingir grandes dimenses, requer a adopo de tcnicas tendentes a evitar graves penalizaesde desempenho.Os problemas so o aumento significativo de instanciaes de objectos temporrios e locais.Isto porque algumas funes de sobrecarga de operadores implicam o retorno, por valor, deobjectos locais.O objectivo deste captulo descrever tcnicas para minimizar o nmero de instanciaes ecpias, de modo a no desmerecer em desempenho face ao paradigma procedimental.As classes de inteiros e fraces com mltipla preciso so pretexto para introduzir algoritmosnumricos e conceitos bsicos que do suporte a aplicaes no domnio da segurana dascomunicaes.

    2.2. Classe String entendida como uma classe contentora de caracteres, que providencia um n alargado demtodos, como concatenao (+), append (+=), afectao (=), extraco e insero sobre streams

    ( >> e

  • 8/3/2019 resumoLivro

    2/49

    - Afectar o respectivo atributo apontador com o endereo do novo espao.O destrutor deve providenciar a devoluo da memria ocupada.String forma cannica --> pg. 60

    Justifica-se a definio de mtodos auxiliares, sempre que venham a ser invocados mais que umavez na definio de outros mtodos. o caso do init ( ), do assign ( ) e do dimNormalize ( ).Na reserva de espao adoptamos dimenses mltiplas de DIM_MIN (por potncias de 2),

    excedentes a sz.O operador concatenao definido como funo global, dado tratar-se de um operador simtricoentre uma string e uma string C-style. No necessita ser declarado como friend da classe Stringpois no precisa aceder a atributos privados dessa classe. Foi definido a partir do +=, o que umestilo muito recomendvel. O operador += devolve uma referncia para o objecto alvo, pelo queno penalizante para o tempo de execuo. O que se torna gravoso na concatenao anecessidade de retornar por valor o objecto String resultante e a construo do objecto String tmp,local funo. Veremos como melhorar.O uso do tipo size_t recomendvel para a portabilidade

    2.2.2. Verso Handle/BodyO desempenho da verso cannica anterior pode ser melhorado, evitando as mltiplas cpias darepresentao string C-style aquando da execuo do construtor por cpia e do operadorafectao por cpia. Isso consegue-se usando o idioma handle/body, que consiste em criar 2classes copperantes:- Uma classe String (handle), nica vsivel ao utilizador- Uma classe Srep (body) que se comporta como intermediria entre a classe String e arepresentao string C-style.A classe String tem como nico atributo um apontador para Srep e apresenta uma interfaceidntica cannica.A classe Srep toma os atributos que na verso anterior pertenciam classe String e alm delesum contador de referncias representao string C-style, que memoriza o nmero de objectosString que em cada momento partilham dessa representao.

    s mtodos so do encargo de Srep. A cada representao de String fica univocamenteassociado um objecto Srep. Instanciae spor cpia ou afectaes de objectos String com outrosj existentes tero como consequncia que uma mesma cadeia de caracteres ficar partilhada porvrios objectos String, evitando assim mltiplas cpias de cadeias de caracteres. O custo disto a ateno necessria quando uma alterao num objecto String poder vir a repercutir-se nosoutros objectos que com ela partilham essa cadeia; ter pois de desligar-s epreviamente.

    2.2.2.1. Definio da classe String (handle/body) ---> ver pg. 66O tempo de desempenho metade do cannico e menor que com a classe string da biblioteca doC++.

    2.2.3. Optimizao Quanto a Objectos Temporrios

    O idioma handle/body tem impacto nas aplicaes em que os objectos so construdos ouafectados por cpia frequentemente mas no so depois alterados. Nos casos comoconcatenao em strings ou operadores aritmticos em classes numricas o idioma poucobeneficia pois os objectos so muitas vezes alterados.Ento, seguindo o nosso ex. vai-se definir uma nova classe StrTmp (string temporria) eprovidenciar que em todas as circunstncias em que a sobrecarga de operadores envolva ainstanciao de objectos temporrios, o objecto retornado por esses operadores seja dessaclasse.No esquecer que a principal causa de perda de desempenho em classes de grande porte comalojamento dinmico reside nos operadores que retornam objectos por valor, criando localmentebuffers de resultados.Por exemplo a concatenao de mais que 2 objectos string implica a criao de vriostemporrios, todos diferentes:s=s1+s2+s3+s4 envolve as seguintes aces:String tmp1 (operator+(s1,s2));

  • 8/3/2019 resumoLivro

    3/49

    String tmp2 (operator+ (tmp1,s3);String tmp3 (operator+)tmp2,s4);s.operator=(tmp3);O ideal seria distinguir o comportamento dos objectos temporrios dos objectos String comuns,criando uma classe auxiliar StrTmp, tal que, se tmp1 tivesse espao para conter a concatenaoglobal dos quatro objectos String, no seja necessrio criar mltiplas representaes para asconcatenaes intermdias. Ficaramos com:

    StrTmp tmp (opearot+(s1,s2);tmp.operator+(s3);tmp.operator+(s4);s.operator=(String (tmp));Ver alteraes na pg. 74 --< tempo de execuo reduzido de 4 para 1.

    2.2.4. Operadores de ndice para LeituraA classe String disponibiliza normalmente a sobrecarga do operador ndice, que permite o acessoao carcter indexado, para leitura ou para escrita.-Modo trivial na verso cannica:char &String::operator[] (inti) {

    assert(i

  • 8/3/2019 resumoLivro

    4/49

    Fraction &operator-=(const Fraction &b);Fraction &operator*=(const Fraction &b);Fraction &operator/=(const Fraction &a);Fraction operator-( ) const {Fraction x =+this; x.num.neg( ); return x; }

    #define oper(op) \Fraction operator op(const Fraction &b) const \ {return Fraction (*this)op##&b; }oper(+) oper(-) oper(*) oper(/)

    undef operfriend ostream &operator

  • 8/3/2019 resumoLivro

    5/49

    CAP. 3 TEMPLATES E DERIVAO3.2. Templates de Classes e de FunesUm template de fine uma famlia de classes ou de funes, que tomam como parmetros typetemplate parameters (parmetros-tipo) e non type template parameters (parmetros-valor).Das tcnicas fundamentais ligadas a templates realam-se as seguintes:- Mecanismos bsicos para definir e usar template de classes;- Template de funes e deduo de argumentos;

    - Template de membros;- Parmetros template que so templates de classes.

    3.2.1. Templates de ClassesOs de uso mais frequente so as classes contentoras. Designam-se por contentores os objectosdestinados a conter outros objectos de qualquer tipo e que disponibilizam ao utilizador mtodoscmodos de acesso (inserir, remover, pesquisar, etc.) aos objectos contidos.Ex: Stack:3.2.1.1. Classe Stackclass Stack {public:

    typedef char T; //O tipo de cada elementostatic const unsigned DIM = 32; //Dimenso do stack

    private:T data[Dim]; //Contentor esttico que suporta o stackunsigned size; //nmero de objectos contidos

    public:Stack() {size=0);}bool empty() const {return !size;}//Retorna a cpia do objecto situado no topo do stack.T &top() {return data[size-1];}//Insere objecto no topo do stackvoid push(const T &p) {assert(DIM!=size); data[size++]=p;}

    //Remove o objecto do topo do stackvoid pop() {assert(size>0); --size;}};

    Esta definio vlida, seja qual for o tipo de objectos que se defina como T e seja qual for ovalor inteiro da constante DIM. Mas tem de se alterar as primeiras linhas conforme o caso. possvel alargar esta definio de Stack tornando-a parametrizvel no tipo T e no valor DIM.

    3.2.1.2. Classe Parametrizvel StackO termo template de classes sinnimo de classe parametrizvel ou classe genrica. Umtemplate de classes uma especificao para criar uma famlia de classes aparentadas.ex:

    template //em vez de typename tambm pode ser classclass Stack {

    T data[DIM];unsigned size;

    public:Stack () {size=0; }int empty () const {return !size; }T &top () {return data [size-1]; }void push (const T &p) {assert (DIM!=size); data[size++]=p; }void pop () {assert(size>0); --size; }

    };Ex. de declarao de objectos:Stack stk1;Stack stk2;

  • 8/3/2019 resumoLivro

    6/49

    O cdigo dos mtodos da generalidade das classes de contentores tem a particularidadeinteressante de ser independente do tipo dos objectos neles contidos (como o exemplo reala), oque propicia definir um template de classes tendo como parmetros, entre outros, o tipo dosobjectos a conter (parmetro-tipo) e eventualmente, como no caso presente, a dimenso inicialdo contentor (parmetro-valor).Uma classe gerada (instanciada) a partir de um template de classes chamada classe template.Um template de classes pode ser definido com um nmero qualquer de parmetros-tipo e de

    parmetros-valor.ex:template class Xpto;typedef Xpto MyXpto;MyXpto ob1, ob2, ob3;- Ex. definio de um novo nome para a classe Stacktypedef Stack CharStack;Stack definido antes no tem natureza dinmica. Geralmente tem sendo suportada porcontentores sequenciais.

    3.2.2. Templates de FunesDefine uma famlia de funes. Ex:templatevoid swap(T &a, T &b) {T aux=a; a=b; b=aux;} importante notar desde j que enquanto na instanciao de um objecto de uma classe templateo tipo do objecto deve sempre explicitar o valor dos seus argumentos template, no caso dachamada a uma funo template prescinde-se geralmente dessa explicitao. Ex. para funoanterior:int x=10, y=20;swap(x,y); //compilador infere, mas tambm podia swap(x,y);

    3.2.2.1. Membros Funo de Templates de ClassesUm membro funo de um template de classes implicitamente um template de funes membro.

    Toma como seus, os parmetros do template de classes a que pertence. Ex:template class Array {T *v; //Apontador para a representaounsigned dim; //Capacidade da representaounsigned size; //Nmero de elementos contidosArray (const Array&); //Impossibilitar a construo por cpiavoid oerator=(const Array&) //Impossibilitar afectao

    public:explicit Array(unsigned d); //Iniciado com dim=d~Array () {delete [] v; }T &operator[](unsigned n) {assert (n

  • 8/3/2019 resumoLivro

    7/49

    for(unsigned i=a.size()-1; i list2Quando declaramos todos os parmetros por omisso. a lista de argumentos da classe templatepode ser vazia. Ex:template class Stack {/*...+/};Stack *p; //OK, apontador para StackStack *q //Erro: Imprescindvel No permitido usdar parmetros por omisso em templates de funes.

    3.2.4. Parmetros Template que so Templatestemplate class List {/* ... */ };templateclass map {

    struct pair {C key;C value;

    };

    //...};Map trata-se de um template de tabelas associativas, cujos elementos Pair tm 2 membros (key evalue). Os membros key e value so contentores do tipo C, de objectos tipo K e tipo V. Destetemplate podem ser instanciados objectos tabelas asociativas to varaiadas como sejam:Map //Chaves do tipo List e dados do tipo ListMap //Chaves do tipo Stack e dados do tipo StackPara usar um parmetro template que template, necessrio especificar os parmetros que eleprprio requer. Os parmetros template que so template so sempre templates de classes.

    3.2.5. Palavra-Chave typename utilizada no corpo da declarao dos templates e tem por objectivo desfazer ambiguidades em

    expresses nas quais o compilador no tenha possibilidade de inferir se um dado nome de ummembro de um argumento template, corresponde ou no a um tipo. typename especificacorresponde de facto a um tipo.A biblioteca standard define em todos os templates de contentores um conjunto de nomes de tiposstandard. Por ex:template class vector {public:

    typedef T value_type; //Tipo de elementotypedef A allocator_type; /Tipo de gestor de memriatypedef typename A::size_type size_type;typedef typename A::difference_type difference_type;typedef typename A::pointer iterator;//...

    };

  • 8/3/2019 resumoLivro

    8/49

    3.2.6. Templates de MembrosPodemos declarar um template de mebros dentro de uma classe ou de um template de classes.Ex:template

  • 8/3/2019 resumoLivro

    9/49

    3.2.9.2. Algoritmos Executados em Tempo de Compilao...

    3.3. DERIVAO DE CLASSES E MTODOS VIRTUAISO paradigma de programao Abstract Data Type (tipos de dados definidos pelo utilizador)esgota-se com a definio de classes de objectos isoladas entre si ou, quando muito, de classesque se associam com outras atravs de relaes, tais como incluso ou agregao.

    O paradigma da Programao Orientada por Objectos pressupes tambm que as classes tmrelaes de herana e usam polimorfismo, conceitos suportados pelos mecanismos dederivao e de mtodos virtuais do C++

    3.3.1. Relao de HeranaNuma dada aplicao complexa o programador deve encontrar classes compropriedades comuns, de modo a que a definio de algumas delas possa ser feitaa partir de outras mais genricas. herdeira chama-se derivada, e herda membros da base.A derivada acrescenta normalmente novos membros dados (atributos) ou membrosfuno (mtodos), pelo que mais rica (em interface e atributos). Para alm de

    acrescentar tambm pode alterar membros.A herana pode sersimples ou mltipla (de classes base directas).Quanto acessibilidade que os membros herdados tomam numa classe derivada,depende do tipo de derivao que for adoptado: pblica; protegida; privada.O mais comum a pblica, em que os membros especificados como pblicos naclasse na classe base mantm-se pblicos nas classes derivadas e os privados nabase passam a ocultos, preservando assim o encapsulamento de membros.Os objectos da classe derivada incluem um objecto da classe base, mas o inversoj no verdade. assim, existe converso implcita da classe derivada para a classebase mas no o inverso.Ex. Classe B derivada de classe A//Classe baseclass A {

    int x; //atributo privado, oculto na classe B.public:

    void set10() {x=10;}void show() {cout

  • 8/3/2019 resumoLivro

    10/49

    A classe derivada mais especfica do que a sua classe base, ou seja, representaum subconjunto dos objectos que a sua classe base representa.atributo = atributo de estadomtodo = atributo de comportamentoOs mtodos pblicos de uma classe (prprios ou herdados) chamam-se interfaceda classe.

    Uma consequncia importante que advm da derivao de classes consiste nareutilizao de cdigo da classe bsica.Derivao Pblica uma relao Is A ( Um).

    3.3.3. Header da Declarao de Classes DerivadasPor forma a suportar a herana, a sintaxe de classe permite adicionar ao header da classe umalista de derivao dessa classe, que especifica a classe (ou classes) base directa.Na declarao de uma classe derivada, a lista de derivao segue-se ao nome da classe,antecedida por 2 pontos. EX:class D : public B1, private B2 {

    3.3.3.1. Construtores de Classes DerivadasOs construtores e os operadores de afectao das classes base no so herdados pela classederivada.Aps a lista de argumentos do construtor da classe derivada e antes do corpo do construtor,antecedida por 2 pontos e separados por vrgulas, segue-se a lista de iniciao, de que constamos construtores das classes base e os construtores dos objectos membros da classe derivada. Seisso no for feito pressupe-se que sejam invocados os seus construtores sem parmetros, casoexistam. importante notar que estes s existem por omisso, se no for definido nenhumconstrutor com parmetros (excepo ao construtor por cpia), o construtor implicitamenteinvocado limita-se a reservar espao de memria, sem iniciao de valores.Da lista de iniciao (das classes base e membros) pode tambm constar a iniciao dosmembros dados tipo-bsico usando para sua iniciao o formalismo da iniciao dos membros

    tipo-classe.ex:class Complex 7

    int x, y;public:

    Complex(int xx=10, int yy=10) {x=xx; y=yy; }//ou Complex(intxx=10, int yy=10) : x(xx), y(yy) {}//...

    };

    class B {Complex zz;

    int a;public:

    B(Complex v1, int v2) : zz(v1), a(v2) {}B() 7a=0} //zz iniciado com x=y=10.//...

    };

    class D : public B {int d;

    public:D(Complex v3, int v4, int v5) : B(v3, v4), d(v5) {}D() {d=5;} //zz iniciado com x=y=10 e a com 0.//...

    };As aces realizadas por um construtor de uma classe so as seguintes:

  • 8/3/2019 resumoLivro

    11/49

    1 - Se for uma classe derivada, pe em execuo o(s= construtor(es) da(s) classe(s) basedirectas, pela ordem indicada na lista de derivao2 - Se a classe contm atributos, pe em execuo os seus construtores pela ordem da suadeclarao na classe3 executa as instrues que constam do seu corpo.

    3.3.4. Especificadores de Acesso a Membros

    Por forma a preservar o encapsulamento dos membros especificados como private, tambm noso acessveis aos mtodos das suas classe derivadas.Os especificados como protected mantm-se inacessveis s entidades externas mas soacessveis directamente pelos mtodos das classes derivadas.Ex:class B {

    int aa; //Zona apenas acessvel pelos mtodos de Bprotected: //Zona acessvel aos derivados de B

    int bb;public: //Zona pblica

    int cc;};

    class D : public B {public:

    int dd;void f() {

    aa=0; //Erro. membro aa privado da classe B.bb=1; //OKcc=2; //oK

    }};

    void main () {B b;D d;b.aa=0; //Erro. aa privado de B (no pode ser acedido de main)b.bb=1; //Erro. bb protegido de Bb.cc=2; //OK. cc pblico de Bb.dd=3; //Erro, dd no membro de B.d.aa=4; //Erro. aa no acessvel a Dd.bb=5; //Erro. bb mantm-se protegido em Dd.cc=6 //OK. cc mantm-se pblico em Dd.dd=7; //Ok. dd pblico em D

    }

    3.3.5. Especificadores de Acesso s Classes BaseA acessibilidade que um membro herdado toma na classe derivada depende conjuntamente doespecificador de acesso classe base e do tipo de acesso que esse membro possua na suaclasse.Derivao Pblica: pblicos --> pblicos; protegidos --> protegidos; privados e ocultos --> ocultosDerivao Protegida: pblicos e protegidos --> protegidos; privados e ocultos --> ocultosDerivao Privada: pblicos e protegidos --> privados; privados e ocultos --> ocultosO membro oculto, no entanto, existe na classe e poder ser acedido indirectamente por mtodospblicos ou protegidos herdados da classe base.Se for omitido, a derivao, por omisso privada.Ex: Acesso a membros da classe baseclass B {

    int n;public:

  • 8/3/2019 resumoLivro

    12/49

    B(in nn) {n=nn; }int getn() {return n; }void display() {cout

  • 8/3/2019 resumoLivro

    13/49

    3.3.7. Derivao MltiplaA hereditariedade mltipla interessante no que se refere a reutilizao de cdigo, mas podesuscitar alguns problemas de ambiguidade:- Ambiguidade de membros herdados --> Tem de se explicitar o operador resoluo de alcance- Ambiguidade por duplicao de herana Problema do diamante --> encaminhar... ex: x=dd.B1::i

    A palavra chave virtual aplicada s classes (base) permite evitar duplicao de cpias quandomais que uma classe deriva da base.

    3.3.8. Implementao handle/body da String com Derivao...

    3.3.9. Mtodos Virtuais e PolimorfismoUma aco diz-se polimorfa se for executada de diferentes formas dependendo do contexto emque for invocada. Esse contexto pode ser determinado em tempo de compilao ou de execuo.O C++ utiliza vrios tipos de polimorfismo, nomeadamente overload de funes e de operadores,template de classe e funes (resolvido em tempo de compilao), e mtodos definidos comovirtuais numa arborescncia de derivao (resolvido em tempo de execuo).Em C++, o polimorfismo traduz-se na possibilidade de redefinir nas classes derivadas os mtodosdeclarados na classe base como virtuais (com o mesmo nome, nmero e tipo de parmetros), porforma a que, quando invocado um mtodo virtual atravs de um apontador ou uma referncia paraa classe base, a verso do mtodo posto em execuo seja o da classe do objecto apontado oureferenciado e no o da classe correspondente ao tipo da declarao do apontador ou dareferncia como acontece nos mtodos comuns. Ex:class B {public:

    virtual char *f() {return B:.f(); } //Polimorfachar *g() {return B::g(); 0 //Normal

    };

    class D : public B {public:char *f() 7return D::f() ; } //Polimorfachar *g() {return D::g() ; } //Normal

    };void main () {

    D obj;B *pt = &obj; //pt do tipo apontador para B

    // mas aponta para um objecto Dcout f()

  • 8/3/2019 resumoLivro

    14/49

    CAP. 4 CONTENTORE SEQUENCIAIS4.1. IntroduoA norma ANSI/ISO da linguagem C++ e da respectiva biblioteca de templates STL, define osconceitos:Contentor para conter objectosIterador para estabelecer ligao entre algoritmos genricos e contentoresAllocator para isolar os contentores do detalhe dos modelos de alojamento de memria

    utilizados e para separar as aces de alojamento das de iniciao de objectos.Resumindo: Os algoritmos genricos usam contentores por intermdio dos iteradores e usamobjectos funo na especializao dos algoritmos genricos. Os contentores usam os allocatorspara alojar e desalojar memria e para construir e destruir objectos.As normas ANSI/ISO no impem implementao especfica mas sim os mtodos pblicos adisponibilizar e a respectiva complexidade em tempo de execuo.Conforme os mtodos disponveis na sua interface, os contentores do STL tm diferentes nomes:vector, list, deque, set, map (tabela), stack, queue, priority_queue.Os tipos de contentores dividem-se em:- Contentores Sequenciais- Adaptadores de Contentores Sequenciais- Contentores Associativos

    4.2. GeneralidadesOs contentores sequenciais suportam-se em estruturas de dados lineares, isto , aquelas em quetodos os elementos contidos tm um nico elemento sucessor e um nico antecessor. permitemacesso sequencial aos elementos e disponibilizam operadores para inseres e remoes deobjectos.

    4.2.1. Tipos de Contentores SequenciaisT a[n] Estrutura array, predefinida na linguagem. Providencia acesso aleatrio a sequncias dedimenso fixa n. Os iteradores so apontadores comuns para objectos tipo T. Acesso em tempoconstante a qualquer objecto, usando indexao ou aritmtica de apontadores. Inseres e

    remoes a meio e no incio requerem tempo linear. No fim requerem tempo constante.

    vector uma generalizao do array que, de modo transparente ao utilizador, aumenta adimenso sempre que se torne necessrio.

    list suportada numa estrutura em lista duplamente ligada. Permite visita sequencial (emambos os sentidos) a todos os objectos. Insero e remoo em tempo constante.

    deque Semelhante ao vector, excepto que permite inseres e remoes rpidas em ambos osextremos da sequncia.

    ring buffer vector em anel variante de fila de espera com capacidade constante

    preestabelecida FIFO. Objectos inseridos no fim da fila e removidos do incio, com tempoconstante.

    4.2.2. Complexidade em Notao Big-OhNum algoritmo que toma como domnio um conjunto de n elementos, a notao Big-Oh exprime otipo de proporcionalidade existente entre n e o tempo t(n) que demora a sua execuo.Por ex. a pesquisa de um elemento num array v no ordenado de dimenso n, requer no mximon comparaes entre a chave de pesquisa e os contedos v[i] do array. Demorando k cada passo,vir: t(n) tempo de pesquisa linear com n ou t(n) O(n) na notao Big-Oh.No caso de usarmos pesquisa dicotmica sobre um array ordenado de n elementos, o tempo depesquisa seria: t(n)

  • 8/3/2019 resumoLivro

    15/49

    t(n) O (n log n)) - tempo n log nt(n) O (n) - tempo lineart(n) O (log n) - tempo logartmicot(n) O (1) - tempo constanteA diferena de tempos concretos pode ser abissal.Nalguns casos melhor usar o tempo amortizado. Por ex. no push_back de um array, que insereno fim do array, mas quando no h mais espao dobra dinamicamente este, de formaautomtica. Aloja espao para 2n elementos, muda para l os n anteriores e devolve espaoanterior. Alojamento e cpia so O(n) e as inseres so O(1). Amortizando, podemos dizer que O(1)+ - algoritmo de tempo constante amortizado.

    4.2.3. Iteradores Associados a ContentoresUm objecto iterador, definido para um determinado contentor, comporta-se como um apontadorinteligente para apontar para os objectos nele contidos, dispondo para tal de operadores que lhepermitem percorrer o conjunto desses objectos. Ex. operador incremento ++ ; e a sobrecarga dooperador desreferncia * sobre um iterador retorna o objecto por ele apontado.No caso de contentores sequenciais (objectos ocupam bloco compacto e contguo de memria),os iteradores por excelncia so os prprios apontadores para esses objectos (T*).

    No caso de contentores sequenciais como a lista duplamente ligada, em que os objectos j noocupam bloco compacto de memria, h que definir uma classe especfica que seja iterador esobrecarregar os operadores ++, -- e *iterator &iterator::operator++(); //Avana o iteradoriterator &iterator::operator(); //Recua o iteradorT &iterator::operator*(); //Retorna a data iterada

    4.2.3.1. Domnio de Iteradores em Contentores SequenciaisOs conceitos de domnio (range) e de iterador (iterator) so fundamentais em tudo o que vamosreferir acerca dos contentores.Os algoritmos ganham acesso a uma dada sequncia de objectos, recebendo como argumentosum par de iteradores, first e last, do contentor onde esses objectos se situem. Designa-se por

    domnio de iteradores num contentor a sequncia de iteradores que apontam para umasequncia de objectos contidos. Denota-se por [first, last[ . last aponta para a primeira posio aseguir ao ltimo objecto do domnio.Um domnio vlido se last for atingvel a partir de first, por incrementos sucessivos. O apontadorlast no pode ser desreferenciado mas pode entrar na aritmtica de apontadores.ex:const int MAX = 10;int v[MAX];//Iterador sobre o arraytypedef int *iterator;//Iterador para o incio do domnioiterator begin() {return &v[0]; }

    //Iterador para o past the enditerator end() {return &v[MAX]; }//Afectar os elementos do domnio com o prprio ndicevoid assign(iterator first, iterator last) 7

    for (int i=0; first != last; ++first, ++i) *first=i; }//Mostrar o valor dos elementos do domniovoid write(iterator first, iterator last) {

    for(; first != last; ++first) cout

  • 8/3/2019 resumoLivro

    16/49

    de iteradores, conforme o conjunto de operaes que disponibilizam satisfazendo esta exigncia.Depende do contentor para o qual foi definido.As categorias so: Output, Input; Forward; Bidirectional; Random Access. Posso definir as funesdo exemplo anterior como template usando a categoria adequada (mnima) mas que funcioantambm se lhe forem passados parmetros de categorias superiores.

    4.2.3.3. Seleco do Algoritmo Apropriado ao Iterador

    ex:templateunsigned distance (ItIn first, ItIn last) {

    unsigned res=0; while(first!=last) {++first; ++res; }return res; }

    Funciona para qualquer iterador da categoria input, logo funcioan para qualquer outro exceptooutput. Mas tem mau desempenho O(n). Se lhe forem passados iteradores de acesso aleatriofica com O(1) pois estes permitem p-q em O(1).O ideal seria ter apenas um template de funes distance() que seleccionasse o algoritmo maiseficiente, conforme a categoria dos iteradores que lhe fossem passados como argumentos. Para oalgoritmo genrico inferir a categoria do iterador, basta que na definio do iterador conste ummembro tipo que possa ser testado, o que complicado dado que o que tem de ser testado seaa categoria do iterador igual ou maior que lhe necessria. A tcnica de utilizao de tagsdescrita no cap. anterior assume aqui a tarefa para que est vocacionada.struct output_iterator_tag {};...struct random_access_iterator_tag {};Basta agora que qualquer classe de iterador tenha uma definio do tipo iterator_category,baseada nestes tipos de classes tag. Ex. classe iterator de list deve ter a seguinte declarao:class iterator { //Iterador de list bidireccional.public:

    typedef bidirectional_iterator_tag iterator_category;//...

    };Tem pois agora coero implcita para input por exemplo quando um algoritmo necessite de umiterador da categoria input.H ainda que usar Traits para o caso de querermos usar o tipo pointer predefinido na linguagemcomo categoria de iterador random acess. ver pg. 192-194 para aprofundamento.

    4.2.4. Gesto de Memria nos Contentores4.2.4.1. Gesto de Memria na Forma TrivialConhecemos 3 modos de alojamento de objectos em memria:- Esttico: quando os objectos (estticos) so alojados na memria de dados globais, durante ocarregamento do programa (load time);- Automtico: quando os objectos (automticos e temporrios) so alojados em run time no stack:

    - Dinmico: quando os objectos (dinmicos) so alojados e desalojados na memria livre (heap).ex. em T a(10) reservada memria esttica ou automtica. Quando o programa sai do scope dadeclarao, invocado implicitamente o destrutor de T e a memria libertada.No declarativa como x=T(10) --> automtica ...

    4.2.4.2. Operadores new e delete bsicosQuando invocado abreviadamente: T *p = new T(10)o operador new reserva espao no heap para um objecto T e posto implicitamente em execuoo construtor. delete p posterior invocado implicitamente o destrutor.Quer o operador new, quer o delete cujas assinaturas so:void *operator new(size_t n);operator delete (void *p);podem ser tambm invocados explicitamente no programa:T p * = ( T *) :: operator new(sizeof(T));..operator delete(p);

  • 8/3/2019 resumoLivro

    17/49

    Este tipo de invocao promove comportamentos diferentes da forma abreviada, pois limita-se areservar espao no heap sem pr em execuo o construtor.

    4.2.4.3. Gesto da Memria nos Contentores StandardA STL diferente. Adopta como critrio separar as aces de reserva de espao, das aces deiniciao de objectos (2 mtodos diferentes). Da mesma a devoluo do espao fica dissociada dadestruio dos objectos. A vantagem a eficincia, como se mostra mais frente para o template

    de classes vector.Este novo critrio implica a sobrecarga do operador new, usando mais um parmetro adicional(apontador para void) para permitir construir um objecto num endereo explcito da memria,previamente reservado --> tcnica do placement syntax.void *operator new (size_t, void *p) {return p; } e limita-se a retornar o prprio apontador que lhefoi passado sem reservar nenhuma reserva de espao. Assim,new(p) T(10) s contri, no espao anteriormente reservado pela invocao explcita do newbsico....4.3 Template de Classes AllocatorTodos os contentores genricos da biblioteca tomam como segundo parmetro uma classetemplate allocator que determina o modo como a memria gerida. Esse template tem umainterface satndard de tipos e mtodos que todos os componentes da biblioteca tomam comoauxiliares, quer para reservar e devolver memria no iniciada, quer para construir e destruirobjectos.Um allocator providencia mtodos para alojar e desalojar memria, e mtodos pblicos paraconstruir e destruir objectos. Isola assim contentores e algoritmos da gesto de memria, paraalm de definir nomes de tipos e mtodos com que nos devemos pouco a pouco familiarizar.Veremos a seguir como se faz, na classe vector.

    4.3.1. Requisitos de um Allocator...4.4. Template de Classes Container

    ...

  • 8/3/2019 resumoLivro

    18/49

    4.5. Template de Classes vectorPrincipais caractersticas:- Permitir acesso aleatrio em tempo constante O(1) aos objectos contidos, por indexao ouaritmtica de apontadores;- Permitirinseres e remoes em tempo constante amortizado O(1)+ no fim da sequncia;

    - Permitirinseres e remoes em no incio ou no meio da sequncia em tempo linearO(n)- Ampliar automaticamente a capacidade da representao em memria, por realojamento. Nocaso duplicar ou criar unidade se zero.A definio de um template de contentor envolve sempre a definio de um iterador que lhe sejaespecfico. No caso um simples apontador.Um vector dispe de 3 atributos do tipo iterator: start, finish e endOfStorage.

    4.5.1. Definio do Template de Classes vector#define SUPER Containertemplateclass vector: public SUPER {public:

    IMPORT_TYPE(pointer);IMPORT_TYPE(const_pointer);IMPORT_TYPE(reference);IMPORT_TYPE(const_reference);IMPORT_TYPE(size_type);

    //Tipos no herdados de Containertypedef pointer iterator;typedef const_pointer const_iterator;

    //Construtores e destrutorexplicit vector(const A & = A()); //Default vazio

    //Iniciado com n objectos tipo Texplicit vector(size_type, const T & =T(), const A & =A);

    vector (const vector&); //Por cpia~vector(); //Invoca destrutor de A

    //Sobrecarga do operador afectaovector &operator=(const vector&);

    //Mtodos de acesso//Acesso s dimensessize_type capacity() const {return endOfStorage-begin(); }size_type size() const 7return end() begin(); }size_type max-size() const {return allocator.max_size(); }bool empty() const {return size() = 0; }const A &get_allocator() const {return allocator;}

    //Acesso por iteradoriterator begin() {return start; }iterator end() {return finish; }const_iterator begin() const {return start; }const_iterator end() const {return finish; }

    //Acesso ao elementoreference front() {return (*begin()); 0reference back() {return (*end()-1)); }reference operator[] (size_type i) {return (*begin() + i)); }

    //Mtodos de insero e remoo de elementositerator insert(iterator p, const T &x);iterator (erase (iterator p);

    void push_back (const T &x) {insert(end(), x); }void pop_baxck () {erase(end() 1); }//Outros mtodos

    void reserve(size_type n);

  • 8/3/2019 resumoLivro

    19/49

    void clear();void swap(vector &x);

    private://Atributos

    A allocator; //allocator por omissoiterator start, finish, endOfStorage;

    //Mtodos auxiliaresvoid destroy(iterator start, itrator finish);iterator uninitializedCopy(const_iterator first, cons_iterator last, iterator p);iterator uninitializedFill(iteartor p, size_type n, const T &x);

    }; //Fim da definio do template de classes vector#undef SUPER

    4.5.1.1. ConstrutoresTodos os construtores constroem por cpia o atributo allocator.O construtor sem parmetros constri um vector vazio, colocando os atributos start, finish eendOfStorage a NULL, e no providencia reserva de espao.

    templatevector::vector(const a &a1) : allocator(a1), start(), finish(), endOfStorage() {}

    templatevector::vector(size_type n, const T &x, const AS &a1) : allocatro(a1) {

    start=allocator.allocate(n); //Pedir memria//Construir n elementos por cpiaendOfStorage = finish = uninitializedFill(star, n, x); }O construtor declarado explicit para que no promova a coero automtica do tipo size_typepara tipo vector

    template

    vector::iterator vector::uninitializedFill(iterator dest, size_type n, const T &x) {for(; n; --n, ++dest) allocator.construct(dest, x);return dest; }

    templatevector::vector(const vector &x) : allocator(x.allocator) {

    start = allocator.allocate(x.size());finish = uninitializedCopy(x.begin(), x.end(), start);endOfStorage = finish; }

    templatevector::iterator vectro::uninitializedCopy(iterator first, iterator last, iterator dest) {

    for(;first!=last; ++dest, ++first)allocator.construct(dest, *first);

    return dest;}

    4.5.1.2. DestrutorO mtodo destrutor destri todos os objectos contidos no vector e liberta memria reservada,invocando o mtodo deallocate() sobre o objecto allocatro.

    template vector::~vector() {destroy(begin(), end());allocator.deallocate(begin(), capacity()); }

    O mtodo auxiliar destroy() destri os objectos do domnio [first, last[, invocando o mtodohomnimo de allocator (pg.213)

  • 8/3/2019 resumoLivro

    20/49

    4.5.1.3. Mtodo reserve()O mtodo reserve(size_type n) garante que, aps ser invocado, a capacidade do vector maiorou igual a n. (pg.213)

    4.5.1.4. Operador AfectaoRequer cuidados especiais, devido ao facto de termos separado a reserva da iniciao.

    - Caso haja necessidade de expanso do espao de memria, destri os objectos contidos, libertaa memria reservada, reserva um novo bloco de memria e constri, nesse bloco, objectos porcpia dos contidos no vector a copiar.- No caso contrrio destri os restantes elementos do vector a afectar. (pg.214)

    4.5.1.5. Mtodo insert()Tambm requer cuidados:templatevector::iterator vector::insert( iterator p, const T &x) {

    if ( endOfStorage == end() ) { //No existe espao//Dimenso do antigo e do novo espaosize_type sz=size(), n=sz + (1 < sz ? sz : 1);//Pedir novo espaoiterator aux = allocator.allocate(n);//Construir por cpia no novo espao elementos at piterator newp=uninitializedCopy(begin(), p, aux);//Construir o elemento a inserir por cpiaallocator.construct(newp, x);//Construir por cpia no novo espao os elementos depois de p.uninitializedCopy(p, end(), newp+1);//Destruir os elementos do espao anteriordestroy(begin(), end());//Libertar o espao anterior

    allocator.deallocate(begin(), capacity());endOfStorage = aux + n;finish = aux + sz + 1; start = aux;return newp; //fica a apontar para o inserido.

    }if (p==end()) //Inserir no fim

    //Construir o elemento a inserir por cpiaallocator.contruct(end(), x);

    else { //Inserir no meio//Deslocar o ltimo, construindo por cpiacopy_backward(p, end()-1, end());*p=x; //Copiar o elemento a inserir

    }++finish; return p;

    }

    templateItBi2 copy_backward(ItBi1 first, ItBi1 last, ItBi2 res) {

    while (first!=last) *--res = *--last;return res;

    }

    4.5.1.6. Mtodo Erase()Desloca o domnio [p+1, end()[ para o domnio [p,end()-1[ e destri o ltimo elemento do vector.templatevector::iterator vector::erase(iterator p) {

  • 8/3/2019 resumoLivro

    21/49

    finish = copy (p+1, end(), p); //Desloca elementos (esmaga o que para apagar). Retornaiterador para o elemento past the end copiado.

    allocator.destroy(finish); //Destruir o excedentereturn p; }

    4.5.1.7. Mtodo clear()template

    void vector::clear(){destroy(begin(), end()); finish = start; }

    4.5.1.8. Mtodo swap()templatevoid vector::swap(vector &vx) {

    if (this != &X)if (allocator == x. allocator) {

    ::swap(start, x.start); ::swap(finish, x.finish);::swap(endOfStorage, x.endOfStorage);

    }else ::swap(*this, x);

    template inline void swap(U &a, U &b) {U aux(a); a=b; b=aux; }

  • 8/3/2019 resumoLivro

    22/49

    4.6. TEMPLATE DE CLASSES LIST uma estrutura linear de elementos (Nodes), encadeados entre si atravs de apontadores.A biblioteca standard tem listas duplamente ligadas com sentinela, o que permite iteraessequenciais nos dois sentidos. O n sentinela simplifica os algoritmos tornando-os mais eficientes.A interface muito parecida com o template de vector, diferindo no que toca ao desempenho dosmtodos. As diferenas fundamentais so:- Na list a memria para um novo Node automaticamente reservada quando se insere um

    objecto e automaticamente devolvida ao gestor de memria (allocator) sempre que se removeum objecto.- a list tem desempenho em tempo constante para remoes e inseres em qualquer ponto dasequncia para o qual se disponha previamente um iterador.

    4.6.1. Definio do template de classes list#define SUPER Container templateclass list: public SUPER {public:

    IMPORT_TYPE(size_type); IMPORT_TYPE(difference_type);

    IMPORT_TYPE(reference); IMPORT_TYPE(const_reference);IMPORT_TYPE(pointer); IMPORT_TYPE(const_pointer);private:

    struct Node;//Define ANode como tipo allocator de Node, da mesma famlia template da qual A o tipo

    allocator para T.typedef typename A::rebind::other ANode;typedef typename Anode::pointer NodePtr;typedef typename Anode::const_pointer ConstNodePtr;struct Node {NodePtr prev;NodePtr next;

    T data;};public://Definio dos iteradores

    class const_iterator {...}; //Definidos adianteclass iterator {...};

    //Os atributos da lista sero os seguintes:private:

    A constr; //Allocator para construir objectos TANode alloc; //Allocator para alojar e desalojar nodesNodePtr head; //Apontador para o n sentinela (dummy)size_type sz; //nmero de objectos contidos

    //Mtodos auxiliares//Aloja o n sentinela e inicia os membros e apontadores a apontarem para ele prprio

    NodePtr newNode();//Aloja e inicia um node com e, e promove o encadeamento dos apontadores posicionando-o atrsde sucNodePtr newNode(NodePtr suc, const T &e);//Desliga da lista o Node apontado por p e destri-ovoid deleteNode(NodePtr p);//Move um bloco entre duas listas se allocators iguaisvoid moveInAlloc (iterator p, iterator f, iterator l);//Move um bloco entre 2 listasvoid move(iterator p, list&, iterator f, iterator l);

    Interface Pblicapublic:

  • 8/3/2019 resumoLivro

    23/49

    //Construtores e destrutorexplicit list(const A &a1=A());//Lista iniciada com n objectos cpia de kexplicit list(size_type n, const T &k=T, const A &a=A());list(const list &lst);~list() {clear(); alloc.deallocate(head,1); }//Afectaes

    //Afectao com os objectos do domnio [first, last[template void assign(InIt first, InIt last);//Afectao com os objectos doutra lista do mesmo tipolist &operator=(const list &lst);Obteno de iteradoresiterator begin() {return head-->next; }iterator end() {return head;}//Dimensessize_type size() const {return sz;}bool empty() {return sz==0;}const A &get_allocator() const {return constr;}//Acesso aos elementosreference front() {return *begin(); }reference back() {return *(--end()); }//Inseres e remoes//Insere na posio anterior a p, um n por cpia de eiterator insert( iterator p, const T &e = T()); }//Insere na posio anterior a p, os objectos situados no domnio [first, last[templatevoid insert(iterator p, InputIter first, InputIter last);void push_front(const T &e) {insert (begin(), e); }void push_back(const T &e) {insert(end(), e); }//Remove da lista o n apontado por p

    iterator erase(iterator p);//Remove os ns contidos no domnio [first, last[iterator erase(iterator first, iterator last);void pop_front() {erase(begin()); }void pop_back() {erase(--end());}//Trocar o contedo entre duas listasvoid swap(list lst);//Interface especializada da lista (s existem na list)//Mover os elementos do domnio [f,l[ ou first da lista lst, para a posio anterior a p, na lista *this;//mover implica inserir numa lista e remover da outravoid splice(iterator p, list &lst, iterator f, iterator l);void splice(iterator p, list &lst, iterator first);

    //Pressupe listas ordenadas. Insere ordenadamente todos os elementos de lst, deixando-a vaziavoid merge(list &lst);void sort(); //Ordena os elementos da lista}; fim da definio do template de classes list#undef SUPER

    4.6.1.1. IteradoresDado que os ns da lista ocupam posies dispersas na memria, passar para o n seguinte nose traduz em incrementar simplesmente o apontador. Torna-se necessrio definir uma classeiterator, especfica para iterar em list. ver como em pg.222 e seguintes.Faz sobrecarga dos opeardores que permitam classific-lo como bidireccional. Assim, alm dosoperadores de desreferncia e afectao deve dispor tambm dos operadores de incremento edecremento (prefixos e sufixos). No dispe dos operadores += e -= pois no so de tempoconstante.O construtor com um apontador para n constri um iterador para esse n.

  • 8/3/2019 resumoLivro

    24/49

    A classe iterator para lista nested, interna, lista.Tem um nico atributo: NodePtr ptr;Tem um mtodo NodePtr current() const {return ptr;}

    4.6.1.2. Mtodos auxiliares newNode()A verso newNode() sem parmetros auxiliar dos construtores de listas tomando para si a tarefade alojar e iniciar o n dummy, colocando os apontadores next e prev a apontar para o prprio

    Node. O membro data no precisa ser iniciado.templatelist::NodePtr list::newNode() {

    NodePtr n = alloc.allocate(1); //Aloja o n dummy ereturn n->next = n->prev = n; //inicia os apontadores.

    //Construtor de lista vaziatemplateinline list::list(const A &a1) : constr(a1), alloc(a1), head(newNode()), sz(0) {}A verso newNode() com 2 parmetros auxiliar de todos os mtodos que necessitam criar e

    inserir na lista objectos Node. Ela reserva espao par um n, constri no campo data um objecto Tpor cpia do objecto cuja referncia lhe seja passada como segundo parmetro e, finalmente,promove o seu encadeamento na posio anterior do n cujo apontador lhe seja passado comoprimeiro parmetro.templatelist::NodePtr listnewNode(NodePtr suc, const T &e) {

    NodePtr n = alloc.allocate(1);constr.construct(&(n->data), e);NodePtr prev = suc ->prev;n->next = suc; n->prev = prev;prev->next = suc->prev = n;return n; }

    4.6.1.3. Mtodos de Insero

    Resulta extremamente simples, suportada no mtodo newNode() com 2 parmetros, que vimosantes. Insere na posio anterior a p.templatelist::iterator list::insert(iterator p, const T &e) {

    ++sz;return newNode(p.current(), e); }

    Insere na posio anterior a p, os objectos situados no domnio [first, last[ de outro contentorqualquertemplatetemplatevoid list::insert(iterator p, InIter first, InIter last) {

    for(; first != last; ++first)insert(p, *first); }

    4.6.1.4. Construtores com n objectos e por cpia4.6.1.5. Mtodo deleteNode()Desliga da lista o n a remover, afectando adequadamente o membro next do n antecessor e omembro prev do n sucessor. Seguidamente invoca o mtodo destroy sobre constr para destruiros dados sem libertar a memria e o mtodo deallocate sobre alloc para desalojar o n (devolvero espao de memria)templatevoid list::deleteNode(NodePtr n) {

    n->prev->next = n->next;n->next->prev = n->prev;constr.destroy(&(n->data));alloc.deallocate(n,1); }

  • 8/3/2019 resumoLivro

    25/49

    4.6.1.6. Mtodos de Remootemplatelist::iterator list::erase(iterator p) {

    deleteNode(p++).current());--sz;return p; }

    4.6.1.7. Operador afectao e mtodo assign()4.6.1.8. Mtodo swap()4.6.1.9. Mtodo splice()4.6.1.10. Mtodo merge()4.6.1.11. Mtodo sort()

  • 8/3/2019 resumoLivro

    26/49

    4.7. Template de Classes dequePode ser descrito como uma fila de espera com insero e remoo rpida em ambos osextremos.Tal como a lista, vocacionado para cumprir a disciplina FIFO ou FILO mas permite acesso

    aleatrio como o vector.Os contentores deque constituem uma verso mais verstil da estrutura de dados queue, muitoutilizada em programao e que se suporta num deque restringido a FIFO; um adaptador.Comparando deque com list e vector:- tal como o vector e contrariamente list, o deque permite acesso aleatrio a todos os objectoscontidos (embora em tempo constante so mais lentas que no vector).- Contrariamente ao vector, permite realizar, em tempo constante, aces de insero e remooem ambos os extremos- tambm contrariamente ao vector, permite que a memria reservadadiminua de dimenso quando predominam as aces de remoo.- Enquanto a list permite inseres e remoes em tempo constante no meio do seu domnio, odeque, tal como o vector, s permite executar essas aces em tempo linear.

    4.7.1. Estrutura de Dados de SuporteEste contentor suporta-se em blocos de memria (DataBlock) de dimenso fixa.Em tempo de execuo, o espao reservado para o deque pode ser ampliado em ambos ossentidos, associando-lhe novos DataBlock.Os apontadores para os DataBlock situam-se, centrados e ordenados, num outro bloco dememria de comprimento varivel que denominamos MapBlock.O template de classes deque tem como atributos dois iteradores: start e finish - cada iteradortem 4 apontadores -> h uma figura muito elucidativa na pg. 243 se me esquecer.Tem ainda como atributos map, que aponta para o MapBlock e mapSize que memoriza adimenso actual do MapBlock. Adopta-se 5 como o n mnimo para a dimenso do MapBlock.A dimenso dos dataBlock situa-se normalmente na ordem dos 100 elementos.

    4.7.2. Exemplos da Construo de um Dequequeremos construir um deque iniciado com 8 objectos tipo int, cpias do inteiro 0 e no qual,para facilitar, restringimos a 5 a dimenso dos DataBlock (DIM_BLOCK = 5)O critrio para organizar a estrutura de dados a seguinte:- Infere-se quantos DataBlock devem ser criados para iniciar o deque com 8 objectos;- Reserva-se espao para um MapBlock, satisfazendoo mnimo de 5 (DIM_MAP_MIN=5) e depoder armazenar um n de apontadores duplo do n de DataBlock a criar.- Reserva-se o n de DataBlock inferidos e situam-se, centrados no MapBlock, os respectivosapontadores.Os critrios de inferncia acima citados so:- O primeiro objecto a inserir num deque deve situar-se a meio do primeiro DataBlock, parapush_back() e push_front() posteriores.- Quando o n de objectos a inserir sequencialmente no DataBlock corrente vierem a ocupar altima posio disponvel, deve-se criar mais um DataBlock (o que proporciona maior eficincianos mtodos, por simplificao dos algoritmos).- Sempre que se cria um MapBlock para n apontadores para DataBlock, reserva-se sempre umespao duplo do necessrio (2*n) e inserem-se os n apontadores centrados nesse espao,prevendo futuras inseres, tanto em posies anteriores como posteriores s ocupadas.Segundo os critrios definidos:

    numOPos = numOfObj + DIM_BLOCK/2 + 1;// numOfPos = 8+5/2+1 =11numOfBlocks = numOfPos/DIM_BLOCK + (numOfPos%DIM_BLOCK !=0);//numOfBlocks=11/5 + 1=3

    mapSize = (numOfBlocks < (DIM_MAP/2))? DIM_MAP:numOfBlocks*2;mapSize = (3 < 5/2)? 5 : 6 = 6

  • 8/3/2019 resumoLivro

    27/49

    Definio do Template de Classes Deque#define SUPER Containertemplate class deque : public SUPER {public:

    IMPORT_TYPE(pointer); IMPORT_TYPE(const_pointer;IMPORT_TYPE(reference); IMPORT_TYPE(const_reference);IMPORT_TYPE(size_type); IMPORT_TYPE(difference_type);

    private://

    static const size_type DIM_MAP_MIN = 5;static const size_type DIM_BLOCK=512/sizeof(T);

    //typedef typename A::rebind::other AMap;typedef typename AMap::pointer MapPointer;template class IT {...};

    public: //typedef IT iteartor;

    //private:A blockAlloc;AMap mapAlloc;MapPointer map;size_type mapSize;iterator start, finish;//public://

    //Constri um deque vazioexplicit deque(const A &a1=A());

    //Constri um deque com n cpias de texplicit deque(size_type n, const T &t=T(), const A &a1=A());deque(const deque &x);~deque();deque &operatro=(const deque &x);

    ////Acesso s dimenses

    size_type size() const {return finish start;}bool empty() const {return start==finish;}

    //Acesso por iteradoriterator begin() {return start;}iterator end() {return finish;}

    //Acesso a elementos//Retorna uma referncia para o objecto indexadoreference operator[](size_type i) {return begin() [i];}//Retorna o objecto apontado por start.currentreference front() {return *begin();}

  • 8/3/2019 resumoLivro

    28/49

    4.8 Template de Classes RING BUFFER uma variante da queue de dimenso fixa, destinada a manter em memria os ltimos nelementos que lhe tenham sido inseridos.Tal como a queue um contentor com disciplina FIFO em que os objectos so inseridos no fim dafila e removidos no seu incio.Os mtodos so:push_back(T) insere no fim da filapop_front() remove no incio da filafront() acede ao elemento do incio para leituraback() acede ao elemento do fim da fila para escritaO RingBuffer implementado num array com dimenso fixa. Quando o array est cheio e seinsere um novo elemento, origina-se o overflow e o elemento que est no incio da fila perdidopor esmagamento.O par de iteradores start e finish mantm a dinmica de insero e remoo de forma similar aositeradores de um deque. A remoo de um objecto do ring buffer limita-se a avanar o iteradorstart, pois o removido sempre o do incio da lista.O array deve ter sempre uma posio no usada, de modo a que o teste de contentor cheio sedistinga do teste de contentor vazio.

    Assim, testar o contentor vazio resume-se a verificar se os iteradores start e finish apontam para omesmo objecto. A operao de insero que providencia que os iteardores no apontem para omesmo objecto se o contentor estiver cheio.O iterador do RingBuffer start, tem 2 atributos: array aponta para o incio do array; current aponta para o elemento 1 do RingBuffer; no finish, array aponta igualmente para o incio do arraye current aponta para o past the end.4.8.1. Definio do template RingBuffer#define SUPER Containertemplate class RingBuffer : public SUPER {public:

    IMPORT_TYPE(pointer); IMPORT_TYPE(const_pointer);

    IMPORT_TYPE(reference); IMPORT_TYPE(const_reference);IMPORT_TYPE(size_type);//

    typedef CircCount difference_type;private:

    template class IT {/*...*/}Interface Pblicapublic://

    typedef IT iterator;typedef IT const_iterator;

    //RingBuffer(const A &a=A());RingBuffer(const RingBuffer&);~RingBuffer();RingBuffer &operator=(const RingBuffer &);

    ////Acesso s dimensessize_type size() const {return finish-start;}size_type max_size() const {return DIM;}bool empty() const {return start==finish; }const A &get_allocator() const {return allocator;}//Acesso por iterador

    iterator begin() const {return start;}iterator end() const {return finish;}//Acesso aos extremosreference front() {return *begin();}

  • 8/3/2019 resumoLivro

    29/49

    reference back() {return *--end();}reference operator[](size_type idx)

    {return begin()[idx];}//

    void push_back(const T&);void pop_front();

    //

    void clear() {destroy(start, finish); finish=start}private://

    A allocator //Allocator para o array circular iterator start;iterator finish;

    //Mtodos auxiliaresiterator uninitializedCopy(const_iterator first, const_iterator last, iterator res);void destroy(iterator first, iterator last);

    };#undef SUPER

    4.8.1.1. IteradorO iterador do RingBuffer tem como atributos o ndice corrente do tipo CircCount (contador circularcom mdulo de contagem) e um apontador para o array, de forma a ser possvel as operaes dedesreferenciao e indexao.

    4.8.1.2. e 4.8.2.4. Construtores e Destrutor e Operador AfectaoConstrutor por omissoRingBuffer(const A &a=A()) : allocator(a), start(allocator.allocate(DIM+1)), finish(start) {}Construtor por cpiaRingBuffer(const RingBuffer &r) : allocator(r.allocator), start(allocator.allocate(DIM+1)),finish(uninitializedCopy(r.begin(), r.end(), begin())) {}

    com:iterator uninitializedCopy(const_iterator first, const_iterator last, iteartor res) {for(; first!=last; ++first, ++res)

    allocator. construct(&(*res), *first);return res;

    }Destrutor~RingBuffer() {

    destroy(start, finish);allocator.deallocate(start.array, DIM+1); }

    com:void destroy(iterator first, iteartor last) {

    for(;first!=last; ++first) allocator.destroy(&(*first));}

    4.8.1.3. Mtodos de Insero e Remoovoid push_back(const T &t) {

    allocator.construct(&(*finish, t);if(++finish==start)

    pop_front(); }

    void pop_front() {allocator.destroy(&(*start)); ++start; }

  • 8/3/2019 resumoLivro

    30/49

    CAP: 5 RVORES BINRIASAs estruturas em rvore um dos tpicos mais importantes de EDAEmbora no sejam componentes standard da biblioteca C++, a famlia dos contentoresassociativos suportam-se em rvores binrias de pesquisa balanceadas e o adaptador decontentores sequenciais priority_queue tem como modelo conceptual uma estrutura em rvorecompleta.Nas rvores cada n pode ter um n arbitrrio de sucessores.rvore: a coleco de ns cuja posio e informao contida satisfazem um determinadoconjunto de propriedadesNs so os objectos constituintes das rvoresRamos so as ligaes entre os nsRaiz o n de onde emergem, directa ou indirectamente, todos os ramos.Percurso um caminho possvel entre 2 ns, satisfazendo uma dada condioNvel de um n o nmero de ramos envolvidos no percurso entre a raiz e o n.Altura o mximo nvel (a raiz o nvel 0)Ascendente (ou pai)Descendentes directos (filhos)Folhas ou ns terminais

    Uma rvore diz-se ordenada, quando o posicionamento relativo dos descendentes de cada n significativo.Uma rvore binria aquela em que cada n tem no mximo dois descendentes directos.Uma rvore binria de pesquisa (ABP) uma rvore binria ordenada, em que o valor contidoem qualquer n maior ou igual que os valores contidos nos ns da sua subrvore esquerda emenor ou igual que os valores da sua subrvore direita.Uma rvore diz-se balanceada quando a diferena de alturas das duas subrvores de qualquern menor que 1.Uma ABP quase balanceada (rvore red-black), no pior caso a altura de uma das subrvoresnunca ultrapassa o dobro da outra, para todos os ns.Uma rvore diz-se perfeitamente balanceada se, relativamente a qualquer n, a diferena entreo nmero de ns das suas subrvores for no mximo 1.

    Diz-se completa se estiver inteiramente preenchida, isto , se todos os ns tm ambos os filhos,excepto no ltimo nvel que vai sendo preenchido da esquerda para a direita.Diz-se organizada em heap (monte) caso seja completa e todos os ns tiverem a propriedade doseu valor ser maior ou igual a qualquer dos seus filhos.

    5.2. ABPO desempenho da pesquisa aproxima-se tanto mais da pesquisa dicotmica sobre vectores(ordem log N), quanto mais balanceadas estas estiverem.Os ns so constitudos por objectos de uma classe, com os atributos:- O valor a armazenar- Um apontador para a sua subrvore esquerda- Um apontador para a sua subrvore direita

    No caso de no existir alguma subrvore, o respectivo apontador toma o valor NULL.Associada a uma estrutura de ns em rvore define-se um template de classes Tree, gestorasdessa estrutura, cujo atributo fundamental um apontador para o n raiz, dispondo de mtodospblicos (inserir n, remover n, aceder a todos os ns com um dado critrio de percurso.)

    5.2.1. Verso Bsica de ABPAdoptando um n dummy e acrescentando estrutura dos ns um apontador para o seuascendente, possvel definir (como prescreve o standard C++) um iterador bidireccional. Osexemplos so parecidos com o RBTree da biblioteca.#define SUPER Containertemplate

    class TreeBase : public SUPER {protected://

    struct Node;

  • 8/3/2019 resumoLivro

    31/49

    typedef typename A::rebind::other ANode;typedef typename ANode::pointer NodePtr;typedef typename Anode::const_pointer ConstNodePtr;struct Node {

    T values;NodePtr Left;NodePtr right;

    NodePtr parent;};//

  • 8/3/2019 resumoLivro

    32/49

    //Auxiliar de erase(), o n x substitudo pelo n y. O parent de x passa a parent de y. assubrvores direita e esquerda de x passam a subrvores direita e esquerda de y

    void transferNode(NodePtr x, NodePtr y);//Destri a rvore ou subrvore com raiz Em rvoid clear(NodePtr r);//Constri uma rvore por cpia da rvore com raiz em r. Retrorna apontador para raiz da

    cpia

    NodePtr copy(const TreeBase &x);//Retorna o n mais direita da subrvore r.template static NP rightMost(NP r);template static leftMost(NP r);//Auxiliar do mtodo pblico isBalance().static bool isBalanced(ConstNodePtr, int &);//Converter a rvore em lista; auxiliar do mtodo balance()static void treeToList(NodePtr r, NodePtr &header);//Converter lista em rvore; auxiliar do mtodo balance()static NodePtr listToTree(NodePtr &header, size_type n);

    //

  • 8/3/2019 resumoLivro

    33/49

    pair insertUni(const T &n);//Insere ordenadamente o valor n, mesmo que j existaiterator insertMulti( const T &n);//Remove da rvore o n cujo valor seja n, caso existasize_type erase(const T &n);//Remove da rvore o elemento apontado por ivoid erase(iterator i);

    //Remove todos os elementosvoid clear()//Promove o balanceamento da rvorevoid balance();

    //Mtodos auxiliares de debugging//Mostra ordenadamente os valores contidos na rvorevoid display() const;//Testa se a rvore est de facto ordenadabool isOrded() const;//Testa se a rvore est balanceadabool isBalanced() const;//Mostra a topologia da rvore usando espaamentos horizontais por nveisvoid printOn(ostream &o) const;

    };

    5.2.1.1. Percursos prefixo, infixo e sufixoPercorrer uma rvore consiste em visitar todos os seus ns por uma determinada ordem,entendendo-se por visitar um n realizar algum tipo de aco sobre o valor que lhe estejaassociado (contar o n total de objectos inseridos na rvore, mostrar no ecr esses valores, etc.)- O percurso prefixo (preorder) visita o n raiz, depois percorre a subrvore esquerda e,finalmente, percorre a subrvore direita;- Infixo: Esquerda, Raiz, Direita- Sufixo: Esquerda, Direita, Raiz

    Numa rvore de pesquisa ordenada de forma crescente tem relevncia o percurso infixo, dadoque ser esse o percurso usado pelo iterador para percorrer por ordem crescente.Em qualquer dos tipos de percursos, aco a executar sobre cada n determinada peloparmetro template Visit (objecto funo ou apontador para funo)//Percurso preordertemplate templatevoid TreeBase::preorder(NodePtr r, Visit visit) const {

    if(r==NULL) return;visit(r->value);preorder(r->left, visit);preorder(r->right, visit);

    Fazerpercurso inorder e postorder.

    Mtodo pblico displaytemplate void displayValue(const T &t) {cout

  • 8/3/2019 resumoLivro

    34/49

    Mtodo reursivo privadoNodePtr find(NodePtr r, const T &e) {

    if(r==NULL) return end();if(r->value < e) return find(r->right, e);if(r->value > e) return find(r->left, e);return r; }

    No entanto, dado que se trata de um mtodo recursivo terminal, facilmente convertvel forma

    iterativa, com melhor desempenho e sem precisar do mtodo auxiliar:iterator find(const T &e) {

    NodePtr r=root;while(r!=NULL) {

    if(r->value < e) r=r->right;else if(evalue) r=r->left;else eturn r;

    }return end();

    }No caso de existirem repeties, conveniente retornar o iterador para o elemento mais antigo.Por esse facto iniciamos um apontador com dummy ecomeando pela root executa-se:- caso o valor do n visitado seja menor que o valor procurado, prossegue-se a iterao nasubrvore direita- caso contrrio, afecta-se aux com o apontador para esse n e prossegue-se a iterao nasubrvore esquerda- atingindo uma folha, testa-se o valor de auxiliar:

    - caso aux seja dummy ou se o valor procuardo for menor que o valor apontado por aux,conclui-se pela sua no existncia e retorna-se o iterador para o past the end

    - caso contrrio, retorna-se o iterador par o n apontado por aux.Fazercom estas regras.

    5.2.1.4. Insero

    O mtodo pblico insertUni() deve retornar 2 valores: um bool a indicar se ocorreu ou noinsero e um iterador a apontar para o n da rvore em que o elemento reside, quer tenha sidoinserido, quer j existisse anteriormente.O modo normal como a biblioteca standard resolve o caso de um mtodo ter de retornar 2 valores,consiste em usar um template de estruturas pair, instanciar dele uma estrutura template pair comos parmetros adequados (do tipo dos valores a retornar) e declarar a funo retornando umainstncia dessa estrutura.template struct pair {

    U first; V second;pair(): first(U()), second(V()) {}pair(const U &u, const V &v) : first(u), second(v) {} };

    ex: Comea-se por comparar e com a raiz. Se menor que a raiz compara-se com raiz da

    subrvore esquerda, se maior, com a direita, se maior direita, se vazia, isere-se; e afecto omembro right do n com o endereo do novo n.pair insertUni(const T &e) {

    NodePtr r; //Apontador para o novo nif root(==NULL) //rvore vazia

    r=root=dummy->left=dummy->right=newNode(dummy, e); //inicia root comparent=dummy; left e right=NULL

    else {r=root;for(;;)

    if (e < r->value)if(r->left != NULL) r=r->left;else {r=insertLeft(r,e); break; }

    else if (r->value < e)if (r->right != NULL) r=r->right;

  • 8/3/2019 resumoLivro

    35/49

    else {r=insertRight(r,e); break; }else

    return pair(r,false);}++sz; return pair(r, true);

    }Os mtodos auxiliares insertLeft() e insertRight() realizam a insero, afectando o membro left ou

    right do n passado como parmetro com o endereo de um novo n. Providenciam aactualizao de dummy->left ou dummy->right se a insero for realizada num dos extremos darvore e retornam o apontador para o novo n.Fazercom estas regras.

    Mtodo InsertMultiEx: comea-se por comparar 6 com a raiz. dado que 6 igual a 6, compara-se com 8 nasubrvore direita, seguidamente com 7 e ao tentar comparar com a raiz da subrvore esquerda don 7, constata-se que esta subrvore est vazia. Ento insere-se como descendente esquerdo do7.Fazercom estas regras.

    5.2.1.5. RemooH 2 mtodos: um para remover objectos dado o valor e outro dado um iterador para o n ondeesse objecto se encontra.erase(T &e) remove todos os objectos com valor igual a e retornando o n de objectos removidos.Comea por invocar o mtodo find(), que retorna um iterador para o 1 n a remover (caso exista)ou o iterador end() caso no exista. Se existir invoca repetidamente o mtodo erase(i),incrementando o iterador, enquanto o valor apontado pelo iterador for igual ao valor a remover(ordenada por valores ???)templateTreeBasesize_type TreeBase::erase(const T &e) {

    size_type count = 0; iterator p = find(e);

    if (p != end())do {++count; erase(p++); } while (p!=end() && !(e

  • 8/3/2019 resumoLivro

    36/49

    templatevoid TreeBase::erase(iterator i) {

    NodePtr r = i.current;if (r == dummy.left) //Actualizar left most

    dummy->left=(++iterator(i)).current;if(r == dummy->right)

    dummy->right=(--iterator(i)).current;

    if (r->left == NULL) transferParent(r, r->right);else if (r->right == NULL) transferParent(r, r->left);else {

    NodePtr previous = rightMost(r->left); //ProcurartransferParent(previous, previous->left); //DesligartransferNode(r, previous); //substituir

    }--sz;deleteNode(r); //Libertar memria

    }

    5.2.1.6/7/8/9 Construtor por Cpia / Operador afectao por cpia / Mtodos auxiliares newNode()e deleteNode() / Destrutor

    5.2.1.10. BalanceamentoJ realmos a necessidade de manter a rvore balanceada (repetidas inseres e remoesdesbalanceiam), sob pena de degradar drasticamente o desempenho dos seus mtodos..O mtodo que vamos analisar permite regenerar o balanceamento de uma rvore, comdesempenho pouco eficiente O(n), facto que no o torna recomendvel para aplicaesgenricas. A soluo para garantir a permanncia do balanceamento das rvores, frente arepetidas inseres e remoes, sem penalizaes gravosas de desempenho, ser estudada maisadiante, nas rvores red-black.

    No entanto didctico e elegante pois manipulamos s apontadores, sem necessidade de realizarcpias.- Converte a rvore numa lista ordenada simplesmente ligada, invocando o mtodo auxiliartreeToList() e, seguidamente, converte a lista numa rvore balanceada, invocando listToTree().template void TreeBase::balance() {

    if (size() parent = dummy;

    }Converso de uma rvore em lista

    este mtodo providencia a concatenao de todos os ns da rvore numa lista ordenada,simplesmente ligada, usando o campo right dos ns da rvore como apontador next da lista.O algoritmo recursivo :- Se a rvore estiver vazia, terminar o algoritmo;- Converter em lista a subrvore direita;- Inserir o n raiz cabea da lista produzida;- Converter em lista a subrvore esquerda (ficando antes da j produzida).templatevoid TreeBase:: treeToList(NodePtr r, NodePtr &header) {

    if(!r) return;treeToList(r->right, header);r->right = header; header = r;treeToList(r->left, header);

    }

  • 8/3/2019 resumoLivro

    37/49

    Converso em rvore de n Elementos de uma Lista- Se o n de ns da lista for zero, a rvore vazia e termina o algoritmo- Converter em rvore a primeira metade dos ns;- Desligar o n que ficou situado cabea da lista, que passar a constituir a raiz da rvore- Agregar raiz como subrvore esquerda a rvore j obtida- Converter em rvore os restantes ns da lista (n de ns da lista original menos metade menosum) e agregando-a raiz como subrvore direita.

    ...

    5.3. rvores Binrias Organizadas em HeapHeap (monte) toma diferentes significados em informtica.No presente contexto queremos referir a estrutura de dados representada como uma rvorebinria completa, tal que, qualquer dos seus ns toma valor maior ou igual ao dos seus filhos,garantindo por esse facto que o n de maior valor a raiz.5.3.1. Estrutura HeapTem propriedades muito interessantes que a recomendam para suporte do adaptador doscontentores standard priority_queue e como base conceptual do algoritmo de ordenaoheap_sort, aplicvel a contentores sequenciais com acesso aleatrio.

    Dado ser completa tem representao implcita em array (bloco contguo de memria).

    5.3.1.1. Representao de rvores Completas em ArrayNumeramos os ns de uma rvore completa de cima para baixo e da esquerda para a direita,atribuindo raiz o n 0, a rvore tem uma representao implcita em array, inserindo cada umdos seus ns no ndice correspondente numerao que lhe foi atribuda.Desta correspondncia resulta uma relao aritmtica simples entre os ndices ocupados pelosns da rvore e os ndices ocupados pelos seus filhos esquerdo e direito, Nomeadamente:- Um n situado no ndice k tem o seu filho esquerdo situado no ndice 2*k+1 e os eu filho direitono 2*k+2- Os filhos esquerdos situam-se nos ndices mpares e os direitos nops pares- Se um filho esquerdo(direito) estiver no ndice k, o seu irmo direito(esquerdo) est no k+1(k-1)- O pai de um n situado no ndice k situa-se em (k-1)/2As estruturas de dados representados em rvores completas podem ser alojadas em array ou emqualquer contentor sequencial, cujo iterador seja de acesso aleatrio, como o caso do vectoredeque.Uma das consequncias importantes que advm do facto de uma estrutura heap ser representadaimplicitamente num array, no ser preciso que na sua implementao os ns da rvoredisponham dos apontadores left, right e parent como na ABP. O n, neste caso, exclusivamenteconstitudo pelo objecto T (valor).

    5.3.1.2. Algoritmos genricos standard das estruturas heapAs setruturas heap revelam-se muito interessantes quendo se trate de aplicaes que se

    pretenda, atravs de aces push_heap, inserir num contentor sequencial valores aleatrios epoder retirar desse contentor, atravs de uma aco pop_heap(), o elemento de maior valor, oude menor valor, conforme o critrio de comparao utilizado. Nas estruturas heap consegu-se issocom complexidade O(log n), como s as rvores balanceadas conseguem.

  • 8/3/2019 resumoLivro

    38/49

    5.4 Adaptador Sequencialpriority_queueUm adaptador de contentores sequenciais consiste num template de classes contentoras, quetoma como parmetros tipo no s o tipo de objectos que vai alojar, como tambm o tipo decontentor sequencial em que se suporta.Da biblioteca STL de componentes constam 3 tipos de adaptadores de contentores sequenciais:- stack (pilha)

    - queue (fila de espera)- priority_queue (fila de espera com prioridades)Os primeiros 2 tipos no utilizam estruturas em rvore e as suas definies, para alm dosconceitos que os 3 partilham, resumem-se a uma aplicao dos temas j tratados no captuloanterior. O 3 baseia-se numa estrutura em heap, e interessante p-lo em confronto com osoutros 2 para podermos inferir as aplicaes mais adequadas a cada.

    5.4.1. Adaptadores de ContentoresCaracterizam-se por disponibilizar um n muito reduzido de mtodos pblicos, correspondentes saces que lhe so tpicas.

    5.4.1.1. Class stackObedece estritamente a uma disciplina FILO e disponibiliza:- push() para inserir objectos no topo da pilha- pop() para retirar/remover objectos do topo da pilha- top() retorna uma referncia para o objecto situado no topo da pilhaO parmetro tipo ou segundo argumento do template pode ser o vector, deque ou list, j quetodos dispem, na sua interfgace, mtodos que do suporte directo s aces que soespecficas dos contentores sequenciais, nomeadamente:- push_back() acrescenta o elemento indicado como argumento, que do tipoSequence::value_type, no fim do contentor sequencial.- pop_back() no toma argumentos e retira o elemento armazenado no fim do contentor.- back() retorna uma referncia para o elemento que se encontra no fim do contentor.O parmetro tipo Sequence deve ser escolhido criteriosamente, conforme a aplicao a que se

    destina o stack, tendo em conta que:- O vector pode aumentar o espao reservado, mas no permite reduzi-lo em run-time- O deque permite aumentar e reduzir em run-time e as aces so um pouco menos eficientesque as do vector- A list reserva e devolve espao em run-time, mas apesar de terem complexidade constante nosmtodos pretendidos, so mais lentos que os anteriores.A diferena bsica dos contentores sequenciais e dos adaptadores que os 1s implementameles prprios a estrutura de dados que lhe especfica, enquanto os adaptadores toma comoparmetro o tipo de contentor e agregam como atributo um objecto desse tipo ao qualdelegam as aces de acesso.

    templateclass stack {public:

    typedef typename Sequence::value_type value_type;typedef typename Sequence::size_type size_type;typedef typename Sequence::reference reference;typedef typename Sequence::const_reference const_reference;typedef Sequence container_type;

    //protected:

    Sequence c;//

    public: stack() : c() {}explicit stack(const Sequence &s) : c(s) {}bool empty() const {return c.empty();}

  • 8/3/2019 resumoLivro

    39/49

    size_type size() const {return c.size();}reference top() {return c.back();}void push(const value_type &x) {c.push_back(x);}void pop() {c.pop_back();}friend bool operator==(const stack &x, const stack &y) {return x.c==y.c;}

    };

    5.4.1.2. Classe queueEste adaptador obedece disciplina FIFO e disponibiliza:push() Insere objectos na fila de espera;pop() Remove objectos na cabea da fila;front() Retorna uma referncia para o objecto que permanece mais tempo na filaback() Retorna uma referncia para o objecto que foi mais recentemente inserido.Estas aces podem ser delegadas num contentor sequencial que disponha de um mtodopop_front() que d suporte ao pop, o que exclui o vector, dado que este no permite remoesno incio do domnio em tempo constante.A definio semelhante, pelo que deixamos como exerccio.

    5.4.2. Definio do template priority_queuePode entender-se como um refinamento do queue e dispe:push() Insere objectos na fila de espera;pop() Remove o objecto ao qual foi atribudo maior prioridade atravs do objecto funo tipoCmp que lhe seja passado como 3 parmetro template.top() Retorna uma referncia para o objecto de maior prioridade.O pequeno pormenor que distingue o adaptador priority_queue do adaptador queue o facto dostandard impor complexidade O(log n) aos algoritmos de todos os seus mtodos, o que implicaque a representao do contentor sequencial em que se suporte seja organizado segundo umadisciplina heap.Este adaptador suporta-se, por omisso, num vector, e os seus mtodos invocam os algoritmos

    push_heap() e pop_heap() j apresentados.templateclass priority_queue {public:

    typedef typename Sequence::value_type value_type;typedef typename Sequence::size_type size_type;typedef typename Sequence::reference reference;typedef typename Sequence::const_reference const_reference;typedef Sequence container_type;

    //

    protected:Sequence c; Cmp cmp;//public:

    explicit priority_queue(const Cmp &cp = Cmp(), const Sequence &pq=Sequence()) :cmp(cp), c(pq) {}

    bool empty() const {return c.empty();}size_type size() const {return c.size();}const value_type &top() const {return c.front();}void pop() {pop_heap(c.begin(), c.end(), cmp); c.pop_back(); }void push(const value_type &x) {c.push_back(x); push_heap(c.begin(), c.end(), cmp);}

    };

  • 8/3/2019 resumoLivro

    40/49

    CAP.6 RVORES BALANCEADAS6.1. IntroduoAs rvores binrias ordenadas por valor de chave de pesquisa so muito boas quanto aodesempenho das aces de pesquisa, remoo e insero, mas exigem que se mantenhambalanceadas, isto , que a sua altura se mantenha da ordem do logaritmo do nmero deelementos que contm.

    Assim, temos que adoptar mtodos de insero e remoo que preservem os eu balanceamento.Em casos especficos, alternativamente, podemos manter controlo sobre a altura e sempre queesta exceda um determinado valor (como sugere Knuth) 5.log2n, balancear com um mtodo comoo que se apresentou no cap. anterior, que exige tempo de execuo linear O(n).Em 1962 foram apresentadas as AVL que so ABP que garantem insero e remoo compermanncia de balanceamento.Em 1970 R.Bayer desenvolveu estrutura arborescente de pginas, com elevado n de chaves depesquisa por pgina. Multidescendentes, portanto e garantem insero e remoo commanuteno de balanceamento. So as B-Tree ou rvores de Bayer.Depois desenvolveu uma variante symmetric binary B-Tree, que B-Tree de ordem 3 (com 2 ou3 descendentes por pgina) vocacionada para residir em memria central.Estas evoluram para ordem 4 (2, 3 ou 4 descendentes), denominadas red-black.

    A generalidade das implementaes da biblioteca standard do C++ adoptam as rvores red-blackcomo suporte dos contentores associativos.Os algoritmos das rvores red-black, relativamente s ABP, s diferem quanto aos mtodos deinsero e remoo.No entanto, dada a complexidade relativa, quer da implementao, quer da anlise destes 2mtodos, vamos adoptar uma abordagem a 3 nveis: grfica, pseudo-cdigo e C++ importante pedagogicamente pois o mtodo que deve ser abordado quando algoritmos somuito complexos (mais de 7 decises segundo psiclogos).

    6.2. Estruturas B-Tree (rvores de Bayer)Desde os primrdios da informtica que o objectivo de aceder com eficincia a bases de dados de

    grandes dimenses, com natureza persistente, ocupa lugar de destaque.dado o tempo de latncia, impe-se que os acessos a ficheiro no se faam individualmente poritem, como nas rvores binrias, mas sim por pginas (com dezenas ou centenas de itens).Numa ABP mesmo que equilibrada, envolvendo um milho de itens, uma aco de pesquisa poderequerer o teste de 20 ns (O(log2 n). Se aglomerarmos os itens em pginas de 100 itens, o nmximo de acessos a pginas, para a mesma quantidade de itens, apenas 3.Num regime de inseres e remoes frequentes, torna-se impossvel garantir que todas aspginas tenham o mesmo n de itens inseridos.O balanceamento refere-se a pginas. Torna-se necessrio ento providenciar um n mnimo emximo de itens por pgina, at por causa do espao ocupado em disco.A ordem de uma B-Tree o n mximo de descendentes de cada pgina.Uma B-Tree de ordem N satisfaz:- Todas as pginas tm no mximo N descendentes- Todas as pginas, excepto a raiz, tm no mnimo N/2 descendentes- A raiz tem no mnimo 2 descendentes ( a menos que tambm seja folha)- As folhas situam-se todas ao mesmo nvel e no tm descendentes- Uma pgina que no seja folha, com k descendentes, contm k-1 itens- Numa B-Tree de ordem N, o n de itens contidos situam-se entre N-1 e (N-1)/2 inclusive.item corporizado por uma estrutura contendo um membro com a chave de pesquisa e ummembro com o valor associado chave.Os valores inteiros aparecem por ordem crescente da esquerda para a direita, se imaginamos a B-Tree comprimida num nico nvel.

    6.2.1.1. Algoritmo de PesquisaVamos considerar cada um dos valores inseridos na B-Tree como raiz de uma rvore, com umasubrvore esquerda, onde se situam valores inferiores a essa raiz, e com uma subrvore direitaonde se situam valores que lhe so superiores.

  • 8/3/2019 resumoLivro

    41/49

  • 8/3/2019 resumoLivro

    42/49

    CAPTULO 7 CONTENTORES ASSOCIATIVOS

    TEORIAO standard ANSI/ISO estabelece para os contentores associativos que estes devem garantircomplexidade O(log n) para os mtodos de pesquisa, insero e remoo (ao contrrio doscontentores sequenciais).Assim, tm de ser suportados em rvores binrias balanceadas (ou quase balanceadas).Os contentores associativos standard que vamos estudar suportam-se no template de classesRBTree, derivando desse template.As tabelas de hash, por vezes, so uma boa alternativa relativamente s rvores, como estruturasde suporte dos contentores associativos, pelo que vamos tambm definir essa extenso biblioteca standard.As tabelas de hash so de utilizao recomendvel, por exemplo, nos casos em que o objectivo aatingir no reduzir o n de colises de chaves ao mnimo, mas sim repartir por vrioscontentores parciais os elementos a que se pretende aceder com eficincia.

    Mritos e demritos dos contentores sequenciais:

    VECTOR M Suporta iteradores de acesso aleatrio;Complexidade O(1), constante, para insero e remoo no fim do contentor.

    D Complexidade linear para inseres e emoes no meio e incio do domnio;Limitaes quanto evoluo dinmica: podem aumentar o espao reservado mas no diminuiposteriormente.DEQUE - M Suportam iteradores de acesso aleatrio (menos eficientes que os de vector);Complexidade O(1) para inseres e remoes em ambos os extremos;Podem aumentar e diminuir o espao reservado ao longo da evoluo dinmica.

    D

    Complexidade linear O(n) para inseres e remoes no meio do domnio.LIST - M Complexidade O(1) para inseres e remoes em qualquer ponto.

    D Suportam apenas iteradores bidireccionais;Complexidade linear na pesquisa;

    Para estruturas de grandes dimenses no tolervel a complexidade O(n) para aces quesejam frequentemente invocadas.A biblioteca STL define 4 variantes de contentores associativos:MAP contentor de elementos constitudos por pares (chave, dados), ordenados por chave, semrepeties;MULTIMAP map que aceita repeties de chaves equivalentes;SET contentor de elementos constitudos apenas pela chave, sem repeties;MULTISET set que aceita mltiplas chaves equivalentes.So denominados associativos porque associam chaves a dados.

    INTERFACE PBLICAbegin ()Retorna um iterator ou const_iterator para o primeiro elemento.end()Retorna um iterator ou const_iterator para o past the end.

    swap(container)Trocar os elementos com o contentor indicadoclear()

  • 8/3/2019 resumoLivro

    43/49

    Remover todos os elementossize()Retorna o n de elementosmax_size()Retorna a dimenso mxima que pode atingriempty()Retorna true se o contentor estiver vazio

    // Mtodos adicionais da interface pblica:key_comp()Retorna o objecto funo comparao de chaves usado na construovalue_comp()Retorna o objecto funo de comparao de valores usado na construo.insert(t)Insere o valor t. Retorna o pair, em que o primeiro membro aponta para umelemento com chave equivalente de t ou para o elemento inserido, conforme o segundo sejafalse ou true.insert(p,t)Idntico ao anterior, em que o iterador p indica onde deve comear a pesquisa.insert(i,j)Insere os elementos situados no domnio [i,,j[ definido pelos iteradores i e j.erase(k)Remove elementos com chave k e retorna o n de elementos removidoserase(q)Remove elemento apontado por qfind(k)Retorna iterador para elemento com chave equivalente a k, ou para o past the end.count(k)Retorna n de elementos com chave klower_bound(k) ; upper_bound(k) ; equal_range(k)

    Conjunto de tipos dependentes do objecto funo comparao Cmp, que os contentores devemdefinir:key_type - tipo das chaveskey_compare tipo da comparao usada para ordenar chavesvalue_compare tipo da comparao usada para valores.

    Construtor recebem como argumentos um objecto Cmp, que estabelece o modo de comparaodos elementos, e um allocator. Por omisso dos argumentos usado o objecto funo Cmp eallocator A, construdos com o construtor sem parmetros dos tipos indicados nos parmetrostemplate.

    TEMPLATE DE CLASSES MAPtemplate struct FirstOfPair {

    const K &operator() (const pair &p) const{return p.first;} };

    #define SUPER RBTreetemplate

  • 8/3/2019 resumoLivro

    44/49

    T &operator[](const K &key){return insert(value_type(key, T())).first->second; }

    };#undef SUPER

    EXEMPLO DE COMO SE INSTANCIA E USA O TEMPLATE DE CLASSESmapvoid main() {

    typedef map Table;Table table;string word;while (cin >> word)

    ++table[word];table::iterator i;for (i=table.begin(); i != table.end(); ++i)

    cout first word) {

    column=is.telg() word.size() + 1;table.insert(Value(word, Position(numLine, column)));

    }}for (iterator i=table.begin(); i != table.end(); ++i)

    cout first

  • 8/3/2019 resumoLivro

    45/49

    TABELAS HASH (abertas)TEORIAAs tabelas de hash adoptam o critrio de converter a chave de pesquisa, por uma relaoaritmtica, directamente no ndice de um array onde se encontra o valor a ela associado.Em casos favorveis consegue-se encontrar em tempo constante o valor pesquisado, ou seja,envolvendo um nico teste.

    A correspondncia entre o universo das chaves e o universo dos ndices deve ser unvoca masnormalmente no biunvoca.Assim, as colises so normais, isto , associado a cada ndice do array a, no correspondeexclusivamente uma chave, mas sim uma lista de chaves, associadas aos respectivos dados.A pesquisa dos dados associados a uma chave exigir, alm da execuo da funo h(k), umacesso ao array a indexado por h(k) e o teste de comparao para confirmar se de facto a[h(k)]corresponde chave procurada. 3 casos pode ocorrer:a[h(k)] um apontador NULL ==> chave k no consta da tabela.a[h(k)] aponta par um n da lista da qual consta a chave k ==> pesquisa com um s testea[h(k)] aponta para um n da lista que no corresponde chave pesquisada ==> testessequenciais ao longo da lista - O(n).O factor de carga M/N. Quanto menor for o factor de carga, menor a probabilidade de colises,

    como convm (mas a relao no linear).Caso as chaves de pesquisa sejam strings deve inicialmente providenciar-se a converso dastring num valor numrico e s depois efectuar a converso desse valor em ndices do array.Baseados numa estimativa do n mximo de chaves a inserir na tabela, implementa-se um arrayde apontadores para listas simplesmente ligadas.Dos ns das listas constam pares (chave, valor) (mais apontador para next).A cada conjunto de chaves em coliso chama-se bucket. Deseja-se pois que os buckets nosejam muito grandes pois no interior deles que se tem de pesquisar (sequencialmente) no casode colises de chaves.FUNES HASHCondies bsicas:- Envolver operaes aritmticas de rpida execuo- Minimizar o n de colisesDas caractersticas da funo hash depende a eficincia dos mtodos de insero, remoo epesquisa. Deve pois apresentar probabilidade uniforme para todos os elementos docontradomnio, mas isso tambm depende da distribuio das chaves de domnio.No h funo hash ptima para todas as aplicaes.endereamento directo domnio dos valores de chaves = domnio dos ndices do array. funohash perfeita, porque biunvoca. No sempre possvel devido ao desperdcio de memria.O critrio que preside ao estabelecimento de uma funo hash procurar uma relao entre achave de pesquisa e um valor numrico, mdulo size_t, o mais disperso possvel. Ento melhor que N seja sempre n primo.CRITRIOS DE OPTIMIZAO

    Dimenso do array:- Deve ser n primo- Ser maior que o n de chaves que previsvel inserir (factor de carga < 1)- Se pretendido tabela dinmica, tem de estar-se sempre a verificar factor de carga e, quando seaproximar de 1, aumentar o tamanho do array para o n primo que seja o mais prximo do dobrodo anterior. Esta operao morosa mas imprescindvel.Para poupar tempo interessa que na definio da tabela conste como constante um array denmeros primos previamente calculados, organizado por ordem crescente com progressogeomtrica de razo 2, atravs da qual a dimenso real a adoptar para a tabela de hash se faapor mera consulta a esse array. Usa-se o crivo de Eratosthenes. Pode-se ento construir umaclasse Prime, que contm como atributo o ndice i do array, e com os seguintes mtodos:Prime(n) construtor invocado com o valor estimado para a dimenso da tabela afecta i com o

    ndice do nmero primo aproximado por excesso.set(n) Afectai com o ndice do n primo aproximado por excesso a n

  • 8/3/2019 resumoLivro

    46/49

    operator prime_type operador de converso para prime_type que retorna o n primocorrespondente ao ndice inext() incrementa i e retorna o n primo correspondente.get() auxiliar para retornar o n primo correspondente ao ndice iFUNO hash_string...

    TEMPLATE DE FUNES HASHDo template de tabelas hash consta como parmetro-tipo a classe template objecto funo hashque se pretenda adoptar, tomando por omisso a classe template de uso genrioco mostrada aseguir:

    template struct Hash {

    size_t operator() (unsigned long x) const{return size_t(x); }

    };Este template de classes objecto funo toma como parmetro o tipo da chave, tem uma verso

    bsica para os tipos integrais (convertveis em unsigned long) que se limita a retornar o valor doparmetro e especializaes para tipo char* e string.Na especializao para string C-style ou string, o operador chamada a funo pe em execuo afuno hash_string() de uso genrico (por exemplo, uma das que se estudaram anteriormente)templatestruct Hash {

    size_t operator() (const char *s) const{return hash_string(s); }

    };

    templatestruct Hash {

    size_t operator() (const string &s) const{return hash_string(s.c_str());}

    };

    TEMPLATE DE CLASSES HashTable---> Parmetros tipo:K a chave de pesquisaFH a classe funo de hash. Como valor por omisso instanciada a classe template HashV a classe dos valoresKFromV um tipo de objecto funo que infere K a partir de VEqual um tipo objecto funo que estabelece o critrio de equivalncia das chaves de pesquisaA o tipo de allocatoradoptado

    #define SUPER Co