I have to make a type of linked-list that stores ints in order from smallest to largest. If you have or know how to make a sorting function for linked-lists please show if off here and / or teach me how to code it in C++.
-
It's usually a bad idea to try to sort linked lists. – alestanis Nov 15 '12 at 23:11
-
1why it's bad idea to sort linked lists? – billz Nov 15 '12 at 23:12
-
Because there is no efficient random access to linked list nodes. – Cogwheel Nov 15 '12 at 23:13
-
@Cogwheel-MatthewOrlando Well, I have to as the requirments for this project were make a type that is a linked-list of non-repeating ints in sorted order from smallest to largest. – IrfanM Nov 15 '12 at 23:16
-
@Cogwheel-MatthewOrlando, there are sorting algorithms that don't require random access. One choice, albeit a bad one, is Bubble sort. I know of a better one but as this smells of Homework I won't give it away. – Mark Ransom Nov 15 '12 at 23:16
-
@MarkRansom key word from alestanis: "usually" and key word from me: "efficient" ;) -- If you have a linked list, you can sort it, but it's usually a better idea to use a different data structure if you need sorting support. – Cogwheel Nov 15 '12 at 23:18
-
@Cogwheel-MatthewOrlando, in fact std::partition (essential part in quicksort) doesn't require RandomAccessIterators – hate-engine Nov 15 '12 at 23:19
-
1@IrfanM: so you actually have to construct the list, rather than sort an existing list? In that case, just insert into the appropriate position. I agree this sounds like homework, though... – Cogwheel Nov 15 '12 at 23:21
-
2Very similar question was asked recently. I'm going to post the same link again, http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html This is the best way, will get top marks, but bubble sort is better than nothing. – john Nov 15 '12 at 23:25
-
It's less that sorting a linked list is a bad idea, than it is that using a linked list *at all* is usually a bad idea (a [previous question](http://stackoverflow.com/questions/2429217/under-what-circumstances-are-linked-lists-useful) covers many of the exceptions to that rule -- if you know of others, please add them there). – Jerry Coffin Nov 15 '12 at 23:28
-
@Cogwheel-MatthewOrlando No, I have to sort an existing list. – IrfanM Nov 15 '12 at 23:44
-
1It's *not* a bad idea to use or sort linked lists. The only bad idea is to make proclamations like "it's usually a bad idea..." The bottom line is that what data structure you use depends on the problem question, the expected usage patterns and the cost of the available alternatives. Additionally, considering the fact that this smells like homework, I think linked lists and sorting are great ideas: people need to learn and understand fundamental data structures and algorithms and their limitations and the best way to do that is to be hands-on. Now, I'll step off the soap box. – Nik Bougalis Nov 16 '12 at 04:47
3 Answers
I often sort linked lists via an index-pointer-list. To build one requires a memory allocation equivalent to the number of nodes (N) * the size of a node pointer. The concept is simple enough.
Note: this algorithm is in C, as I was not entirely sure if the OP meant to class this as a C++ question (who the hell uses linked lists in C++ with the standard containers at your disposal??)
- Determine the number (N) of nodes in the list
- Allocate a pointer-array for N node pointers.
- Load the pointer array with every node pointer in the list. I.e. walk the list, and put a pointer in each slot of the pointer-array, incrementing as you go.
- Send this node pointer array to your sorting algorithm (I like the runtime library
qsort()
since it is standard-equipped). - After sorting, walk the entire pointer array (less one), setting each node's "next" pointer to point to the one that follows. The last one sets its "next" pointer to NULL.
- Set the head pointer to be the first pointer [0] in the pointer array.
- Free the memory of the pointer array
Your linked list is sorted.
Assuming your node is something like this:
struct node
{
..data fields..
int keyField; // << determines sort order
struct node *next;
};
Determine the number of nodes in your list. I'm assuming you have a proc that can do this, which is trivial:
size_t list_count(struct node* head)
{
size_t count = 0;
while (head)
{
++count;
head = head->next;
}
return count;
}
Allocate a pointer array the size of the list, where nItems is the list node count greater than 1 (no sense in bothering with a list of length zero or one):
struct node **ptrs = malloc(sizeof(*ptrs)*nItems);
Populate the pointer array with all the items in the list:
struct node *ptr = head;
size_t i=0;
for (;i<nItems;++i,ptr = ptr->next)
ptrs[i] = ptr;
Now send this to qsort()
with an appropriate comparision function. An example comparison function that sorts based on the keyField
in our structure is below:
int compare_node_ptrs(const void* left, const void* right)
{
struct node *l = *(struct node**)left;
struct node *r = *(struct node**)right;
return l->keyField - r->keyField;
}
Invoking qsort() looks like this:
qsort(ptrs, nItems, sizeof(*ptrs), compare_node_ptrs);
Now walk the entire list. rewiring "next" pointers:
for (i=0;i<(nItems-2);++i)
ptrs[i]->next = ptrs[i+1];
ptrs[nItems-1] = NULL;
Rewire the head pointer.
head = ptrs[0];
And finally, free the pointer array.
free(ptrs);
Your linked list is sorted.
Sidebar merge-sort is the only O(nlogn) algorithm I know of that can sort a linked list with no added space requirements. A general solution that prototypes to the following would be nutz:
mergesort_list(void **head, size_t offset_ptr, int(*comp)(void*,void*))
head: address of the head pointer.
offset_ptr: offset in bytes from a node ptr where the 'link' pointer can be found.
comp: comparison function.

