I'm using Queue Abstract Data Type which is based on Singly Linked List. I want to sort the data which Queue keeps in 3 ways: First with merge sort, second with quick sort, third with heap sort. So is there anyone can help about this?
Ordinarily a queue is sorted by insertion order - items are sorted by the order in which they were inserted into the queue. It appears you want to break that essential quality of a queue.
I'm only going to cover merge sorting with this answer. Hopefully others will cover the other algorithms or you can derive them yourself.
A single linked list can be treated as a list of lists simply by knowing when one list ends and another begins. For a merge sort you need to start with sorted lists - if each list has a length of 1, it is sorted simply because no other order is possible. Merging two linked lists into one is easy - you take the smallest item from each of two lists and link it into a new list, until both lists are exhausted. So for the first pass, you break the list into sublists of length 1, and combine them into sublists of length 2. The second pass you merge the sublists of length 2 into sublists of length 4. Each pass doubles the size of the sorted sublists. You're finished when the size of the sorted sublist is greater or equal to the size of your entire list.
Related
In a problem inputs are several lists of numbers,
Ex-
(1,5,4,3), (2,7,3,1,5), (1,9,1,7,3,7,2), (3,5,4,2,3).
where each list may appear twice.
In the final output distinct lists should be printed, in which elements in each list should be sorted in non increasing order, as well as lists should be sorted like that.
Is it possible to implement this whole thing with map in c++ ?
Output for the above example should be
9,7,7,3,2,1,1
7,5,3,2,1
5,4,3,3,2
5,4,3,1
Simply,set of unique lists where within each lists numbers again sorted in non increasing order.
std::set will definitely help you. You will get a unique sorted list as the resultant set if you insert your list into a std::set<int>
Edit:
std::set<std::multiset<int, std::greater<int>> myList;
Inner set going to sort in non increasing order and keeping duplicates elements, and outer set going to keep only unique list of inner list.
I have the following problem and would like to see if somebody could tell me if I'm on the right track with my approach:
I want to do a "rolling window" kind of computation on two linked lists and for that I need them to be sorted by magnitude. If I just have one linked list, writing the corresponding mergesort is not the problem. However, now I'm wondering how I should go about the fact that I have two linked lists where I want to have the corresponding elements from list 1 and list 2 move together as I sort by the magnitude of list 1. If this is not entirely clear, this is what I mean:
In list 1, I want to do a sort by magnitude, so basically just rearrange the pointers. Whenever I move element "n" in one list, however, I also need to move the corresponding element "n" in the other list to the same position as the element from the other one.
Would my approach of using mergesort for this be the right way to go or does anyone know a better approach? I am having a hard time imagining how I would go about reordering the second list while mergesorting the first one since the second list is not necessarily going to be sorted by magnitude anymore and I need the individual elements to correspond to each other.
Thanks!
Marc
Just create a list of pairs of corresponding elements, and then sort the list by the first element of the pair.
Let's say i have 2 std::lists, each contains various numbers of elements. Every element (on each list) has UNIQUE int id value. On every iteration i need to remove elements from first list that don't appear on the second one and add elements from the second list that don't belong to the first one. E.g (numbers=unique ids):
iteration: first[3,2,1], second[4,3,5,7,6], result: [3,4,5,6,7]
iteration: first[3,4,5,6,7], second[4,10,9], result: [4,10,9]
etc...
I cannot simply swap second one to first one (let us recognise it's impossible, too long to read). My question is:
What is the best search algorithm I can perform to update first list? I mean, should i use nested loops on both sorted lists and compare ids? Remove continuously elements from first lacking in the second but also delete repeating ones in first. Then merge it? Or maybe make one of them unordered_map(hash table)?
Edited:
I wanted to simplify problem but in fact, it's unclear now. I cannot change containers, there are 2 unsorted lists contain 2 different structures each. The only link between 2 types of structures is an id parameter. In every iteration i have to check if first list looks just like the second one. Ids are unique, no repeats allowed. So if ids match lists will be identical. I can't swap them because first list has e.g 30 values and the second one 10 (it's incompleted). There are another special functions to prepare structure for first list that consist of many different structures (including structure from list 2). These functions are launched only if there are ids from the second list that don't appear in the first list. I mustn't manipulate first list but i'm able to modify the second one.
I tried in this ways. In every iteration:
1. Create a std::unordered_set with hashed ids from second list. Then compare it to first list and remove outdated ids from first list. Remove also repeating ids from unordered_set. We'll end up with the set of new structures from list 2. We can run another functions and then add suitable ones to first list.
2. Sort list2 by ids. Then do binary search.
3. Linear search. 2 loops. Id that appears in first list and doesn't in the second one is removed from first list. Id that appears in both lists is removed from the second list. And finally we got ids that appear in second list and don't in the second one. We can process them and merge with list 1.
The most important thing: There will be a lot of comparisons but lists are the same most of the time!
The most efficient way to do this is probably going to be to simply assign the second list to the first:
first = second;
which will copy all the elements in second and put them in first.
If for some reason you need to keep the elements in place, you can sort each list and use the set_difference algorithm to find all the elements in one list that are not in the other list.
I have two given integer List:
alist : TList<Integer>; // eg. 1,2,3,4,5,6,7,8,9
blist : TList<Integer>; // e.g 1,2,3,4,5
Resultlist : TList<Integer>;
IgnoreList : TList<Integer>; // e,g, 1,2,3
What is a effective way to find the common elements on both lists, excluding elements from the ignore list. As I have to run this procedure over many items I need a effective and fast way of implementation for this problem.
Resultlist should be 4,5
I agree with Dmitry. Converting lists to hash sets and looking up in them would be fast irrespective of whether the lists are sorted.
Have a look at Delphi's TDictionary. TDictionary intersection is one quick way of finding common elements. Otherwise,
1) Create a TDictionary for blacklisted elements.
2) Create a TDictionary and insert elements from alist that are not present in blacklist-dictionary. This operation is fast because TDictionary are optimized for lookup.
3) finally, iterate over elements of blist and only output elements preent in alist-dictionary.
What you want for this is the list comparison algorithm. You take two sorted lists (make sure to sort them first if they aren't already) and two index variables, set both indices to 0, and start comparing values, advancing one index or the other if they aren't equal, or both indices of they are. By customizing the behavior of the algorithm when unequal or equal values are found, there are a lot of things you can do with this. What you want for here is, when equal values are found, insert the value into the output list.
I have been trying out to figure out a way to find intersection of N lists in c++.
The method that is clicking me is sort, merge and iterate.
Is there any other way too ?
Please share your suggestions.
Sort each list using std::sort (or if it's an std::list, use std::list::sort) then compute the intersections using std::set_intersection iteratively (apply it to the first two lists, then to the result and the third list, then to the result and the fourth list, and so on).
A solution using unsorted lists would be messier. Presumably, you'd have an 'answer' list, initially empty. Then you'd identify two lists, and step through one; for each element, you'd scan the other list to see if it is present in that list - storing the element in the answer if there's a match. Then you'd create a new empty answer list, and step through another of the original lists, searching through the previous answer list for a matching element, and adding to the new answer list. Repeat ad nauseam.
This is not particularly efficient.
For the 'sort, merge, and iterate' solution, working with pairs of lists, is also not as effective as simultaneously iterating through the N sorted lists in parallel, only selecting elements that appear in all lists as part of the answer.