Lista Duplamente Encadeada (com Nó Cabeça) Perfeita! Para fins didáticos

0 respostas
R

Pode copiar e analisar à vontade.
Apenas peço que, se você fizer algum melhoramento, republique para que possamos aprender mais.

Para quem está enfrentando aquela famosa tarefa de Estrutura de Dados na Faculdade de SI.
:)

Tinha um erro, mas, acabei de corrigir.

Classe principal:
package listas;

import javax.swing.JOptionPane;

/**
 * * @author robson.alcantara
 */
public class ListaDE_NoCabeca {

	static final String[] menuGeral = { "Métodos de Inserção",
			"Métodos de Remoção", "Métodos de Busca", "Métodos de Listagem",
			"Sair" };
	static final String[] menuInicialInserir = { "Inserir no Início",
			"Inserir no Final", "Inserir Antes", "Inserir Após",
			"Inserir ordenado", "Sair" };
	static final String[] menuInicialRemover = { "Remover do Início",
			"Remover do Final", "Remover Antes", "Remover Após",
			"Remover um valor", "Sair" };
	static final String[] menuInicialBuscas = { "Recuperar o primeiro",
			"Recuperar o último", "Localizar um elemento", "Sair" };
	static final String[] menuInicialManutencao = { "Ordenar a Lista",
			"Limpar a Lista", "Listar", "Sair" };

