720 likes | 818 Views
Estruturas Fundamentais. Sumário. Objetivo do Curso Estruturas de Dados Fundamentais Implementação Java A classe Array A classe LinkedList Implementação C++ A classe Array A classe LinkedList. Objetivo do Curso. Estudo de tipos abstratos de dados tais como Pilhas Filas Deques Listas
E N D
Sumário • Objetivo do Curso • Estruturas de Dados Fundamentais • Implementação Java • A classe Array • A classe LinkedList • Implementação C++ • A classe Array • A classe LinkedList
Objetivo do Curso • Estudo de tipos abstratos de dados tais como • Pilhas • Filas • Deques • Listas • Árvores • Filas de Prioridades • etc
Estruturas de Dados Fundamentais • As Estruturas de Dados Fundamentais para a criação dos tipos abstratos de dados são: • Arrays • Listas Encadeadas
Características das Linguagens • Nenhuma linguagem de programação possui nativa a classe Lista Encadeada. Assim será necessário implementar esta classe. • A classe array é nativa de toda linguagem de programação • Em C++ não existe expressões sobre arrays. Não se pode passar um array como parâmentro de função nem retornar um array de uma função. Não se pode atribuir o valor de um array a a outro array • Na linguagem Java é usual criar uma extensão para a classe Array
Arrays primitivos em Java • Os arrays em Java possuem três limitações que seria interessante contornar: • Índices sempre vão de 0 até n-1 • Não existe atribuição para todo um array • O tamanho de um array não pode ser alterado • Para contornar estas limitações pode-se definir uma extensão : a classe Array
Classe Array (extensão a Java) public class Array { protected Object[] data; protected int base; // ... }
Construtores da classe Array public class Array { protected Object[] data; protected int base; public Array (int n, int m) { data = new Object[n]; base = m; } public Array () { this (0, 0); } public Array (int n) { this (n, 0); } // ... }
Método assign public class Array { // cria uma cópia da lista corrente protected Object[] data; protected int base; public void assign (Array array) { if (array != this) { if (data.length != array.data.length) data = new Object [array.data.length]; for (int i = 0; i < data.length; ++i) data [i] = array.data [i]; base = array.base; } } // ... }
Métodos getData, getBase e getLength public class Array { protected Object[] data; protected int base; public Object[] getData () { return data; } public int getBase () { return base; } public int getLength () { return data.length; } // ... }
Métodos de indexação get e put public class Array { protected Object[] data; protected int base; public Object get (int position) { return data [position - base]; } public void put (int position, Object object) { data [position - base] = object; } // ... }
Emprego de get e put • Caso se desejasse fazer a[2] = b[3] usando a classe Array escrever-se-ia a.getData()[2] = b.getData()[3]; • Isto é feio e como não existe sobrecarga de operadores em Java definem-se métodos de indexação get e put obtendo a.put (2, b.get (3));
Redimensionamento – Métodos setBase e setLength public class Array { protected Object[] data; protected int base; public void setBase (int base) { this.base = base; } public void setLength (int newLength) { if(data.length != newLength) { Object[] newData = new Object[newLength]; int min = data.length < newLength ? data.length : newLength; for(int i = 0; i < min; ++i) newData [i] = data [i]; data = newData; } } // ... }
Classe LinkedList public class LinkedList { protected Element head; // cabeça protected Element tail; // cauda public final class Element { // elemento do lista Object datum; // dado do elemento ou item Element next; // ponteiro para sucessor Element(Object datum, Element next) { // construtor this.datum = datum; this.next = next; } public Object getDatum() // obter dado { return datum; } public Element getNext() // obter sucessor { return next; } // ... } // ... }
Métodos Construtor e purge public class LinkedList { protected Element head; protected Element tail; public LinkedList () // construir uma lista {} public void purge () // esvaziar uma lista { head = null; tail = null; } // ... }
Métodos getHead, getTail e isEmpty public class LinkedList { protected Element head; protected Element tail; public Element getHead () // cabeça da lista { return head; } public Element getTail () // cauda da lista { return tail; } public boolean isEmpty () //teste de lista vazia { return head == null; } // ... }
Métods getFirst e getLast public class LinkedList { protected Element head; protected Element tail; public Object getFirst() { // obter o primeiro elemento //da lista if(head == null) throw new ContainerEmptyException(); return head.datum; } public Object getLast() { // obter o último elemento //da lista if(tail == null) throw new ContainerEmptyException(); return tail.datum; } // ... }
Método prepend public class LinkedList { protected Element head; protected Element tail; // inluir o objeto item no início da lista corrente public void prepend(Object item) { Element tmp = new Element(item, head); if(head == null) tail = tmp; head = tmp; } // ... }
Método append public class LinkedList { protected Element head; protected Element tail; // incluir o objeto item no final da lista corrente public void append (Object item) { Element tmp = new Element (item, null); if(head == null) head = tmp; else tail.next = tmp; tail = tmp; } // ... }
Método assign public class LinkedList { protected Element head; protected Element tail; // a lista list será uma cópia da lista corrente public void assign(LinkedList list) { if(list != this) { purge (); for(Element ptr = list.head; ptr != null; ptr = ptr.next) { append (ptr.datum); } } } // ... }
Método extract (1) public class LinkedList { protected Element head; protected Element tail; // Exclui objeto item public void extract(Object item) { Element ptr = head; Element prevPtr = null; while(ptr != null && ptr.datum != item) { prevPtr = ptr; ptr = ptr.next; }
Método extract (2) if(ptr == null) throw new IllegalArgumentException("item not found"); if(ptr == head) head = ptr.next; else prevPtr.next = ptr.next; if(ptr == tail) tail = prevPtr; } // ... }
Métodos insertAfter e insertBefore (1) public class LinkedList { protected Element head; protected Element tail; public final class Element { Object datum; Element next; // Inclui item depois do objeto corrente public void insertAfter(Object item) { next = new Element (item, next); if(tail == this) tail = next; }
Métodos insertAfter e insertBefore (2) // Inclui item antes do objeto corrente public void insertBefore(Object item) { Element tmp = new Element(item, this); if(this == head) head = tmp; else { Element prevPtr = head; while(prevPtr != null && prevPtr.next != this) prevPtr = prevPtr.next; prevPtr.next = tmp; } } // ... } // ... }
Definição da Classe Array<T> (1) // pgm04_01.cpp template <class T> class Array { protected: T* data; unsigned int base; unsigned int length; public: Array(); Array(unsigned int, unsigned int = 0); ~Array(); Array(Array const&); Array& operator = (Array const&);
Definição da Classe Array<T> (2) // pgm04_01.cpp (Continuação) T const& operator [] (unsigned int) const; T& operator [] (unsigned int); T const* Data () const; unsigned int Base () const; unsigned int Length () const; void SetBase (unsigned int); void SetLength (unsigned int); };
O Construtor Default da Classe Array<T> // pgm04_02.cpp template <class T> Array<T>::Array () : data (new T [0]), base (0), length (0) {}
Definição do Construtor com tamanho da Classe Array<T> // pgm04_03.cpp template <class T> Array<T>::Array (unsigned int n, unsigned int m) : data (new T [n]), base (m), length (n) {}
Construtor Copy da Classe Array<T> // pgm04_04.cpp template <class T> Array<T>::Array (Array<T> const& array) : data (new T [array.length]), base (array.base), length (array.length) { for(unsigned int i = 0; i < length; ++i) data [i] = array.data [i]; }
Destrutor da Classe Array<T> // pgm04_05.cpp template <class T> Array<T>::~Array () { delete [] data; }
Definição de Funções Accessor da Classe Array <T> // pgm04_06.cpp template <class T> T const* Array<T>::Data () const { return data; } template <class T> unsigned int Array<T>::Base () const { return base; } template <class T> unsigned int Array<T>::Length () const { return length; }
Definição de Função Operador subscrito da Classe Array <T> // pgm04_07.cpp template <class T> T const& Array<T>::operator [] (unsigned int position) const { unsigned int const offset = position - base; if(offset >= length) throw out_of_range ("invalid position"); return data [offset]; } template <class T> T& Array<T>::operator [] (unsigned int position) { unsigned int const offset = position - base; if (offset >= length) throw out_of_range ("invalid position"); return data [offset]; }
Redimensionamento de “arrays” // pgm04_08.cpp template <class T> void Array<T>::SetBase (unsigned int newBase) { base = newBase; } template <class T> void Array<T>::SetLength (unsigned int newLength) { T* const newData = new T [newLength]; unsigned int const min = length < newLength ? length : newLength; for(unsigned int i = 0; i < min; ++i) newData [i] = data [i]; delete [] data; data = newData; length = newLength; }
Definição das Classes LinkedList<T> e ListElement<T> (1) // pgm04_09.cpp template <class T> class LinkedList; template <class T> class ListElement { T datum; ListElement* next; ListElement (T const&, ListElement*); public: T const& Datum () const; ListElement const* Next () const; friend LinkedList<T>; };
Definição das Classes LinkedList<T> e ListElement<T> (2) // pgm04_09.cpp (Continuação) template <class T> class LinkedList { ListElement<T>* head; ListElement<T>* tail; public: LinkedList (); ~LinkedList (); LinkedList (LinkedList const&); LinkedList& operator = (LinkedList const&);
Definição das Classes LinkedList<T> e ListElement<T> (3) // pgm04_09.cpp (Continuação) ListElement<T> const* Head () const; ListElement<T> const* Tail () const; bool IsEmpty () const; T const& First () const; T const& Last () const; void Prepend (T const&); void Append (T const&); void Extract (T const&); void Purge (); void InsertAfter (ListElement<T> const*, T const&); void InsertBefore (ListElement<T> const*, T const&); };
Definição de Funções Membro da Classe ListElement<T> // pgm04_10.cpp template <class T> ListElement<T>::ListElement ( T const& _datum, ListElement<T>* _next) : datum (_datum), next (_next) {} template <class T> T const& ListElement<T>::Datum () const { return datum; } template <class T> ListElement<T> const* ListElement<T>::Next () const { return next; }
Construtor Default da Classe ListElement<T> // pgm04_11.cpp template <class T> LinkedList<T>::LinkedList () : head (0), tail (0) {}
Definição de Funções Membro Destrutor e Purge da Classe ListElement<T> // pgm04_12.cpp template <class T> void LinkedList<T>::Purge () { while (head != 0) { ListElement<T>* const tmp = head; head = head->next; delete tmp; } tail = 0; } template <class T> LinkedList<T>::~LinkedList () { Purge (); }
Definição de Funções Accessor da Classe ListElement<T> // pgm04_13.cpp template <class T> ListElement<T> const* LinkedList<T>::Head () const { return head; } template <class T> ListElement<T> const* LinkedList<T>::Tail () const { return tail; } template <class T> bool LinkedList<T>::IsEmpty () const { return head == 0; }
Definição de Funções First e Last da Classe ListElement<T> // pgm04_14.cpp template <class T> T const& LinkedList<T>::First () const { if(head == 0) throw domain_error ("list is empty"); return head->datum; } template <class T> T const& LinkedList<T>::Last () const { if(tail == 0) throw domain_error ("list is empty"); return tail->datum; }
Definição de Função Prepend da Classe ListElement<T> // pgm04_15.cpp template <class T> void LinkedList<T>::Prepend (T const& item) { ListElement<T>* const tmp = new ListElement<T>(item, head); if(head == 0) tail = tmp; head = tmp; }