Ajuda com MergeSort

5 respostas
A

Ae pessoal.....na boa?

to eu dnv aki atucando com esse problema hehehe...

é o seguinte

tenho que implementar o mergeSort... implementei mas ele tah dando IndexOfBoundsException.... eu vi onde é, mas me parece que o código esta certo... não sei o que mudar pra solucionar isso...

abaixo esta o código do merge q implementei,...tem um System.out no meio para imprimir o "esq e o dir" que pelo que vi é ali que esta dando erro....

obrigado pela ajuda pessoal

abraços

import java.util.*;

public class MergeSort {
	
	public void mergeSort(ArrayList<Integer> vetor, int esq, int dir){
		System.out.println("Esq: "+esq+" Dir: "+dir);
		if(esq==dir) return;
		if(dir-1==1){
			if(vetor.get(esq)>vetor.get(dir)){
				int aux = vetor.get(esq);
				vetor.set(esq, vetor.get(dir));
				vetor.set(dir, aux);				
			}
			return;
		}
		int meio = (dir+esq)/2;
		mergeSort(vetor, esq, meio);
		mergeSort(vetor, meio+1, dir);
		uniao(vetor, esq, meio, dir);
	}
	
	public void uniao(ArrayList<Integer> vetor, int i, int m, int f){
		
		ArrayList<Integer> vetor1 = new ArrayList<Integer>(m-i+1);
		ArrayList<Integer> vetor2 = new ArrayList<Integer>(f-m+1);
		int aux, indVetor1 = 0, indVetor2 = 0;
		
		for(aux = i; aux < m + 1; aux++){
			vetor1.set(indVetor1, vetor.get(aux));
			indVetor1++;
		}
		for(aux = m; aux < f; aux++){
			vetor2.set(indVetor2, vetor.get(aux));
			indVetor2++;
		}
		
		int i1 = 0, i2 = 0;
		
		while(i1 < indVetor1 && i2 < indVetor2){
			if(vetor1.get(i1) < vetor2.get(i2)){
				vetor.set(i, vetor1.get(i1));
				i1++;
			}
			else{
				vetor.set(i, vetor2.get(i2));
				i2++;
			}
			i++;
		}		
		while(i1 < indVetor1){
			vetor.set(i, vetor1.get(i1));
			i1++;
			i++;
		}
		while(i2 < indVetor2){
			vetor.set(i, vetor2.get(i2));
			i2++;
			i++;
		}
		
	}	
}

5 Respostas

L

Não entrando nos méritos da implementação que eu não sei se esta certo ok?

mas quando você faz

for(aux = i; aux < m + 1; aux++){
         vetor1.set(indVetor1, vetor.get(aux));
         indVetor1++;
      }
      for(aux = m; aux < f; aux++){
         vetor2.set(indVetor2, vetor.get(aux));
         indVetor2++;
      }

O set o arrayList vai pre-supor que a lista ja esteja populada naquela posicao, ou seja contenha um elemento naquela posicao, mas ali sua lista esta vazia ( não tem elemento ainda)

Olha o código do set do arrayList:

public E set(int index, E element) {
	RangeCheck(index);

	E oldValue = elementData[index];
	elementData[index] = element;
	return oldValue;
    }

e o código de RangeCheck

private void RangeCheck(int index) {
	if (index >= size)
	    throw new IndexOutOfBoundsException(
		"Index: "+index+", Size: "+size);
    }

como seu index eh 0 (sua posicao) e é igual a size (que é o número de elementos que a lista contém), ele da o erro.

Tenta usar ao invés de set

vetor1.set(indVetor1, vetor.get(aux));
         vetor2.set(indVetor2, vetor.get(aux));

o método add

vetor1.add(indVetor1, vetor.get(aux));
         vetor2.add(indVetor2, vetor.get(aux));
Eu não olhei seu código para saber se vai ordenar algo, mas caso vc ainda tenha duvidas quanto ao algoritmo, tem uma implementação em java aqui

<aside class="onebox wikipedia">
  <header class="source">
      <a href="https://pt.wikipedia.org/wiki/Merge_sort" target="_blank">pt.wikipedia.org</a>
  </header>
  <article class="onebox-body">
    <div class="aspect-image" style="--aspect-ratio:280/237;"><img src="//upload.wikimedia.org/wikipedia/commons/c/c5/Merge_sort_animation2.gif" class="thumbnail"></div>

