Advertisement
Guest User

Untitled

a guest
Oct 23rd, 2018
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.59 KB | None | 0 0
  1. #include <iostream>
  2. #include <stdexcept>
  3. #include <limits>
  4.  
  5. typedef int TChave;
  6.  
  7. class Torneio {
  8.     friend std::ostream& operator << (std::ostream& saida, const Torneio& h);
  9.     public:
  10.         // Construtor sem valores
  11.         Torneio(int tam);
  12.         // Construtor com valores
  13.         Torneio(TChave vet[], int tam);
  14.         ~Torneio();
  15.         void Inserir(TChave chave);
  16.         // Retorna o vencedor do torneio (maior) sem removê-lo.
  17.         TChave Raiz();
  18.         TChave Retirar();
  19.         bool Vazio();
  20.     protected:
  21.         // Atualiza uma posição, com base em seus dois filhos.
  22.         void Atualizar(int i);//Corrige Descendo
  23.         // Atualiza um toneiro subindo a partir da posicao dada. Util para inserção.
  24.         void ArrumarSubindo(int i);//Corrige Subindo
  25.         // Atualiza todos os não intermediários do torneio.
  26.         void ArrumarTudo();//heapify
  27.         // Calcula o espaço necessário e inicializa atributos. Usado nos contrutores.
  28.         void CalcularEspacoDeArmazenamento(int tam);
  29.         // Calcula a posição do filho direito de um noh.
  30.         inline int Direito(int i);
  31.         // Calcula a posição do filho esquerdo de um noh.
  32.         inline int Esquerdo(int i);
  33.         // Calcula a posição do pai de um noh.
  34.         inline int Pai(int i);
  35.  
  36.         TChave* mVetChaves; // espaço de armazenamento
  37.         int mCapacidade; // quantidade máxima de nohs
  38.         int mTamanho; // quantidade de noh utilizados
  39.         int mNroTorneios; // quantidade de nohs intermediários
  40.         TChave mMenor; // valor especial que indica ausência de valor
  41. };
  42.  
  43. using namespace std;
  44.  
  45. Torneio::Torneio(int tam) {
  46.     CalcularEspacoDeArmazenamento(tam);
  47.     mMenor = numeric_limits<TChave>::min();
  48.     mTamanho = mNroTorneios;
  49.     for (int i = 0; i < mCapacidade; ++i)
  50.         mVetChaves[i] = mMenor;
  51. }
  52.  
  53. Torneio::Torneio(TChave vet[], int tam) {
  54.     CalcularEspacoDeArmazenamento(tam);
  55.     mMenor = numeric_limits<TChave>::min();
  56.     mTamanho = mNroTorneios + tam;
  57.     int i = 0;
  58.     // copiar dados do vetor para o torneio
  59.     for (; i < tam; ++i) {
  60.         mVetChaves[mNroTorneios+i] = vet[i];
  61.     }
  62.     // posicoes extras ganham a menor chave para completar nós intermediarios
  63.     i += mNroTorneios;
  64.     while (i < mCapacidade)
  65.         mVetChaves[i++] = mMenor;
  66.     ArrumarTudo();
  67. }
  68.  
  69. Torneio::~Torneio() {
  70.     delete[] mVetChaves;
  71. }
  72.  
  73. void Torneio::Atualizar(int i) {//-------------------------------certo?
  74.     // completar aqui
  75.     int esq = Esquerdo(i);
  76.     int dir = Direito(i);
  77.     int pos_maior = i;//começa supondo que "i" é a posição do maior
  78.     if(esq < mTamanho && mVetChaves[esq] > mVetChaves[i]){//Testa se possui filho esquerdo. Se sim, testa se o filho esquerdo é maior que o valor atual
  79.         pos_maior = esq;//a posição do maior passa a ser a do filho esquerdo
  80.     }
  81.     if(dir < mTamanho && mVetChaves[dir] > mVetChaves[pos_maior]){//Testa se possui filho direito. Se sim, testa se o filho direito é maior que o maior
  82.         pos_maior = dir;//a posição do maior passa a ser a do filho direito
  83.     }
  84.     if(pos_maior != i){//se a posição do maior não é a posição do atual
  85.         mVetChaves[i] = mVetChaves[pos_maior];//o atual recebe o maior
  86.         Atualizar(pos_maior);//chama "Corrige Descendo" na posição do maior
  87.     }
  88. }
  89.  
  90. void Torneio::ArrumarSubindo(int i) {//---------------------------certo?
  91.     // completar aqui
  92.     int p = Pai(i);
  93.     if(p >= 0 && mVetChaves[i] > mVetChaves[p]){//se possui pai, e o valor dele é maior que o do pai
  94.         mVetChaves[p] = mVetChaves[i];//o pai recebe o valor dele
  95.         ArrumarSubindo(p);//chama "Corrige Subindo" na posição do pai
  96.     }
  97. }
  98.  
  99. void Torneio::ArrumarTudo() {//------------------------------------certo?
  100.     // completar aqui
  101.     for (int i = (mTamanho-1)/2; i > 0 ; --i)
  102.     {
  103.         Atualizar(i);
  104.     }
  105. }
  106.  
  107. void Torneio::CalcularEspacoDeArmazenamento(int tam) {
  108.     mNroTorneios = 1;
  109.     while (mNroTorneios < tam)
  110.         mNroTorneios *= 2;
  111.     mCapacidade = 2 * mNroTorneios - 1;
  112.     mNroTorneios -= 1;
  113.     mVetChaves = new TChave[mCapacidade];
  114. }
  115.  
  116. int Torneio::Pai(int i) {
  117.     return (i-1)/2;
  118. }
  119.  
  120. int Torneio::Esquerdo(int i) {
  121.     return 2*i+1;
  122. }
  123.  
  124. int Torneio::Direito(int i) {
  125.     return 2*i+2;
  126. }
  127.  
  128. TChave Torneio::Raiz() {//--------------------------------------errado?
  129.     if (mTamanho == mNroTorneios)
  130.         throw runtime_error("Impossível acessar raiz de torneio vazio.");
  131.     // completar aqui
  132.     return mVetChaves[0];
  133. }
  134.  
  135. TChave Torneio::Retirar() {//----------------------------------------certo?
  136.     if (mTamanho == mNroTorneios)
  137.         throw runtime_error("Impossível retirar de torneio vazio.");
  138.     // completar aqui
  139.     TChave aux = Raiz();//armazena valor da raiz
  140.    
  141.    
  142.    
  143.     //-------------------------------------------------------------------------------------------INCOMPLETO
  144.    
  145.     //~ swap(mVetChaves[0]. mVetChaves[mTamanho-1]);//troca a raiz com o ultimo elemento
  146.     int i = 0;//começando pela raiz
  147.     int esq = Esquerdo(0);//para testar se entra no while
  148.     int dir;
  149.     mVetChaves[0] = mMenor;//"remove" a raiz
  150.     //esse while transforma todos os resquícios do valor da raiz em mMenor
  151.     while(esq < mCapacidade){//enquanto o ultimo testado possui algum filho (se não tiver filho esquerdo, não tem direito)
  152.         esq = Esquerdo(i);
  153.         dir = Direito(i);
  154.         if(aux == mVetChaves[esq]){
  155.             i = esq;
  156.         }
  157.         if(dir < mCapacidade && aux == mVetChaves[dir]){
  158.             i = dir;
  159.         }
  160.         mVetChaves[i] = mMenor;//"remove" o valor que está sendo retirado
  161.     }
  162.     Atualizar(0);//atualiza a raiz
  163.     return aux;//efetua ação desejada com o valor armazenado
  164. }
  165.  
  166. bool Torneio::Vazio() {
  167.     return mTamanho == mNroTorneios;
  168. }
  169.  
  170. void Torneio::Inserir(TChave chave) {//------------------------------certo?
  171.     if (mTamanho == mCapacidade)
  172.         throw runtime_error("Impossível inserir em torneio cheio.");
  173.     // completar aqui
  174.     mVetChaves[mTamanho] = chave;
  175.     ArrumarSubindo(mTamanho);
  176.     mTamanho++;
  177. }
  178.  
  179. std::ostream& operator << (std::ostream& saida, const Torneio& t) {
  180.     // Operador de escrita pode ser util para depurar o torneio.
  181.     saida << '[';
  182.     TChave chave;
  183.     for (int i=0; i < t.mNroTorneios; ++i) {
  184.         chave = t.mVetChaves[i];
  185.         if (chave == t.mMenor)
  186.             saida << "## ";
  187.         else
  188.             saida << chave << ' ';
  189.     }
  190.     saida << '|';
  191.     int pos = t.mNroTorneios;
  192.     int limite = t.mTamanho;
  193.     while (pos < limite) {
  194.         chave = t.mVetChaves[pos];
  195.         if (chave == t.mMenor) {
  196.             saida << " ##";
  197.             ++limite;
  198.         }
  199.         else
  200.             saida << ' ' << chave;
  201.         ++pos;
  202.     }
  203.     saida << ']';
  204.     return saida;
  205. }
  206.  
  207. int main() {
  208.     int capacidade; // nro de valores que quero guardar no torneio
  209.     cin >> capacidade;
  210.     Torneio torneio(capacidade);
  211.     TChave chave;
  212.     char operacao;
  213.     do {
  214.         cin >> operacao;
  215.         switch (operacao) {
  216.             case 'i': // Inserir
  217.                 try {
  218.                     cin >> chave;
  219.                     torneio.Inserir(chave);
  220.                 }
  221.                 catch (runtime_error& e) {
  222.                     cerr << e.what() << endl;
  223.                 }
  224.                 break;
  225.             case 'r': // Remover
  226.                 try {
  227.                     cout << torneio.Retirar() << endl;
  228.                 }
  229.                 catch (runtime_error& e) {
  230.                     cerr << e.what() << endl;
  231.                 }
  232.                 break;
  233.             case 'e': // Escrever
  234.                 cout << torneio << endl;
  235.         }
  236.     } while (operacao != 'f'); // Finalizar execução
  237.     return 0;
  238. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement