Queue in normal linked list - c

I want to merge N ordered linked lists into one ordered linked list.
However, I also want the individual ordered linked list to be retained. I am successful in doing so using an array of Node pointers with each array element as a node corresponding to first node of individual lists. However, with array size fixed, I cannot proceed with merging more than array size.
Now my question is, is there a way I can dynamically change array size. If not I am thinking of using Queue instead to hold the first node of individual lists in a queue linked list. Am I going right or wrong? Please give me some tips regarding the problem.

It sounds like you are looking for realloc, assuming you dynamically allocated your array in the first place.

Related

Search in flat array based double link list when element in between head and tail

I have a double link list using arrays and while inserting elements I maintain order, something like this. I am treating new values (nodes) as array indices and store them directly to their location. The link list is quite long. Everything is working as required but is there any algorithm or ideas that can help me to reduce number of iterations when a node falls between head and tail?
That is
if (new_node > head && new_node < tail) {
search from head()
}
So to reduce iteration; I added search from tail() after finding new-node is closer to which head or tail. Then I added a mid-node that is somewhere in mid of head and tail. But still I am still not able to reduce iterations when node needs to be linked. Will knowing range of values help? What else can be done to reduce number of iteration while inserting (due to sorted nature)?
I hope I am able to explain this properly.
Here is a SO answer discussing the difference between array and linked list: insert/delete functions.
tldr; It is a limitation of double linked lists. Even if you wrap it inside an array to do stuff.
Understanding the underlying methods of how a linked list and array works will help identify the impossible issue you are solving. Unless you utilize a different structure, you will typically have the issues you are describing.
I would do the following:
Consider your problem, what do you CARE about
Searching?
Insert/Delete?
Memory size?
Then decide a data structure that best solves your problem
Array
Linked List
Trees
Hash

Array VS single linked list VS double link list

I am learning about arrays, single linked list and double linked list now a days and this question came that
" What is the best option between these three data structures when it comes to fast searching, less memory, easily insertion and updating of things "
As far I know array cannot be the answer because it has fixed size. If we want to insert a new thing. it wouldn't always be possible. Double linked list can do the task but there will be two pointers needed for each node so there will be memory problem, so I think single linked list will fulfill all given requirements. Am I right? Please correct me if I am missing any point. There is also one more question that instead of choosing one of them, can I make combination of one or more data structures given here to meet all the requirements?
"What is the best option between these three data structures when it comes to fast searching, less memory, easily insertion and updating of things".
As far as I can tell Arrays serve the purpose.
Fast search: You could do binary search if array is sorted. You dont get that option in linkedlist
Less memory: Arrays will take least memory (but contiguous memory )
Insertion: Inserting in array is a matter of a[i] = "value". If array size is exceeded then simply export data into a new array. That is exactly how HashMaps / ArrayLists work under covers.
Updating things: Only Arrays provide you with Random access. a[i] ="new value".. updated in O(1) time if you know the index.
Each of those has its own benefits and downsides.
For search speed, I'd say arrays are better suitable due to the quick lookup times.
Since an array is a sequence of same-size elements, retrieving the value at an index is just memoryLocation + index * elementSize. For a linked list, the whole list needs traversing.
Arrays also win in the "less memory" category, since there's no need to store extra pointers.
For insertions, arrays are slow. You'll need to traverse the array, copy contents to a new array, assign the new array, delete the old one...
Insertions go much quicker in linked- or double lists, because it's just a matter of changing one or two pointers.
In the end, it all just depends on the use case. Are you inserting a lot? Then you probably want to consider a non-array structure.
Do you need many quick lookups? Consider those arrays again. Etc..
See also this question.
A linked list is usually the best choice when we don’t know in advance the number of elements we will have to store or the number can change dynamically.
Arrays have slow insertion and deletion times. To insert an element to the front or middle of the array, the first step is to ensure that there is space in the array for the new element, otherwise, the array needs to be RESIZED. This is an expensive operation. The next step is to open space for the new element by shifting every element after the desired index. Likewise, for deletion, shifting is required after removing an element. This implies that insertion time for arrays is Big O of n (O(n)) as n elements must be shifted.
Using static arrays, we can save some extra memory in
comparison to linked lists because we do not need to store pointers to the next node
a doubly-linked list support fast insertion/removal at their ends. This is used in LRU cache, where you need to enter new item to front and remove the oldest item from the end.

Implementing arrays using linked lists (and vice versa)