<h3><a href="https://pt.wikipedia.org/wiki/Merge_sort" target="_blank">Merge sort</a></h3>


  
    
      
        Θ
        (
        n
        )
      
    
    {\displaystyle \Theta (n)}
  
 variante natural
 O merge sort, ou ordenação por mistura, é um exemplo de algoritmo de ordenação por comparação do tipo dividir-para-conquistar.
 Sua ideia básica consiste em Dividir (o problema em vários subproblemas e resolver esses subproblemas através da recursividade) e Conquistar (após todos os subproblemas terem sido resolvidos ocorre a conquista que é a união das resoluções dos subproble...

ps1: quando vc for chamar seu método pela primeira vez, o index inicial eh 0 e o index final eh o tamanho da lista -1, pois são esses os valores que ele vai usar de base para pegar os index do array, se vc passar tamanho da lista, ele vai pensar que uma lista de tamanho 4 tem o quinto que esta na posição 4, o certo eh passar de 0-3 (elemento 0, elem 1, elem 2 e elem 3).

ps2: eu falo para vc rever depois o algoritmo e que não sei se esta certo porque essa parte me pareceu meio que gambiarra no código

if &#40;dir - 1 == 1&#41;
      &#123;
         if &#40;vetor.get&#40;esq&#41; &gt; vetor.get&#40;dir&#41;&#41;
         &#123;
            int aux = vetor.get&#40;esq&#41;;
            vetor.set&#40;esq, vetor.get&#40;dir&#41;&#41;;
            vetor.set&#40;dir, aux&#41;;
         &#125;
         return;
      &#125;

Mas… vai saber neh, faz tempoooo que estudei algoritmos de ordenação :wink:

boa sorte

A

luBS velho,…vlw mesmo, nem notei essa parada…era ai mesmo o erro…

vo t falar uma coisa, pra mim o código inteiro parece meio gambiarra, mas fazer o que… foi PROFA. da minha facul q passou isso… v c pode…

pior q agora funcionou,…capenga mas funcionou… ordena metade dos numeros soh e desaparece com outros… vou continuar procurando erros de implementação do algoritmo dela uhauhauhauha

vlw pela mão velho

abração

A

outra coisa pessoal,…

todos os algoritmos do Merge q catei na net, nenhum é com ArrayList, e transformei uns 4 jah, mas todos dão o erro de indexofbounds… e tenho QUASE certeza q to fazendo certo…pq primeiro estou adicionando os numeros em um novo vetor e dps eu modifico,…mas continua dando o mesmo erro :’(

vlws

L

hehehe relaxa, olha, alterei aquele merge do wikipedia… acho que funcionou… testa ai…

ps: se funcionar quero uma cerva depois :wink:

package lubs;

import java.util.ArrayList;
import java.util.List;

public class Mer
&#123;

   public static void main&#40;String&#91;&#93; args&#41;
   &#123;
      List&lt;Integer&gt; x = new ArrayList&lt;Integer&gt;&#40;&#41;;
      x.add&#40;3&#41;;
      x.add&#40;5&#41;;
      x.add&#40;7&#41;;
      x.add&#40;2&#41;;
      x.add&#40;9&#41;;
      x.add&#40;1&#41;;
      x.add&#40;4&#41;;

      mergeSort&#40;x, 0, x.size&#40;&#41; - 1&#41;;
      for &#40;Integer s &#58; x&#41;
      &#123;
         System.out.println&#40;s&#41;;
      &#125;
   &#125;

   public static void mergeSort&#40;List&lt;Integer&gt; x, int esq, int dir&#41;
   &#123;
      if &#40;esq &lt; dir&#41;
      &#123;
         int medio = &#40;esq + dir&#41; / 2;
         mergeSort&#40;x, esq, medio&#41;;
         mergeSort&#40;x, medio + 1, dir&#41;;
         mezclar&#40;x, esq, medio + 1, dir&#41;;
      &#125;
   &#125;

   public static void mezclar&#40;List&lt;Integer&gt; x, int posEsq, int posDir, int posFin&#41;
   &#123;
      int&#91;&#93; xAux2 = new int&#91;x.size&#40;&#41;&#93;;
      int finIzq = posDir - 1;
      int posAux = posEsq;
      int numElementos = posFin - posEsq + 1;
      // Busca principal
      while &#40;posEsq &lt;= finIzq &amp;&amp; posDir &lt;= posFin&#41;
         if &#40;x.get&#40;posEsq&#41; &lt; x.get&#40;posDir&#41;&#41;
         &#123;
            xAux2&#91;posAux++&#93; = x.get&#40;posEsq++&#41;;
         &#125;
         else
         &#123;
            xAux2&#91;posAux++&#93; = x.get&#40;posDir++&#41;;
         &#125;
      // Copia primeira metade
      while &#40;posEsq &lt;= finIzq&#41;
      &#123;
         xAux2&#91;posAux++&#93; = x.get&#40;posEsq++&#41;;
      &#125;
      // Copia segunda metade
      while &#40;posDir &lt;= posFin&#41;
      &#123;
         xAux2&#91;posAux++&#93; = x.get&#40;posDir++&#41;;
      &#125;
      // Copia veteor temporário no principal
      for &#40;int i = 0; i &lt; numElementos; i++, posFin--&#41;
      &#123;
         x.set&#40;posFin, xAux2&#91;posFin&#93;&#41;;
      &#125;
   &#125;

&#125;

ps2: isso aqui eh xunxera, vc não vai precisar provavelmente de uma array sempre do mesmo tamanho que a ArrayList, mas eu não to com tempo de ficar vendo certinho que tamanho criar o array… ai isso acho eh algo que de vc melhorar caso use esse codigo.

int&#91;&#93; xAux2 = new int&#91;x.size&#40;&#41;&#93;;
A

Velho, t devo uma cerva mesmo…até 2 uhauhauhauha

kra brigadão mesmo pela mão…eu soh testei ali e funcionou direitinho…
dps eu vou ver o que eu tava fazendo de errado hehehe

vlws mesmo pela ajuda

abração

Criado 24 de outubro de 2006
Ultima resposta 24 de out. de 2006
Respostas 5
Participantes 2
Alura Sistemas operacionais: entenda seu conceito e suas funções Descubra o que são sistemas operacionais, suas funções e tipos. Aprenda tudo de forma clara e objetiva. Não perca tempo!
Casa do Codigo Orientacao a Objetos: Aprenda seus conceitos e suas... Por Thiago Leite e Carvalho — Casa do Codigo