What is the purpose of sorting a linked list? - list

I am wondering what is the purpose of sorting a linked list. Because if you need to find an element in an unsorted linked list and a sorted linked list, you have to do O(n).
Please forgive if my question is stupid

The purpose of sorting isn't always to search in logarithmic time. There are lots of other applications of sorted data obviously.
Suppose, you have to de-duplicate(remove the duplicate elements) from a large linked list and you don't have enough space to load the list items into hashtable as the list is very big. In this case, you can sort the list and remove consecutive elements if they are same and thus de-duplicate the list.
If you want to insert an element into it's appropriate position in a sorted container, sorted linked list is very handy which will guarantee linear time and constant space complexity. But for array, you need to use a temporary array and move all the elements afterwards one by one. Infact LRU cache is a doubly-linked list under the hood and keep sorted based on the recent hit on items. Newly used item and old item which is recently being accessed again, are inserted in front to keep the already sorted list sorted. If an array like structure would be used here, LRU cache can't offer of constant complexity
This is just some classic applications. You can find a lot of other applications.

Let us think a linked list is used to implement a priority queue. We can add elements of different priorities at random, but we want to process the elements of the queue according to priority, it would be useful to maintain a sorted linked list so that the top priority items appear at the beginning, and removing them from the queue is an easy operation. This not exactly sorting the list, but as and when an item is inserted, it would be placed in it's correct position based on the priority. This is similar to insertion sort of an array.

Related

Good sources to understand Containers

