Поиск дубликатов в отсортированном, связанном списке - PullRequest
0 голосов
/ 24 октября 2010

Я создал отсортированный связанный список, и теперь я пытаюсь выяснить, как удалить дубликаты.Я хотел добавить код, который сделал бы это в методе Add, который я создал, но я не могу понять это.Я чувствую, что это должно быть относительно легко, но сейчас я немного умираю.

В моем методе добавления я проверяю индекс, чтобы увидеть, где должен быть добавлен элемент.«Index» - это переменная типа int, но я хотел проверить, был ли «item», сопоставимый, тем же самым элементом, сохраненным перед ним.Я хотел использовать метод CompareTo, но я получил бы несоответствие типов.У кого-нибудь есть идея лучшего способа сделать это?

Вот код для моего метода добавления:

 package sortedListReferenceBased;

     public class SortedListReferenceBasedIterativeNoDuplicates
     implements SortedListInterface {

     // reference to linked list of items
     private Node head; 
     private int numItems; // number of items in list

     public SortedListReferenceBasedIterativeNoDuplicates() {
     numItems = 0;
     head = null;
     }  // end default constructor

      public boolean sortedIsEmpty() {
        return numItems == 0;
      //TODO
     }  // end sortedIsEmpty

     public int sortedSize() {
  return numItems;
      //TODO
     }  // end sortedSize

      private Node find(int index) {
     // --------------------------------------------------
     // Locates a specified node in a linked list.
     // Precondition: index is the number of the desired
    // node. Assumes that 1 <= index <= numItems+1
    // Postcondition: Returns a reference to the desired 
   // node.
  // --------------------------------------------------
  Node curr = head;
  for (int skip = 1; skip < index; skip++) {
   curr = curr.getNext();
} // end for
return curr;
  } // end find


  public Comparable sortedGet(int index) 
                throws ListIndexOutOfBoundsException {
      if (index >= 1 && index <= numItems){
          Node curr = find(index);
          Object dataItem = curr.getItem();
          return (Comparable) dataItem;
      }
      else {
          throw new ListIndexOutOfBoundsException("List index out of bounds on   get.");
  }
    //TODO
  } // end sortedGet()


  public void sortedAdd(Comparable item) throws ListException{ 
   int index = locateIndex(item); //to find location where item should be added
   if( index >=1 && index <= numItems+1){
       //if adding an item to the very beginning of list
       if (index == 1){
           Node newNode = new Node(item,head);
           head = newNode;
       }
       if (item.compareTo(something something?)== 0){ //if item is a duplicate of previous item do nothing
           System.out.println("No duplicates!");
       }

       //advances 
       else {
           Node prev = find(index-1); //finds out where previous node is
           Node newNode = new Node(item, prev.getNext()); //creates Node with item you wish to add
           prev.setNext(newNode); //links new node with previous node
          }
          numItems++;  
      }//end main if statement
      else {
           throw new ListIndexOutOfBoundsException("List index out of bounds on add.");
      }
    //TODO
  }  // end sortedAdd()


  public void sortedRemove(Comparable item) throws ListException {
      int index = locateIndex(item);
      if (index >= 1 && index <= numItems){ //if the index is greater than 1 (meaning list not empty) and
                                              //index doesn't exceed list size do the following:
      //if index is value of one then delete first node in this special way
      if (index == 1) {
          head = head.getNext();
      }
    //if there is only one item in the list then set head to nothing so index out of bounds error won't occur
      if (numItems == 1){
          head = null;
      }
      else { //if none of these things occur go ahead and delete item, allocating Nodes accordingly
          Node prev = find(index-1);
          Node curr = prev.getNext();
          prev.setNext(curr.getNext());
      }
      numItems--;//must account for one less item
      }
  if (!sortedIsEmpty()){
      System.out.println("Item does not exist!");
  }
  else { //if index doesn't meet if statement requirements 
      throw new ListIndexOutOfBoundsException("List index out of bounds on remove.");
  }

//TODO
 } // end sortedRemove


 public void sortedRemoveAll() {
   // setting head to null causes list to be
   // unreachable and thus marked for garbage 
   // collection
   head = null;
   numItems = 0;
 } // end sortedRemoveAll


 //Returns the position where item belongs or exists in a sorted list;
 //item and the list are unchanged.
 public int locateIndex(Comparable item) {
     Node curr = head;
     for (int i = 1; i <= sortedSize(); i++){
         if (item.compareTo(curr.getItem())<= 0){
            return i;
        }//end if

         else {
             curr = curr.getNext();
         }//end else
     }//end for
     return sortedSize()+1; 
    //TODO
 } //end locateIndex()




} // end ListReferenceBased

Я прошу прощения за странное форматирование.Это сейчас довольно грубо.Я также прошу прощения, если этот вопрос действительно очевиден!Ха-ха

Ответы [ 3 ]

4 голосов
/ 24 октября 2010

Предварительные замечания:

  1. Я не понимаю, почему вы, похоже, пытаетесь реализовать связанные списки в Java ... учитывая, что в форме уже есть очень хорошая реализацияиз java.util.LinkedList.

  2. Набор без дубликатов - это набор ...

  3. Набор на основе связанных списков будетнеоптимальным.Например, вставка равна O(N) по сравнению с O(logN) для реализации на основе дерева и O(1) для реализации на основе хеш-таблицы (при условии, что она имеет соответствующий размер).java.util.TreeSet и java.util.HashSet являются примерами соответственно.

Сказав это, и предположив, что вы действительно хотите понимание / подсказку ...

Если у вас естьпредварительно отсортированный связанный список, затем способ удалить дубликаты состоит в том, чтобы пройти по узлам, сравнивая node.value с node.next.value.Если значения равны, то вы нашли дубликат, и вы можете удалить его, изменив node.next на node.next.next.Ваш код также должен справляться с различными «крайними случаями»;например, списки с 0 или 1 элементом и т. д.

0 голосов
/ 24 октября 2010

Попробуйте

if (locateIndex(item) != (sortedSize() + 1)) { //locateIndex returns sortedSize() + 1 if it didn't find the item, so we check that

    System.out.println("No duplicates!");
}

Все дело в использовании кода, который вы уже написали.

0 голосов
/ 24 октября 2010

Вы настроены на использование связанного списка?Использование встроенного TreeSet может показаться более естественным для этого.

...