Ich habe ein Array von numlists
verknüpften Listen. Knoten in den Listen sind von der Form:Sortieren und Zusammenführen mehrerer verkettete Listen mit sortierten Unterabschnitten
struct Edge
{
int64_t blocknum;
int64_t location;
struct Edge *next;
};
typedef struct Edge edge;
ich alle Listen zu einer einzigen Liste verschmelzen müssen, die von location
aufsteigend sortiert ist. Jede Liste besteht aus Blöcken, für die Knoten gleich blocknum
sind, und jeder dieser Blöcke ist bereits sortiert. Listenblöcke mit größeren Werten von blocknum
haben alle ihre Standortwerte größer als Blöcke mit kleineren blocknum
. Blöcke in den Unterlisten sind bereits in der Reihenfolge blocknum
lokal sortiert. Was praktisch bedeutet, dass dies auf das Sortieren von Blöcken durch blocknum
in aufsteigender Reihenfolge hinausläuft, und ich muss mich nicht zu sehr um location
kümmern, da das für sich selbst sorgen wird. Sie können davon ausgehen, dass das next
Mitglied eines Arrays entweder gültig und zugewiesen ist oder explizit NULL deklariert ist.
Dies ist die Funktion, die ich mit
edge *sort_edges(edge **unsorted, int numlists)
{
edge *sorted_head = NULL;
edge *sorted_current = NULL;
edge *current_edge = NULL;
edge *temp = NULL;
int64_t blocknum;
int i;
int64_t minblock;
int remaining = numlists;
int first = 1;
int minblock_index;
while(remaining) //while there are still more lists to process
{
minblock = LLONG_MAX;
temp = NULL;
minblock_index = INT_MAX;
remaining = numlists;
for (i=0; i<numlists; i++) //loop over the list of head nodes to find the one with the smallest blocknum
{
if (!unsorted[i]) //when a lists is exhausted the lead node becomes NULL, and we decrement the counter
{
remaining--;
}
else //a simple minimum finding algorithm
{
current_edge = unsorted[i];
if (current_edge->blocknum < minblock)
{
temp = current_edge;
minblock = current_edge->blocknum;
minblock_index = i;
}
}
}
if (remaining == 0)
{
break;
}
if (first) //if we have not yet set up the head of the list, we have to save a pointer to the head
{
sorted_head = temp;
sorted_current = sorted_head;
first = 0;
}
else
{
sorted_current->next = temp;
}
blocknum = sorted_current->blocknum;
while (sorted_current->blocknum == blocknum && sorted_current->next) //skip through to the end of the block so that the next section we append will go on the end
{
sorted_current = sorted_current->next;
}
unsorted[minblock_index] = sorted_current->next; //reset the head of the unsorted list to the node after the block
}
return sorted_head;
}
Dies funktioniert kam. Meine Frage ist:
Kann ich besser in Bezug auf einen effizienten Sortieralgorithmus tun? (Fast sicher ja, ich bin nur neugierig, was die Leute für ein Sortierproblem mit den gegebenen Annahmen einfallen lassen).
Bitte beachten Sie, dass ich die Frage bearbeitet habe, da ich den ursprünglichen Fehler selbst gefunden habe, bevor jemand darauf geantwortet hat. Wenn jemand während dieser Zeit eine Antwort eintippte, lass es mich wissen und ich werde es rückgängig machen. – KBriggs