I'm studying containers and their different performances.
When , for a vector, I read something like
"inserting elements other than the back is slow"
but for a list:
"fast insert/delete at any point"
My questions are:
How a vector is different from a list in such a way that the two sentences above are true?
How its a vector built differently from a list?
Is because they store their elements in different memory parts?
I was searching some sources to better understand these concepts.
All examples will be linked to C++ language as I believe it is perfectly described there
Vectors
Vectors are the same as dynamic arrays with the ability to resize themselves
automatically when an element is inserted or deleted, with their
storage being handled automatically by the container. Vector elements
are placed in contiguous storage so that they can be accessed and
traversed using iterators. In vectors, data is inserted at the end.
Inserting at the end takes differential time, as sometimes there may
be a need of extending the array. Removing the last element takes only
constant time because no resizing happens. Inserting and erasing at
the beginning or in the middle is linear in time.
Vector is the dynamic array, but which can manage the memory allocated to itself. This means that you can create arrays whose length is set at runtime without using the new and delete operators (explicitly specifying the allocation and deallocation of memory).
Lists
Lists are sequence containers that allow non-contiguous memory
allocation. As compared to vector, the list has slow traversal, but once a
position has been found, insertion and deletion are quick. Normally,
when we say a List, we talk about a doubly linked list. For implementing
a singly linked list, we use a forward list.
There are 2 types of lists:
Double linked list where each element has an address of [next]
and [previous], to access first or last element you could you a specific function (e.g. in C++ front() or back() on the list - listName.front() will return you the 1st(0) element in your list), head.previous point to NULL and the tail.next point to NULL;
Single linked list where each element only has the link(knows)
about the [next] element, and the last element in this list points
to NULL.
Now let's get back to your question:
how a vector is different from a list in such a way
that the two sentences above are true? How is a vector built
differently from a list? Is it because they store their elements in
different memory parts? I was searching some sources to better
understand these concepts.
As I have mentioned there are 2 types of lists (single linked and double liked), they are good when you are going to have:
many insertion/deletion everywhere except the end of a list;
You could use vector in case you are planning to:
frequently access insert/delete elements at the end of a list;
access elements at the random position (as you could use [N] to access the element at any point, where the N is the index/position of an element.
Whereas in the List you would need to use iterators to access the element at the position/index N.
So vector is a dynamic array and they tend to perform faster when you are accessing it (since there is no additional wrapper over it, and you directly access a point in memory by the pointer).
The list is a sequence container (so this one has a wrapper over some base language functionality) that sacrifices some point in favor of additional simplicity of insertion and deletion by providing a user with some useful methods to work with its elements.
And to resolve you question, we could conclude the following:
Vector
inserting elements other than the back is slow
List
fast insert/delete at any point
This can be judged by the structure they have what they are.
Insertion is swift in List because it is a linked list and this
means what? Exactly, This means that the only change is to be taken
to achieve it is to change the pointer of the [previous ] and the
[next] item, and we are done!
Whereas in Vector it would take waaaay more time to insert an element anywhere other than at the end. This could be proven by the array concept. If you have an array of one million elements and you want to replace/delete/insert the element at the very beginning of the array it would need to change the position of each element that is coming after the altered element.
List vs Vector Image:
images were taken from this sources:
singly linked list
double linked list
double linked list 2nd image
vector
Also, try having a look here vector-vs-list-in-stl. Their comparison is well described there. + look through the-c-standard-template-library-stl, by going to the "Containers" section and checking the description and its methods.

Topological sorting of DAG in C++; data structure for storing the sorted list?

I implemented a topological sorting of a directed acyclic graph in C++ that outputs a topological sorted list.
I see some implementations where the sorted list is stored in std::stack, and some in std::vector. I am not sure which or some other data structure would be the most appropriate for my case. Essentially, I just need to loop through this sorted list, and extract the elements stored from top to bottom. The list is not modified during the extraction process.
Using a std::vector seems to be a waste, time-complexity-wise, since I'll be reallocating the vector every time a new element is added to the list. This list can get pretty massive.
It seems that I cannot loop through std::stack according to How to traverse stack in C++?.
Is there another option that would be more appropriate for what I want to do?

Heap Sort a Linked List

I'm trying to create a sort function in c++ that sorts a linked list object using Heap sort but I'm not sure how to get started. Can anyone give me any idea on how to do it ? I'm not even sure how I would sort a Linked List
Heapsort works by building a heap out of the data. A heap is only efficient to build when you have random-access to each element.
The first step is going to be creating an array of pointers to your list objects, so you can perform the usual heap sort on the array.
The last step will be converting your array of pointers back into a linked list.
A better sorting method for a linked list is an insertion sort -- not least because you can perform the sort as part of your linked list implementation's insert() function.
I have to agree with sarnolds answer. It is extremely inefficient to heap set a linked list for a number of reasons but the first being that they should have been sorted upon initial placement. That said, if I were going to try I would create an ArrayList<T> links the load all the links into it. Then you can grab that in heaps and sort them. Once you're finished just reload your linked list starting with thr head.
HeapSort is good for 2 reasons -
1- It is an In place algorithm.
2- Time complexity of O(nlogn)
The O(nlogn) is because of random access nature of array, But if you use linked list then you would not get random access advantage of array.
Hence the time complexity will become O(n^2). That is not good for sorting.
I will recommend you to use merge sort algo for linked list.

sorting an STL List after all pushbacks or just use Multimap?

We were using a multimap<int,string> to store several hundred thousand items (>300K), when we realized we needed to add more data for analysis. So we created a class that held a few items and the necessary overridden operators for stl and used a multimap<ourStruct,String>. This worked fine and didn't take much longer than before (with some test data), when we then realized an stl <list> would do just fine, as long as we sorted it after we finished adding all the items. To our surprise, we found that adding all items to multimap still easily beats the total time to add all items to list, and then sort.
This doesn't make sense to us EE types, since by our thinking every insert to multimap would have to traverse the list then tack it on to the end, where as with list we would just add on to the end (via push back), then hopefully the sort wouldn't take as long.
One more factoid: we intially did the comparison test with out sorting the list and were thrilled to see significant speed ups in speed using list. Then we added the sort, and were a bit stunned...
Any of the CS gurus out there care to weigh in?
std::multimap uses a balanced tree1, so it does not traverse the entire list when you insert an item. The number of items traversed for an insert is approximately the base 2 logarithm of the number of items in the collection.
Based on what you've said, your best bet would probably be to put your data in a vector, and then sort.
1 Technically, the standard doesn't directly require a balanced tree, but it requires ability to traverse in sorted order, and logarithmic complexity for insertions and deletions in the worst case, and I'm not aware of many other data structures that can meet that requirement.
Removed ref to hash .. Balanced tree is why only an n2 traverse is required.

diff between ADT list and linked list

What is the ( real | significiant ) difference (s) between ADT list implementation and linked list implementation
with respect to queue ?
Moreover,
Can you suggest any website with visual example of these type of lists ?
It is REALLY hard to understand this question, but in an attempt to ask what the actual question is, I believe to have figured it out. So my assumption is, that the question is: "What is the difference between std::list and std::queue. #fatai: Please correct me, when I am wrong.
The std::list is a doubly-linked list. Each element of the list "knows" the next and previous element. And the list "knows" it's beginning and end. Look here: http://www.cplusplus.com/reference/stl/list/
The std::queue is a list, with special functionality. This functionality allows you to easily insert elements at the front, and remove elements from the back. Have a look here:
http://www.cplusplus.com/reference/stl/queue/
If you want to have minimal functionality, I'd use queue. The queue is optimized for its purpose. It also prevents you from doing things accidentally wrong (such as remove an element from the middle).
I hope that answers your (confusing) question. ;-)
Erasing and inserting into middle of the list by using iterator has O(n) complexity because in the background it has to shift all the other elements. (uses special model of vector ADT, but you cant even access to list element with index mechanism).
In linked-lists erasing and inserting to list has O(1) complexity. It doesn't needs to shift the elements for the operations. Even searching an element in linked lists has O(n) complexity like the list ADT.