	public static void main(String[] args) {

		ClasseListaDE<String> auxiliar, novo, enc, kbeca = new ClasseListaDE<>();
		String entrada, depois;
		int opcao;
		boolean pronto;
		do {
			opcao = (JOptionPane
					.showOptionDialog(null, "Escolha sua opção",
							"Painel de opções", JOptionPane.DEFAULT_OPTION,
							JOptionPane.QUESTION_MESSAGE, null, menuGeral,
							menuGeral[0]));
			switch (opcao) {
			case 0:
				int opcao1 = (JOptionPane.showOptionDialog(null,
						"Escolha sua opção", "Painel de opções",
						JOptionPane.DEFAULT_OPTION,
						JOptionPane.QUESTION_MESSAGE, null, menuInicialInserir,
						menuInicialInserir[0]));
				switch (opcao1) {
				case 0:
					do {
						entrada = (JOptionPane
								.showInputDialog(
										null,
										"Informe o elemento a ser inserido no início da lista.\nPode ser inteiro, string, palavra, o que você quiser!",
										"Inserção de elementos",
										JOptionPane.QUESTION_MESSAGE));
						auxiliar = kbeca;
						pronto = false;
						ClasseListaDE busca = localizar(entrada, auxiliar,
								"inserir");
						if (busca == null) {
							pronto = true;
							if (kbeca.getProximo() == null
									|| kbeca.getAnterior() == null) {
								novo = new ClasseListaDE<>(entrada);
								kbeca.setProximo(novo);
								kbeca.setAnterior(novo);
								novo.setProximo(kbeca);
								novo.setAnterior(kbeca);
								ClasseListaDE.aumentaTamanho();
							} else {
								novo = new ClasseListaDE<>(entrada, kbeca,
										kbeca.getProximo());
								kbeca.getProximo().setAnterior(novo);
								kbeca.setProximo(novo);
								ClasseListaDE.aumentaTamanho();
							}
						}
					} while (pronto == false);
					break;
				case 1:
					do {
						entrada = (JOptionPane
								.showInputDialog(
										null,
										"Informe o elemento a ser inserido no fim da lista.\nPode ser inteiro, string, palavra, o que você quiser!"));
						auxiliar = kbeca;
						pronto = false;
						ClasseListaDE busca = localizar(entrada, auxiliar,
								"inserir");
						if (busca == null) {
							pronto = true;
							if (kbeca == null) {
								novo = new ClasseListaDE<>(entrada);
								kbeca.setProximo(novo);
								kbeca.setAnterior(novo);
								novo.setProximo(kbeca);
								novo.setAnterior(kbeca);
								ClasseListaDE.aumentaTamanho();
							} else {
								novo = new ClasseListaDE<>(entrada,
										kbeca.getAnterior(), kbeca);
								kbeca.getAnterior().setProximo(novo);
								kbeca.setAnterior(novo);
								ClasseListaDE.aumentaTamanho();
							}
						}
					} while (pronto == false);
					break;
				case 2:
					do {
						entrada = (JOptionPane
								.showInputDialog(
										null,
										"Informe o elemento a ser inserido.\nPode ser inteiro, string, palavra, o que você quiser!"));
						auxiliar = kbeca;
						pronto = false;
						ClasseListaDE busca = localizar(entrada, auxiliar,
								"inserir");
						if (busca == null) {
							pronto = true;
						}
					} while (pronto == false);
					depois = (JOptionPane.showInputDialog(null,
							"Ele será inserido antes de qual elemento?"));
					auxiliar = kbeca;
					enc = localizar(depois, auxiliar, "");
					if (enc != null) {
						novo = new ClasseListaDE<>(entrada, enc.getAnterior(),
								enc);
						enc.getAnterior().setProximo(novo);
						enc.setAnterior(novo);
					} else {
						JOptionPane.showMessageDialog(null,
								"Elemento não foi inserido.", "Lamento, mané!",
								JOptionPane.ERROR_MESSAGE);
					}
					break;
				case 3:
					do {
						entrada = (JOptionPane
								.showInputDialog(
										null,
										"Informe o elemento a ser inserido.\nPode ser inteiro, string, palavra, o que você quiser!"));
						auxiliar = kbeca;
						pronto = false;
						ClasseListaDE busca = localizar(entrada, auxiliar,
								"inserir");
						if (busca == null) {
							pronto = true;
						}
					} while (pronto == false);
					depois = (JOptionPane.showInputDialog(null,
							"Ele será inserido após qual elemento?"));
					auxiliar = kbeca;
					enc = localizar(depois, auxiliar, "");
					if (enc != null) {
						novo = new ClasseListaDE<>(entrada, enc,
								enc.getProximo());
						enc.getProximo().setAnterior(novo);
						enc.setProximo(novo);
					} else {
						JOptionPane.showMessageDialog(null,
								"Elemento não foi inserido.", "Lamento, mané!",
								JOptionPane.ERROR_MESSAGE);
					}
					break;
				case 4:
					do {
						entrada = (JOptionPane
								.showInputDialog(
										null,
										"Informe o elemento a ser inserido na lista.\nPode ser inteiro, string, palavra, o que você quiser!\n"
												+ "O programa buscará o primeiro elemento que seja\n"
												+ "menor que o que você irá inserir e o colocará depois dele."));
						auxiliar = kbeca;
						pronto = false;
						ClasseListaDE busca = localizar(entrada, auxiliar,
								"inserir");
						if (busca == null) {
							pronto = true;
							if (kbeca.getProximo() == null
									|| kbeca.getAnterior() == null) {
								novo = new ClasseListaDE<>(entrada);
								kbeca.setProximo(novo);
								kbeca.setAnterior(novo);
								novo.setProximo(kbeca);
								novo.setAnterior(kbeca);
								ClasseListaDE.aumentaTamanho();
							} else {
								auxiliar = kbeca.getProximo();
								boolean encontrado = false;
								do {
									if (auxiliar.getObjeto().compareTo(entrada) > 0) {
										encontrado = true;
										break;
									} else {
										auxiliar = auxiliar.getProximo();
									}
								} while (auxiliar.getObjeto() != null);
								if (encontrado == true) {
									novo = new ClasseListaDE<>(entrada,
											auxiliar.getAnterior(), auxiliar);
									auxiliar.getAnterior().setProximo(novo);
									auxiliar.setAnterior(novo);
									ClasseListaDE.aumentaTamanho();
								} else {
									novo = new ClasseListaDE<>(entrada,
											kbeca.getAnterior(), kbeca);
									kbeca.getAnterior().setProximo(novo);
									kbeca.setAnterior(novo);
									ClasseListaDE.aumentaTamanho();
								}
							}
						}
					} while (pronto == false);
					break;
				case 5:
				}
				break;
			case 1:
				int opcao2 = (JOptionPane.showOptionDialog(null,
						"Escolha sua opção", "Painel de opções",
						JOptionPane.DEFAULT_OPTION,
						JOptionPane.QUESTION_MESSAGE, null, menuInicialRemover,
						menuInicialRemover[0]));
				switch (opcao2) {
				case 0:
					if (kbeca.getTamanho() == 1) {
						limparLista(kbeca);
ClasseListaDE.diminuiTamanho();
					} else {
						if (kbeca != null) {
							kbeca.getProximo().getProximo().setAnterior(kbeca);
							kbeca.setProximo(kbeca.getProximo().getProximo());
							ClasseListaDE.diminuiTamanho();
						}
					}
					break;
				case 1:
					if (kbeca.getTamanho() == 1) {
						limparLista(kbeca);
ClasseListaDE.diminuiTamanho();
					} else {
						if (kbeca != null) {
							kbeca.getAnterior().getAnterior().setProximo(kbeca);
							kbeca.setAnterior(kbeca.getAnterior().getAnterior());
							ClasseListaDE.diminuiTamanho();
						}
					}
					break;
				case 2:
					entrada = (JOptionPane
							.showInputDialog(null,
									"Informe o elemento cujo antecessor será removido."));
					auxiliar = kbeca;
					if (auxiliar.getTamanho() == 1) {
						limparLista(kbeca);
ClasseListaDE.diminuiTamanho();
					} else {
						enc = localizar(entrada, auxiliar, "buscar");
						if (enc != null) {
							if (enc.getAnterior().getObjeto() == null) {
							} else {
								if (enc.getAnterior().getAnterior().getObjeto() == null) {
									kbeca.setProximo(enc);
									enc.setAnterior(kbeca);
									ClasseListaDE.diminuiTamanho();
								} else {
									enc.getAnterior().getAnterior()
											.setProximo(enc);
									enc.setAnterior(enc.getAnterior()
											.getAnterior());
									ClasseListaDE.diminuiTamanho();
								}
							}
						}
					}
					break;
				case 3:
					entrada = (JOptionPane.showInputDialog(null,
							"Informe o elemento cujo sucessor será removido."));
					auxiliar = kbeca;
					if (auxiliar.getTamanho() == 1) {
						limparLista(kbeca);
ClasseListaDE.diminuiTamanho();
					} else {
						enc = localizar(entrada, auxiliar, "buscar");

						if (enc != null) {
							if (enc.getProximo().getObjeto() == null) {
							} else {
								if (enc.getProximo().getProximo().getObjeto() == null) {
									kbeca.setAnterior(enc);
									enc.setProximo(kbeca);
									ClasseListaDE.diminuiTamanho();
								} else {
									enc.getProximo().getProximo()
											.setAnterior(enc);
									enc.setProximo(enc.getProximo()
											.getProximo());
									ClasseListaDE.diminuiTamanho();
								}
							}
						}
					}
					break;
				case 4:
					entrada = (JOptionPane.showInputDialog(null,
							"Informe o elemento que será removido."));
					auxiliar = kbeca;
					if (auxiliar.getTamanho() == 1) {
						limparLista(kbeca);
ClasseListaDE.diminuiTamanho();
					} else {
						enc = localizar(entrada, auxiliar, "buscar");

						if (enc != null) {
							enc.getProximo().setAnterior(enc.getAnterior());
							enc.getAnterior().setProximo(enc.getProximo());
							ClasseListaDE.diminuiTamanho();
						}
					}
					break;
				case 5:
				}
				break;
			case 2:
				int opcao3 = (JOptionPane.showOptionDialog(null,
						"Escolha sua opção", "Painel de opções",
						JOptionPane.DEFAULT_OPTION,
						JOptionPane.QUESTION_MESSAGE, null, menuInicialBuscas,
						menuInicialBuscas[0]));
				switch (opcao3) {
				case 0:
					if (kbeca.getProximo() != null
							|| kbeca.getAnterior() != null) {
						JOptionPane.showMessageDialog(null,
								"O primeiro elemento da lista é: "
										+ kbeca.getProximo().getObjeto());
					}
					break;
				case 1:
					if (kbeca.getProximo() != null
							|| kbeca.getAnterior() != null) {
						JOptionPane.showMessageDialog(null,
								"O último elemento da lista é: "
										+ kbeca.getAnterior().getObjeto());
					}
					break;
				case 2:
					entrada = (JOptionPane.showInputDialog(null,
							"Informe o elemento a ser procurado"));
					auxiliar = kbeca;
					localizar(entrada, auxiliar, "buscar");
					break;
				case 3:
				}
				break;
			case 3:
				int opcao4 = (JOptionPane.showOptionDialog(null,
						"Escolha sua opção", "Painel de opções",
						JOptionPane.DEFAULT_OPTION,
						JOptionPane.QUESTION_MESSAGE, null,
						menuInicialManutencao, menuInicialManutencao[0]));
				switch (opcao4) {
				case 0:
					if (kbeca.getProximo() != null
							|| kbeca.getAnterior() != null) {
						JOptionPane
								.showMessageDialog(
										null,
										"Esta opção ordenará todos os elementos que você já inseriu.\n"
												+ "Fará igual no mapa de caracteres. Números na frente e alfabeto depois.\n"
												+ "As palavras inseridas também serão colocadas em ordem.",
										"Ordenação da Lista",
										JOptionPane.INFORMATION_MESSAGE);
						auxiliar = kbeca.getProximo();
						String pivo;
						int vezes, cont = 0;
						do {
							vezes = 0;
							do {
								if (auxiliar.getObjeto().compareTo(
										auxiliar.getProximo().getObjeto()) > 0) {
									pivo = auxiliar.getObjeto();
									auxiliar.setObjeto(auxiliar.getProximo()
											.getObjeto());
									auxiliar.getProximo().setObjeto(pivo);
									vezes++;
									cont++;
								}
								auxiliar = auxiliar.getProximo();
							} while (auxiliar.getProximo().getObjeto() != null);
							do {
								if (auxiliar.getObjeto().compareTo(
										auxiliar.getAnterior().getObjeto()) < 0) {
									pivo = auxiliar.getObjeto();
									auxiliar.setObjeto(auxiliar.getAnterior()
											.getObjeto());
									auxiliar.getAnterior().setObjeto(pivo);
									vezes++;
									cont++;
								}
								auxiliar = auxiliar.getAnterior();
							} while (auxiliar.getAnterior().getObjeto() != null);
						} while (vezes != 0);
						JOptionPane.showMessageDialog(null, "Houve " + cont
								+ " permutações.");
					}
					break;
				case 1:
					limparLista(kbeca);
					break;
				case 2:
					listar(kbeca);
					break;
				case 3:
				}
				break;
			}
		} while (opcao != 4);
	}

