我花了很多時間試圖解決這個問題,並在課堂結束。我已經發現了很多有關數組和其他選擇支點的方法,但我只是處於末尾,而且我真的很瘋狂,任何幫助都會讓你無法想象。使用隨機數據透視錶快速排序鏈接列表C
#include <stdlib.h> /*and, malloc*/
#include <stdio.h> /*printf*/
struct listnode {
struct listnode *next;
long value;
};
/*Finds length of list, which is usefull in selecting a random pivot*/
int ListLength (struct listnode *list)
{
struct listnode *temp = list;
int i=0;
while(temp!=NULL)
{
i++;
temp=temp->next;
}
return i;
}
/*Prints list*/
void printList(struct listnode *list)
{
struct listnode *node;
node=list;
printf("\nList Values\n");
while(node!=NULL)
{
printf("%2lo ", node->value);
node=node->next;
}
}
/*Creates a list of desired length*/
struct listnode *createList(int lengthOfList)
{
long i;
struct listnode *node, *space;
space = (struct listnode *) malloc(lengthOfList*sizeof(struct listnode));
for(i=0; i< lengthOfList; i++)
{ (space + i)->value = 2*((17*i+1)%lengthOfList);
(space + i)->next = space + (i+1);
}
(space+(lengthOfList-1))->next = NULL;
node = space;
return node;
}
/*Prof Brass's test*/
void Brass_test(struct listnode *list)
{
int i;
printf("\nChecking sorted list\n");
for(i=0; i < 100; i++)
{
if(list == NULL)
{
printf("List ended early\n"); exit(0);
}
if(list->value != 2*i)
{
printf("Node contains wrong value\n"); exit(0);
}
list = list->next;
}
printf("Sort successful\n");
}
/*Selects a random pivot point*/
struct listnode *SelectPivot(struct listnode *list)
{
int k, n, i = 0;
n = ListLength(list);
struct listnode *pivot=list;
k=rand()%n;
for (; i < k; ++i)
{
pivot=pivot->next;
}
return pivot;
}
// Sorts a list using quicksort algo with random pivot point
struct listnode *Quicksort(struct listnode *list)
{
// Return NULL list
if (ListLength(list) <= 1) return list;
struct listnode *less=NULL, *more=NULL, *next, *endl, *temp=list;
/*Select a random pivot point*/
struct listnode *pivot = SelectPivot(list);
printf("Pivot Value = %lo\n", pivot->value);
/*Divide & Conquer*/
while(temp != NULL)
{
next = temp->next;
if(temp->value < pivot->value)
{
temp->next = less;
less = temp;
}
else
{
temp->next = more;
more = temp;
}
temp = next;
}
less = Quicksort(less);
more = Quicksort(more);
// Merge
if(ListLength(less)!=0)
{
while(endl != NULL)
{
endl = less->next;
less->next = more;
more = less;
less = endl;
}
return more;
}
else
{
return more;
}
}
int main(void)
{
struct listnode *node;
node = createList(25);
printf("Unsorted List\n");
printList(node);
printf("\nSorted List\n");
node = Quicksort(node);
printf("\nList Count node %d\n", ListLength(node));
printList(node);
/* Brass_test(node);*/
exit(0);
}
快速排序上是一個不切實際的概念 - 它對於數據結構來說真的不是一個合適的算法。您可能最好將列表轉換爲數組,對數組進行排序,然後重建列表。其他任何東西都會比普通的QuickSort慢很多,因爲QuickSort是基於O(1)訪問數組中任意項目的時間,並且通過列表可以獲得O(N)訪問列表中的任意項目的權限,所以你的O(N log N)QuickSort算法變成O(N * N log N),這比Bubble Sort更糟糕。 – 2012-02-20 21:10:34
@Jonathan:不正確 - Quicksort的分區階段按順序遍歷所有元素。因此,即使您需要額外的O(N)每步選擇數據透視表,它仍然是O(N log N),用於排序列表。由於具有較低的常數因子,其他種類的情況可能更有意義。 – 2012-02-20 21:33:33
@ChrisDodd對於鏈表,mergesort變體很容易實現,並且比quicksort更快。 – 2012-02-20 21:56:18