2015-10-05 4 views
1

У меня есть то, что я уверен, является основной логической ошибкой, но я не могу ее исправить. Я сортирую GenericSimpleArrayList перед созданием дерева, используя как несортированные (упорядоченные), так и отсортированные (inorder) списки. Когда я сортирую один из списков, он сортирует их обоих? Я не знаю, почему.Изменение переменной также изменяет ранее назначенную переменную

public static <AnyType extends Comparable<? super AnyType>> BinaryNode<AnyType>constructBST (GenericSimpleArrayList<AnyType> postorder){ 


    GenericSimpleArrayList <AnyType> g = postorder; 

    quicksort(postorder, new SortFunctor()); //this is where i sort the list. 

    GenericSimpleArrayList <AnyType> inorder = postorder; 
    return constructTree(inorder, g); 

} 

Может ли кто-нибудь помочь мне исправить это? Почему он сортирует как g, так и postorder, когда я только сортирую postorder? Благодарю.

Редактировать: Добавлено constructTree.

public static <AnyType> BinaryNode<AnyType> constructTree(GenericSimpleArrayList<AnyType> inorder, GenericSimpleArrayList<AnyType> postorder) { 
    int nodes = postorder.size(); 

    AnyType root = postorder.get(nodes-1); 
    BinaryNode<AnyType> left = null; 
    BinaryNode<AnyType> right = null; 

    if (nodes > 1) { 
     int rootPos = 0; 
     for (int loop = 0; loop <= nodes-1; loop++) { 

      if (inorder.get(loop).equals(root)) { 
       rootPos = loop; 
       //System.out.println(loop); 
      } else { 
       //System.out.println("Not found at pos: " + loop); 
      } 
     } 

     if (rootPos != 0) { 
      GenericSimpleArrayList <AnyType> leftInorder = new GenericSimpleArrayList();//(AnyType) new Object[rootPos]; 
      GenericSimpleArrayList <AnyType> leftPostorder = new GenericSimpleArrayList();//(AnyType[]) new Object[rootPos]; 
      for (int loop = 0; loop < rootPos; loop++) { 
       leftInorder.add(inorder.get(loop)); 
       leftPostorder.add(postorder.get(loop)); 
      } 
      left = constructTree(leftInorder, leftPostorder); 
     } 

     if (rootPos < nodes-1){ 
      GenericSimpleArrayList <AnyType> rightInorder = new GenericSimpleArrayList();//(AnyType[]) new Object[nodes - rootPos - 1]; 
      GenericSimpleArrayList <AnyType> rightPostorder = new GenericSimpleArrayList();//(AnyType[]) new Object[rightInorder.length]; 
      for (int loop = 0; loop < nodes-rootPos-1; loop++){ 
       rightInorder.add(inorder.get(rootPos + loop + 1)); 
       rightPostorder.add(postorder.get(rootPos + loop)); 
      } 

      right = constructTree(rightInorder, rightPostorder); 
     } 


    } 

    return new BinaryNode<AnyType>(root, left, right); 

} 
+0

Покажите нам, что 'constructTree' порадует – Juxhin

+0

@Juxhin Добавил его. –

+1

Это то, что мы называем «пройти по ссылке». Когда вы назначаете vairable другому. Тогда обе они имеют одну и ту же «ссылку».Если вы измените внутреннюю ссылку, они будут показывать одинаковые значения ссылки. –

ответ

3

Почему сортировать как г и postorder, когда я только своего рода postorder?

GenericSimpleArrayList <AnyType> g = postorder; 

postorder является ссылка к объекту. Когда вы скопируете ссылку , у вас теперь есть два ссылок. Однако есть еще один объект.

Я не знаю API для пользовательского ArrayList, но я предполагаю, что вы можете сделать

GenericSimpleArrayList<AnyType> g = new GenericSimpleArrayList<AnyType>(postorder); 

или

GenericSimpleArrayList<AnyType> g = new GenericSimpleArrayList<AnyType>(); 
for(AnyType at: postorder) 
    g.add(at); 

Скорее всего ваша сортировка утилита сортирует коллекцию на месте. Это очень часто используется для функций sort, чтобы изменить исходный список.

Если вы хотите сохранить как первоначальный порядок, так и отсортировать список, я предлагаю сначала взять копию списка.

Alanticive должен использовать различные структуры, такие как TreeMap, для записи строки в отсортированном порядке и индекса исходной позиции.

+0

Ну, вот что я пытался сделать, создав 'g'. Как мне сделать копию списка? –

+0

@SarahvdByl Я могу только угадать API, который вы используете, но добавил некоторые примеры. –

2
GenericSimpleArrayList <AnyType> g = postorder; 

GenericSimpleArrayList <AnyType> inorder = postorder; 

В этих двух утверждениях, все три переменные будет иметь в виду то же эталонное удержание postorder изначально. Поскольку вы выполняете ссылочное назначение и обновление в одном состоянии объекта, оно будет отражено во всей ссылочной переменной.

constructTree(inorder, g); 

Итак, когда вы делаете вышеуказанный вызов, вы передаете ту же самую ссылку.

2

В этой строке:

GenericSimpleArrayList <AnyType> g = postorder; 

вы только определить новое имя g для же объекта. Если вы хотите, чтобы g был другим списком, вам нужно его создать заново (это действительно вызывает конструктор ) и копирует в него содержимое postorder.

Смежные вопросы