QuickSort

5 respostas
F

Ola!

Bom pessoal, estou com uma dúvida de como usar o método quicksort para uma lista duplamente encadeada.

Preciso de um método que faça mais ou menos isso:

Este, recebe uma Lista Duplamente Encadeada (no caso DLinkedList), e utilizando o método QuickSort, ele ordena esta lista.

Eu já vi o método quicksort, porém ele faz isto apenas com vetores normais.

Eu tinha uma ideia de fazer este método da seguinte forma: Ps.: este método fica dentro da classe DLinkedList
public DLinkedList<E> ordenaDLinkedList(DLinkedList<E> dll){
		int sizedll = (int) dll.size; //número de nós da lista
		DNode<E> current = head; //auxiliar para percorrer a lista duplamente encadeada
		E[] vetor = new E[sizedll]; //esta linha não compila, diz o seguinte "Cannot created generic array of E"
		for(int i = 0;i<vetor.length;i++ , current = current.getNext()){ //este for pegaria cada elemento da lista e adicionaria em uma posição do array
			vetor[i] = current.getElement(); //atribui  ao indice i do vetor
		}
		QuickSort.sort(dll); //chamando o método quicksort ele ordenaria o array
		current = tail; // auxiliar que neste caso fica sendo o último  da lista duplamente encadeada
                DLinkedList<E> ordenada = new DLinkedList<E>(); //lista que ficara ordenada
	        for(int i = vetor.length;i>0;i--,current=current.getPrevious()){  //atribui os valores do vetor ordenado para a nova lista
                ordenada.addFirst(vetor[i]);
                 }
                return ordenada; //retorna a lista
		
		
	}

Porém este método não funciona, devido ao erro da linha 4.

Alguém têm sugestões de como eu póssa fazer?

Grato por enquanto...

Segue as classes da Lista Duplamente Encadeada e o restante que é necessário para ela.

public class DLinkedList<E> {
	protected DNode<E> head; //nodo cabeça da lista
	protected DNode<E> tail; //nodo cauda da lista
	protected long size; //número de nodos da lista

	public DLinkedList() {
		size = 0;
		head = tail = null;
	}

	public boolean isEmpty() {
		return head == null;
	}

	public E getFirst() throws UnderflowException {
		if (isEmpty())
			throw new UnderflowException();
		return head.getElement();
	}

	public E getLast() throws UnderflowException {
		if (isEmpty())
			throw new UnderflowException();
		return tail.getElement();
	}

	public void addFirst(E insertItem) {
		DNode<E> n = new DNode<E>(insertItem);
		if (isEmpty()) {
			head = tail = n;
		} else {
			head.setPrevious(n);
			n.setNext(head);
			head = n;
		}
		size++;
	}

	public void addLast(E insertItem) {
		DNode<E> n = new DNode<E>(insertItem);
		if (isEmpty()) {
			head = tail = n;
		} else {
			tail.setNext(n);
			n.setPrevious(tail);
			tail = n;
		}
		size++;
	}

	public E removeFirst() throws UnderflowException {
		if (isEmpty()) {
			throw new UnderflowException();
		}
		E removedItem = head.getElement();
		if (head == tail) {
			head = tail = null;
		} else {
			head = head.getNext();
			head.setPrevious(null);
		}
		size--;
		return removedItem;
	}

	public E removeLast() throws UnderflowException {
		if (isEmpty()) {
			throw new UnderflowException();
		}
		E removedItem = tail.getElement();
		if (head == tail) {
			head = tail = null;
		} else {
			DNode<E> penultimo = tail.getPrevious();
			tail = penultimo;
			tail.setNext(null);
		}
		size--;
		return removedItem;
	}

	public void print() {
		System.out.println("Exibindo a lista:");
		DNode<E> current = head;
		while (current != null) {
			System.out.println(current.getElement());
			current = current.getNext();
		}
	}

	public DNode<E> find(E key) {
		DNode<E> current = head;
		while (current != null) {
			if (current.getElement().equals(key)) {
				return current;
			}
			current = current.getNext();
		}
		return null;
	}

