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++.
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??)
qsort()
since it is standard-equipped). 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.
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.
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.