I have a C structure that contains contact info for a person, such as name, phone number, etc. The "contact" structures are contained within a linked list. I need to insert nodes in a way such that the linked list is sorted into alphabetical (ascending) order.
Is there a built-in sorting function in C that I can call? Or do I have to write my own sorting function? If there is a built-in function, could I get an example of how I'd call it on a structure within a linked list?
There's no standard sorting method for a "list". The closest is qsort (which can indeed sort user-defined objects) but it only works on continuous ranges (arrays and the like).
You'll probably have to implement your own sorting procedure or use and array instead of a list.
Here is an example of code that performs an insertion sorted linked list. This isn't a cut and paste for you, but will show you what to expect in that type of insertion:
http://www.c.happycodings.com/Sorting_Searching/code8.html
Focus on the "insert()" call. I did not compile this code to test it, but I read it over and it looks correct to me. It shows how to search a list and pointer adjustments. You should be able to solve your problem from this code.
Related
In a program I'm working on for a final project, I've got to implement search functions for ordered and unordered linked lists. In the assignment, it's made clear that there's an expectation for a search function for each type.
I've worked with linked lists in previous classes, I understand the difference between ordered and unordered, but I hit a wall in trying to figure out what the difference would be in searching them. In my mind, both should iterate through the list until the key value is found and then return it. How should these differ?
In case of order linked list time complexity can be reduced while performing search operation. You can implement skip list for this purpose. But if your linked list need to be a singly linked list strictly then there is no difference other than mentioned by #kaylum in his comment
When trying to insert into an ordered list, consider the two scenarios.
Using an array of pointers. Binary search to find where the
insertion point is then:
Use memmove() to move the bytes to make room for the new address
Move the addresses using iteration to make room for the new address
Use a linked list and linear search
Which would perform better? My guess is that in optimized code, the two options for 1. would perform about the same but how would 1. and 2. compare. It seems to be that they would both be O(n). Is there an easier way to do this? Would it be possible to set up a binary search on any type of linked list?
Any other suggestions would be greatly welcome.
I have gone through following link
http://analgorithmaday.blogspot.in/2011/01/insertion-sort-using-linked-list.html
They are using another array (*arr) to do the sorting.
Is it possible, to do the insertion sort, on the linked list without using any other array or linked list?
Your reading of their algorithm is not correct -- the passed-in array is simply the source of the data and is not used for the insertion sort.
Insertion sort is a good algorithm for small vectors and short linked lists too. A good method for linked lists can be to insertion sort small chunks (10 - 50 elements) and then recursively merge sort the linked lists until one sorted list remains.
Insertion Sort is an in-place algorithm, which means that it does not need any auxiliary memory space to order an array or whatever.
If you use Insertion Sort on an array, you have to exchange the elements inside it while executing the algorithm, but if you have a linked list, you can exchange the pointers instead of the elements inside the list itself.
I have to organize a struct or an array of some people's first name, last name, and age then organize them in alphabetical order writing them from an input file to an output file using the string library.
This is partically for a Lab that I have tomorrow afternoon in which my TA said we might be asked to complete the task I stated above. I'm trying to get opinions or suggestions from individuals whom are much more experienced in C than myself so I'll be more prepared than I was last lab where I didn't so hot.
I'm stuck, any suggestions on where I should start?
Well, reading and writing the input and output should be a no brainer (you open the file, read/write and then close it when you're done with it).
The trick is to get those pesky strings sorted.
The way I look at strnig sorting is an array of arrays sorting. The first array-level is an iteration over all the structs while the second is an iteration over all the letters of a name (note that some names are longer then others)
1. First you sort the first column - all the first letters
2. Then all the sub-columns - within each first letter group you sort the second letter
3. Repeat 1&2 until you run out of letters to sort.
The sorting of an array of letters is the same as sorting an array of byte (AKA chars), and if you're working with an algorithm like bubble sort, working on a sub array is seamless.
Hope this idea helps
You can use strcmp from string.h library, which compares two strings and returns the result.
You should read every string from input file and keep in memory. You will probably use a list for that, for example linked list. While adding you can organize them in alphabetical order. Here is an example:
Take the an element in list.
Compare it with new string.
Where should it be placed? if it should be before the current element, place it before the current element. If it should be after current element, do the same for next element.
This is a simple algorithm for your problem.
The tricky part is to implement the comparation of two strings. the strcmp function only tells you whether the strings are identical. You can loop through the char array to do it.
Once this is done, the remaining sorting is simple.
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