	public boolean addBefore(E el, E chave) {
		DNode<E> current = find(chave);
		if (current == null) {
			return false;
		} else if (current == head) {
			addFirst(el);
			return true;
		} else {
			DNode<E> n2 = new DNode<E>(el);
			DNode<E> before = current.getPrevious();
			before.setNext(n2);
			n2.setPrevious(before);
			n2.setNext(current);
			current.setPrevious(n2);
			return true;
		}
	}


	public static void main(String args[]) {
		DLinkedList<Integer> list = new DLinkedList<Integer>();
		list.addLast(2);
		list.addLast(4);
		list.addLast(6);
		list.addLast(1);
		list.addLast(8);
		list.addLast(9);
		list.print();
		/*try {
			list.removeFirst();
		} catch (UnderflowException e) {
			e.printStackTrace();
		}
		list.print();*/
		System.out.println(list.find(1));
		System.out.println(list.addBefore(5, 6));
		list.print();
	}

} // end class List
public class DNode<E> {
	private E element;
	private DNode<E> next;
	private DNode<E> previous;

	public DNode(E element) {
		this (element, null, null);
	}
	public DNode(E element, DNode<E> next, DNode<E> previous) {
		super();
		this.element = element;
		this.next = next;
		this.previous = previous;
	}
	public E getElement() {
		return element;
	}
	public void setElement(E element) {
		this.element = element;
	}
	public DNode<E> getNext() {
		return next;
	}
	public void setNext(DNode<E> next) {
		this.next = next;
	}
	public DNode<E> getPrevious() {
		return previous;
	}
	public void setPrevious(DNode<E> previous) {
		this.previous = previous;
	}

	public String toString() {
		return "DNode [element=" + element + "]";
	}
	
	

}
public class UnderflowException extends Exception {
	public String toString() {
		return "UNDERFLOW!";
	}
}

5 Respostas

kdoigor

esse ‘E’ é o tipo ou objeto ? se for tipo vai dar erro mesmo. pq se num substitui por :

Object[] vetor = new Object[sizedll];
F

kdoigor:
esse ‘E’ é o tipo ou objeto ? se for tipo vai dar erro mesmo. pq se num substitui por :

Object[] vetor = new Object[sizedll];

Vou tentar.

E é pra ser o tipo. Tendo em vista que ele recebe também uma lista de “E”.

Depois posto o resultado.

F

Não funcionou, pois o método QuickSort não aceita um Object[].

Tem que ser um E[] mesmo.