	/**
	 * Método que localiza determinado elemento em uma lista. A busca é
	 * recursiva e o elemento poderá, ou não, ser encontrado.
	 * 
	 * @param entrada
	 * @param lista
	 * @return
	 */
	private static ClasseListaDE localizar(String entrada,
			ClasseListaDE<String> lista, String quemPediu) {
		ClasseListaDE auxiliar = lista.getProximo();
		if (auxiliar != null) {
			boolean encontrado = false;
			do {
				if (auxiliar.getObjeto().equals(entrada)) {
					encontrado = true;
					break;
				} else {
					auxiliar = auxiliar.getProximo();
				}
			} while (auxiliar.getObjeto() != null);
			if (encontrado == true) {
				if (auxiliar.getProximo().getObjeto() == null) {
					switch (quemPediu) {
					case "inserir":
						JOptionPane.showMessageDialog(null,
								"O elemento indicado já existe. Informe outro",
								"Mensagem de Erro!!!",
								JOptionPane.ERROR_MESSAGE);
						break;
					case "buscar":
						JOptionPane.showMessageDialog(null,
								"O elemento foi encontrado. Ele é o último: "
										+ auxiliar.getObjeto(),
								"Busca finalizada",
								JOptionPane.INFORMATION_MESSAGE);
						break;
					}
					return auxiliar;
				} else {
					if (auxiliar.getAnterior().getObjeto() == null) {
						switch (quemPediu) {
						case "inserir":
							JOptionPane
									.showMessageDialog(
											null,
											"O elemento indicado já existe. Informe outro",
											"Mensagem de Erro!!!",
											JOptionPane.ERROR_MESSAGE);
							break;
						case "buscar":
							JOptionPane.showMessageDialog(null,
									"O elemento foi encontrado. Ele é o primeiro: "
											+ auxiliar.getObjeto(),
									"Busca finalizada",
									JOptionPane.INFORMATION_MESSAGE);
							break;
						}
						return auxiliar;
					} else {
						switch (quemPediu) {
						case "inserir":
							JOptionPane
									.showMessageDialog(
											null,
											"O elemento indicado já existe. Tá no meio do bolo!",
											"Mensagem de Erro!!!",
											JOptionPane.ERROR_MESSAGE);
							break;
						case "buscar":
							JOptionPane
									.showMessageDialog(null,
											"O elemento foi encontrado. Ele está entre o "
													+ auxiliar.getAnterior()
															.getObjeto()
													+ " e o "
													+ auxiliar.getProximo()
															.getObjeto(),
											"Busca finalizada",
											JOptionPane.INFORMATION_MESSAGE);
							break;
						}
						return auxiliar;
					}
				}
			} else {
				switch (quemPediu) {
				case "inserir":
					break;
				case "buscar":
					JOptionPane
							.showMessageDialog(null,
									"O elemento não foi encontrado.",
									"Busca finalizada",
									JOptionPane.INFORMATION_MESSAGE);
					break;
				}
				return null;
			}
		} else {
			switch (quemPediu) {
			case "inserir":
				break;
			case "buscar":
				JOptionPane.showMessageDialog(null,
						"O elemento não foi encontrado.", "Busca finalizada",
						JOptionPane.INFORMATION_MESSAGE);
				break;
			}
			return null;
		}
	}

