Sorting two linked lists according to memory location

Go To StackoverFlow.com

0

I need to merge two doubly-linked lists, but not by their values (the lists are not sorted). I want to obtain a single list that has all the nodes from the two, but in the order in which they appear in memory.

Maybe this image helps more: http://img140.imageshack.us/i/drawing2.png/

Is there any algorithm (preferably a fast one) that can do this kind of merge ? Maybe this is a bit helpful:

  • the start node of the lists is always before the other ones.
  • a list can have up to 8192 nodes.
  • I know where the nodes are located in memory because the lists keep track of free location in a big block of memory (used in a memory allocator).
  • I work in C++.

Thanks in advance!

2009-06-16 14:56
by Gratian Lup
your requirements make this sound not so much like a linked list.. why the upper limit on nodes? why the big block to allocate from - Evan Teran 2009-06-16 15:00
This is part of a memory allocator. A block of memory has 32KB and this "lists" keep track of which locations from this block have been freed (one for objects freed by the thread that owns the block, one for other threads). You're right, this aren't actually linked lists. A "node' is a single 32 bit number, the lower part meaning Next, the upper Previous, expressed in distance from the block start. Because the address of the block is known, I don't need to store real pointers and save so a lot of space. The maximum number of nodes is 32KB / 4 bytes = 8192 nodes - Gratian Lup 2009-06-16 15:36


6

Well it sounds like you aren't using std::list, so I'll go with the generic solution. Since your requirement is to merge the lists, but have the nodes be in order of there physical location in memory. You can likely just append the two lists, then sort the nodes by address of the nodes.

see: http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html for a sorting algorithm for linked lists.

When sorting, instead of comparing node1->value < node2->value just do (size_t)node1 < (size_t)node2, or something to that nature.

2009-06-16 15:02
by Evan Teran
std::less is the "official" way to compare pointers. It is defined by the standard to be capable of comparing any two pointers, even if operator < for pointers can't - Steve Jessop 2009-06-17 01:15


2

"Merge" is a bit misleading here, as you can only merge sorted lists, and yours aren't sorted.

You need to sort, not to merge.

Put the pointers to nodes into a vector. use std::sort on the vector, and pass a comparison functor that casts each pointer to size_t (i think) and compares the resulting numbers.

You can then rearrange your linked lists according to the resulting order in the vector.

2009-06-16 15:01
by Arkadiy
Evan's answer is better - use list sorting algorithm rather than creating a spare vector - Arkadiy 2009-06-16 15:05
Ads