- 65,258
- 11
- 75
- 141
-
-
@IrfanM no problem. I hope what is going on at each step makes sense. – WhozCraig Nov 15 '12 at 23:47
-
I think so at least now I do. I'll implement it in a second and let you know. – IrfanM Nov 15 '12 at 23:48
If we simply show you the code we will be doing you a great disservice. I will give you, instead, two different approaches and you can implement the one that you prefer.
The first approach is to "sort" as you insert: when you are inserting a value, say, 7, you follow this procedure starting with the first entry in your list until you run out of nodes:
If the node you are examining has a value that is greater than 7 you insert a new node before the node you are examining and return. Otherwise you look at the next node. If there is no next node, the. You insert a new node at the end of the list since that means that 7 is larger than al other entries in the list and return.
A second alternative is to sort the entire list using one of the many sorting algorithms. I would suggest that you use BubbleSort since it's easy to understand and implement. You can read more about bubblesort (ans many other sorting algorithms) on Wikipedia.

- 10,495
- 1
- 21
- 37
Good old quicksort will do the trick (C++03 friendly):
#include <algorithm>
#include <functional>
#include <iostream>
#include <iterator>
#include <list>
using namespace std;
void qsort(list<int>::iterator first, list<int>::iterator last)
{
if (distance(first, last) < 2)
return;
int pivot = *first;
list<int>::iterator it = partition(first, last, bind2nd(less<int>(), pivot));
qsort(first, it);
qsort(it, last);
}
int main()
{
std::list<int> l;
l.push_back(5);
l.push_back(4);
l.push_back(1);
l.push_back(10);
l.push_back(3);
l.push_back(6);
l.push_back(7);
cout << "List:";
copy(l.begin(), l.end(), std::ostream_iterator<int>(std::cout, " "));
cout << endl;
qsort(l.begin(), l.end());
cout << "Sorted list:";
copy(l.begin(), l.end(), std::ostream_iterator<int>(std::cout, " "));
cout << endl;
return 0;
}
Check: http://ideone.com/OOGXSp

- 2,300
- 18
- 26
-
ah, okay. I like this method. But how could I change it so that it works with having only one argument / parametre, which is my type ( Set ) or the linked-list that needs to be sorted. – IrfanM Nov 15 '12 at 23:52
-
If you were going to start with `std::list` you could just use the built-in [`sort` method](http://en.cppreference.com/w/cpp/container/list/sort). – Mark Ransom Nov 16 '12 at 01:33