After learning about arrays and linked lists in class, I'm curious about whether arrays can be used to create linked lists and vice versa.
To create a linked list using an array, could I store the first value of the linked list at index 0 of the array, the pointer to the next node at index 1 of the array, and so on? I guess I'm confused because the "pointer to next" seems redundant, given that we know that the index storing the value of the next node will always be: index of value of current node + 2.
I don't think it's possible to create an array using a linked list, because an array involves continuous memory, but a linked list can have nodes stored in different parts of computer memory. Is there some way to get around this?
Thanks in advance.
The array based linked list is generally defined in a 2-dimentional array, something like :
Benefit: The list will only take up to a specific amount of memory that is initially defined.
Down side: The list can only contain a specific predefined amount of items.
As a single linked list the data structure has to hold a head pointer. This data structure holds a head pointer however in this specific implementation it is a int. The head of the list is the pointer that holds the index to the first node. The first node holds the index to the next node and so on. The last node in the list will hold a next value of -1. This will indicate the end of the list. The fact that indices are taken as elements are added into the structure makes a requirement for a free list head. This free list is incorporated into the same 2-dementional array. Just as the head is an int the free list pointer is an int.
Now the data structure is composted of 3 major elements. The head pointer, the free head pointer and the 2-dimentional array. The list has to be initialized correctly to allow the list to be used. The list should be initialized as below.
Reference is this link
You could store a linked list in an array, but only in the sense that you have an ordered list. As you say, you do not need pointers as you know the order (it's explicit in the array ordering). The main differences for choosing between an array or linked list are:
Arrays are "static" in that items are fixed in their elements. You can't mremove an element and have the array automatically shuffle the following elements down. Of course you can bypass "empty" elements in your iteration it this requires specific logic. With a linked list, if you remove an element, it's gone. With an array, you have to shuffle all subsequent elements down.
As such, linked lists are often used where insertion/ deletion of elements is the most common activity. Arrays are most often used with access is required (as faster as directly accessed [by index]).
Another area where you may see benefits of linked lists over arrays is in sorting (where sorting is required or frequent). The reason for this being that linked list sorts require only pointer manipulation whereas aray sorting requires swapping and shuffling. That said, many sorting algorithms create new arrays anyway (merge-sort is typical) which reduces this overhead (though requires the same memory again for the sorted array).
You can mix your metaphors somewhat if, for example, you enable your linked list to be marked "read-only". That is, you could create an array of pointers to each node in your linked list. that way, you can have indexed access to your linked-list. The array becomes outdated (in the way described above) once elements are added or removed from your linked list (hence the read-only aspect).
So, to answer your specific questions:
1) There's no value in doing this - as per the details above
2) You haven't really provided enough information to answer the question of contiguous memory allocation. It depends on a lot: OS, architecture, compiler implementation. You haven't even mentioned the programming language. In short though, choosing between a linked list and array has little to do with contiguous memory allocation and more to do with usage. For instance, the java LinkedList class and ArrayList class both represent a List implementation but are specialised based on usage patterns. It is expected that LinkedList performs better for "lists" expecting high-modification (although in tests done a few years ago this proved to be negligible - I'm not sure of the state in the latest versions of java).
Also, you wouldn't typically "create an array with a linked list" or vice versa. They're both abstract data structures used in building larger components. They represent a list of something in a wider context (e.g. a department has a list of employees). Each datatype just has usage benefits. Similarly, you might use a set, queue, stack, etc. It depends on your usage needs.
I really hope I haven't confused you further!

Ideas for data structure for implementing graph in c

I want to implement a graph in C. I am confused on how should I store each node. I was first thinking of using a linked list but how can I store the next nodes connected to one node.
Any ideas what data structure should I use and how should I use it?
There are some well known ways to do that.
One is to use a bidimensional array of size [n][n] where n is the number of nodes. And then set graph[a][b]= 1 if there is a link from a to b. This method is in general fast but uses a lot of memory, expecially if there are not so many links and many nodes.
Another way is to make a list (or an array, for the matter) of all nodes and set the content of everyone of them to point to a dynamic array or to a list of nodes it is linked to.
The data structure that is helpful in case your graph is sparse is an adjacency list(linked list of linked lists) that is when you have few connections(edges) between the vertices.
If your graph is dense then use an adjacency matrix(nxn) 2 dimensional array that is the case your vertices have lots of edges between them.

Sorting a linked list and returning to original unsorted order

I have an unsorted linked list. I need to sort it by a certain field then return the linked list to its previous unsorted condition. How can I do this without making a copy of the list?
When you say "return the linked list to its previous unsorted condition", do you mean the list needs to be placed into a random order or to the exact same order that you started with?
In any case, don't forget that a list can be linked into more than one list at a time. If you have two sets of "next"/"previous" pointers, then you can effectively have the same set of items sorted two different ways at the same time.
To do this you will need to either sort and then restore the list or create and sort references to the list.
To sort the list directly Merge Sort is most likely the best thing you could use for the initial sort, but returning them to their original state is tricky unless you either record your moves so you can reverse them or store their original position and resort them using that as the key.
If you would rather sort the references to the list instead you will need to allocate enough space to hold pointers to each node and sort that. If you use a flat array to store the pointers then you could use the standard C qsort to do this.
If this is an assignment and you must implement your own sort then if you don't already know the length of the list you could take advantage of having to traverse it to count its length to also choose a good initial pivot point for quicksort or if you choose not to use quicksort you can let your imagination go wild with all kinds of optimizations.
Taking your points in reverse order, to support returning to original order, you can add an extra int field to each list node. Set those values based on the original order, and when you need to return it to the original order, just sort on that field.
As far as the sorting in general goes, you probably want to use something like a merge-sort or possibly a Quick-sort.
You can make that data structure somewhat like this.
struct Elem {
Elem* _next;
Elem* _nextSorted;
...
}
Then you can use any algo for sorting the list (maybe merge sort)
If you want to keep your linked list untouched, you should add information to store the ordered list of elements.
To do so, you can either create a new linked list where each element points to one element of your original linked list. Or you can add one more field in the element of your list like sorted_next.
In any case, you should use a sequential algorithm like mergesort to sort a linked list.
Here is a C source code of mergesort for linked lists that you could reuse for your project.
I guess most of the answers have already covered the usual techniques one could use. As far as figuring out the solution to the problem goes, a trick is to look at the problem and think if the human mind can do it.
Figuring out the original random sequence from a sorted sequence is theoretically impossible unless you use some other means. This can be done by
a)modifying the linked list structure (as mentioned above, you simply add a pointer for the sorted sequence separately). This would work and maybe technically you are not creating a separate linked list, but it is as good as a new linked list - one made of pointers.
b)the other way is to log each transition of the sorting algo in a stack. This allows you to not be dependent on the sorting algorithm you use. For example when say node 1 is shifted to the 3rd position, you could have something like 1:3 pushed to the stack. The notation, of course, may vary. Once you push all the transitions, you can simply pop the stack to give take it back to the original pattern / any point in between. This is more like
If you're interested in learning more about the design for loggers, I suggest you read about the Command Pattern

Resources