2010-08-06 3 views
0

Цель: у меня есть несколько списков доступных элементов, и я хочу иметь возможность хранить все эти элементы в результирующем списке упорядоченным способом.Сохранение элементов в списке в порядке возрастания

Некоторые из идей, которые мне приходят в голову, - это результат: как результат: set (std :: set), но B-дерево необходимо перебалансировать время от времени. b) Сохраните все элементы в списке и отсортируйте список в конце.

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

Вот моя функция, которая выполняет задание по упорядочению результатов. Есть ли эффективный способ сделать то же самое?

void findItemToInsertAt(std::list<int>& dataSet, int itemToInsert, std::list<int>::iterator& location) 
{ 
    std::list<int>::iterator fromBegin = dataSet.begin(); 
    std::list<int>::iterator fromEnd = dataSet.end() ; 
    // Have two pointers namely end and begin 
    if (!dataSet.empty()) 
     --fromEnd; 

    // Set the location to the beginning, so that if the dataset is empty, it can return the appropriate value 
    location = fromBegin; 
    while (fromBegin != dataSet.end() ) 
    { 
     // If the left pointer points to lesser value, move to the next element 
     if (*fromBegin < itemToInsert) 
     { 
      ++fromBegin; 
      // If the end is greater than the item to be inserted then move to the previous element 
      if (*fromEnd > itemToInsert) 
      { 
       --fromEnd; 
      } 
      else 
      { 
       // We move only if the element to be inserted is greater than the end, so that end points to the 
       // right location 
       if (*fromEnd < itemToInsert) 
       { 
        location = ++fromEnd; 
       } 
       else 
       { 
        location = fromEnd; 
       } 
       break; 
      } 
     } 
     else 
     { 
      location = fromBegin; 
      break; 
     } 
    } 

} 

И вот вызывающий функции

void storeListToResults(const std::list<int>& dataset, std::list<int>& resultset) 
{ 

    std::list<int>::const_iterator curloc; 
    std::list<int>::iterator insertAt; 

    // For each item in the data set, find the location to be inserted into 
    // and insert the item. 
    for (curloc = dataset.begin(); curloc != dataset.end() ; ++curloc) 
    { 
     // Find the iterator to be inserted at 
     findItemToInsertAt(resultset,*curloc,insertAt); 
     // If we have reached the end, then the element to be inserted is at the end 
     if (insertAt == resultset.end()) 
     { 
      resultset.push_back(*curloc); 
     } 
     else if (*insertAt != *curloc) // If the elements do not exist already, then insert it. 
     { 
      resultset.insert(insertAt,*curloc); 
     } 
    } 
} 

ответ

2

С первого взгляда ваш код выглядит так, как будто он выполняет линейный поиск списка, чтобы найти место для вставки элемента. Хотя верно, что std::set придется балансировать свое дерево (я думаю, что это Red-Black Tree), чтобы поддерживать эффективность, скорее всего, он будет делать гораздо более эффективно, чем то, что вы предлагаете.

+0

Я пишу два разных решения: один с std :: set, а другой со списком и вставка в список соответствующим образом. Но интересно, есть ли более быстрый способ, чем это вставить в список. – user373215

+0

@nsivakr Не то, что я могу придумать. Связанные списки не могут быть бинарными; массивы (или векторы) могут, но вставка в них неэффективна по другим причинам. Помещение их в ** массив/вектор ** (а не список) и сортировка их после этого примерно так же эффективны, как использование 'std :: set', но если вы действительно обеспокоены потреблением памяти, вы можете выбрать алгоритм сортировки (в частности, heapsort или quicksort), а не древовидную структуру, которая будет занимать дополнительную память для каждого узла. – David

+0

Спасибо, Дэвид. Цените свое подробное объяснение. – user373215

0

Я бы отсортировать indivual списки, а затем использовать STL в list::merge для создания списка результатов. Затем, если список является довольно большим, вы можете заплатить за перевод результата в вектор.

+0

Но использовать список :: merge, элементы должны быть отсортированы первыми. Но в отношении моего примера элементы в исходном списке не отсортированы. – user373215

+0

@nsivakr Да, я заметил, что вы прокомментировали и отредактировали ответ соответственно. –

1

Отвечая на поставленный вопрос:

Есть ли эффективный способ сделать то же самое?

Да. Используйте std::set.

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