Já estou quase desistindo disso. :(

Tem outra sugestão?

Segue o QuickSort, caso queira dar uma olhada...

import java.util.Arrays;
import java.util.Random;
 
public class QuickSort {
    public static final Random RND = new Random();
 
    private static void swap(Object[] array, int i, int j) {
        Object tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
    }
 
    private static <E extends Comparable<? super E>> int partition(E[] array, int begin, int end) {
        int index = begin + RND.nextInt(end - begin + 1);
        E pivot = array[index];
        swap(array, index, end);
        for (int i = index = begin; i < end; ++i) {
            if (array[i].compareTo(pivot) <= 0) {
                swap(array, index++, i);
            }
        }
        swap(array, index, end);
        return (index);
    }
 
    private static <E extends Comparable<? super E>> void qsort(E[] array, int begin, int end) {
        if (end > begin) {
            int index = partition(array, begin, end);
            qsort(array, begin, index - 1);
            qsort(array, index + 1, end);
        }
    }
 
    public static <E extends Comparable<? super E>> void sort(E[] array) {
        qsort(array, 0, array.length - 1);
    }
 
    // Exemplo de uso
    public static void main(String[] args) {
 
        // Ordenando Inteiros
        Integer[] l1 = { 5, 1024, 1, 88, 0, 1024 };
        System.out.println("l1  start:" + Arrays.toString(l1));
        QuickSort.sort(l1);
        System.out.println("l1 sorted:" + Arrays.toString(l1));
 
        // Ordenando Strings
        String[] l2 = { "gamma", "beta", "alpha", "zoolander" };
        System.out.println("l2  start:" + Arrays.toString(l2));
        QuickSort.sort(l2);
        System.out.println("l2 sorted:" + Arrays.toString(l2));
    }
}
JoaoBluSCBR

Cara!!

Esse mundos dos generics é muito doido.

E nessa área dos arrays parece que nada funciona fácil e como um todo.

Fiz umas mudanças no teu código, mas tudo acaba não dando certo por causa dos Bounds (dos limites).

O QuickSort quer uma coisa e você só pode fornecer outra.

Ao invés do teu E[] que obviamente é impossível, tentei um

java.util.List<E> vetor = new java.util.ArrayList <E>();

O meu maior problema aqui é que que ArrayList não aceita Bounds, se aceitasse, bastava colocar o <? super E> e
tudo estaria resolvido.

Bem, daí é claro que mudei o teu for para poder colocar os Elementos no array:

for(int i = 0;i<sizedll;i++ , current = current.getNext()){ 
      vetor.add(current.getElement()); //atribui nó ao indice i do vetor   
}

sem problemas

e daí mudei a classe QuickSort (que estranhamente aceita parâmetros (E[] que não podem ser construídos . kkkkkk)

por métodos parecidos que aceitem ArrayList

public static <E extends Comparable<? super E>> void sort(java.util.ArrayList<E> array) {
        qsort(array, 0, array.size() - 1);
    }
    
    private static <E extends Comparable<? super E>> void qsort(java.util.ArrayList<E> array, int begin, int end) {
        if (end > begin) {
            int index = partition(array, begin, end);
            qsort(array, begin, index - 1);
            qsort(array, index + 1, end);
        }
    }
    
    private static <E extends Comparable<? super E>> int partition(java.util.ArrayList<E> array, int begin, int end) {
        int index = begin + RND.nextInt(end - begin + 1);
        E pivot = array.get(index);
        swap(array, index, end);
        for (int i = index = begin; i < end; ++i) {
            E tmp = array.get(i);
            if (tmp.compareTo(pivot) <= 0) {
                swap(array, index++, i);
            }
        }
        swap(array, index, end);
        return (index);
    }
    
    private static <E extends Comparable<? super E>> void swap(java.util.ArrayList<E> array, int i, int j) {
        E tmp = array.get(i);
        array.remove(i);
        array.add(i, array.get(j));
        array.remove(j);
        array.add(j, tmp);
    }

e então tentei (sem sucesso) achar um jeito de fazer o QuickSort.sort(aceitar meu vetor).

public DLinkedList<E> ordenaDLinkedList(DLinkedList<E> dll){   
        int sizedll = (int) dll.size; //número de nós da lista   
        DNode<E> current = head; //auxiliar para percorrer a lista duplamente encadeada 
        java.util.List<E> vetor = new java.util.ArrayList <E>();
        //E[] vetor = new E[sizedll]; //esta linha não compila, diz o seguinte "Cannot created generic array of E"
        for(int i = 0;i<sizedll;i++ , current = current.getNext()){ //este for pegaria cada elemento da lista e adicionaria em uma posição do array   
            vetor.add(current.getElement()); //atribui  ao indice i do vetor   
        }   
        QuickSort.sort(vetor); //chamando o método quicksort ele ordenaria o array
        
        current = tail; // auxiliar que neste caso fica sendo o último  da lista duplamente encadeada   
        DLinkedList<E> ordenada = new DLinkedList<E>(); //lista que ficara ordenada   
        for (int i = vetor.size(); i > 0; i--, current = current.getPrevious()) {  //atribui os valores do vetor ordenado para a nova lista 
            E temp = vetor.get(i);
            ordenada.addFirst(temp);
        }
        return ordenada; //retorna a lista                         
    }

Mas não deu, parece que tudo se resume aos limites na chamada do sort.

To mandando só por que de alguma maneira isso possa te dar alguma idéia.

F

Malditos generics…

Abandonei isso, já quebrei a cabeça d+.

Desisto.

Criado 23 de junho de 2011
Ultima resposta 24 de jun. de 2011
Respostas 5
Participantes 3