	/**
	 * Este método limpa a lista. O parâmetro passado é o nó cabeça.
	 * 
	 * @param kbeca
	 */
	private static void limparLista(ClasseListaDE<String> kbeca) {
		ClasseListaDE novo;
		novo = new ClasseListaDE<>("", kbeca, kbeca);
		kbeca.setProximo(novo);
		kbeca.setAnterior(novo);
		ClasseListaDE.setTamanho(0);
	}

	/**
	 * Este método faz a listagem em caixa de mensagem.
	 * 
	 * @param kbeca
	 */
	private static StringBuilder listar(ClasseListaDE<String> kbeca) {
		StringBuilder saida = new StringBuilder();
		if (kbeca.getProximo() != null) {
			ClasseListaDE auxiliar;
			auxiliar = kbeca;
			while (auxiliar.getProximo().getObjeto() != null) {
				saida.append(auxiliar.getProximo().getObjeto().toString())
						.append(" ");
				auxiliar = auxiliar.getProximo();
			}
			JOptionPane.showMessageDialog(null, saida.toString());
		}
		return saida;
	}
}
Classe do tipo (com três construtores diferentes para usar da forma que convir:
package Listas;

/**
 * @author robson.alcantara
 */
public class Classe_ListaDencadeada<E> {

    private static int tamanho;
    private E objeto;
    private Classe_ListaDencadeada<E> proximo;
    private Classe_ListaDencadeada<E> anterior;

    /**
     * Este construtor cria um nó que recebe como valor o objeto passado como
     * parâmetro. Ele, automaticamente, apontará para anterior nulo e para
     * próximo nulo.
     *
     * @param objeto
     */
    public Classe_ListaDencadeada(E objeto) {
        this.objeto = objeto;
        this.anterior = null;
        this.proximo = null;
    }

    public Classe_ListaDencadeada() {
        this.objeto = null;
        this.anterior = null;
        this.proximo = null;
    }

    /**
     * Este construtor cria um nó e o aloca entre os nós passados como
     * parâmetros. Ele automaticamente apontará para os nós.
     *
     * @param objeto
     * @param anterior
     * @param proximo
     */
    public Classe_ListaDencadeada(E objeto, Classe_ListaDencadeada<E> anterior, Classe_ListaDencadeada<E> proximo) {
        this.objeto = objeto;
        this.proximo = proximo;
        this.anterior = anterior;
    }

    public static int getTamanho() {
        return tamanho;
    }

    public static void setTamanho(int tamanho) {
        Classe_ListaDencadeada.tamanho = tamanho;
    }

    public static void aumentaTamanho() {
        tamanho++;
    }

    public static void diminuiTamanho() {
        tamanho--;
    }

    public E getObjeto() {
        return objeto;
    }

    public void setObjeto(E objeto) {
        this.objeto = objeto;
    }

    /**
     * Método que retorna o próximo nó da lista.
     *
     * @return
     */
    public Classe_ListaDencadeada<E> getProximo() {
        return proximo;
    }

    /**
     * Método que determina o nó para quem o nó atual apontará. Ou seja, define
     * o próximo.
     *
     * @param proximo
     */
    public void setProximo(Classe_ListaDencadeada<E> proximo) {
        this.proximo = proximo;
    }

    /**
     * Método que retorna o nó anterior da lista.
     *
     * @return
     */
    public Classe_ListaDencadeada<E> getAnterior() {
        return anterior;
    }

    public void setAnterior(Classe_ListaDencadeada<E> anterior) {
        this.anterior = anterior;
    }
}
Criado 9 de novembro de 2012
Respostas 0
Participantes 1