使用C中的随机数据透视表在链接列表上快速排序

时间:2012-02-20 20:38:33

标签: c sorting random linked-list quicksort

我花了很多时间尝试为一个班级解决这个问题,而且我已经结束了。我已经找到了很多有关阵列和其他选择枢轴的方法的资源,但我只是在结束,我真的在这里疯狂,任何帮助都会非常感激,你无法想象。

#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);
}

3 个答案:

答案 0 :(得分:5)

对于那些对代码感到好奇的人来说,这就是问题的解决方案。我只包括它自己的函数和辅助函数。

干杯,

#include <stdlib.h>     //rand, malloc
#include <stdio.h>      //print
#include <time.h>

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;
}

// 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, *end, *temp=NULL;

    // Select a random pivot point
    struct listnode *pivot = SelectPivot(list);

    // Remove pivot from list
    while(list !=NULL)
    {
        next = list->next;

        if(list->value != pivot->value)
        {
            list->next=temp;
            temp = list;
        }
        list = next;
    }

    // Divide & Conq
    while(temp != NULL)
    {
        next = temp->next;
        if(temp->value < pivot->value)
        {
            temp->next = less;
            less = temp;
        }
        else 
        {
            temp->next = more;
            more = temp;    
        }
        temp = next;
    }

    // Recursive Calls
    less = Quicksort(less);
    more = Quicksort(more);

    // Merge
    if(less != NULL)
    {
        end = less;
        while(end->next != NULL){
            end=end->next;
            }
        pivot->next=more;
        end->next = pivot;
        return less;        
    }
    else{
        pivot->next = more;
        return pivot;   
    }

}

答案 1 :(得分:0)

您的合并代码存在一个问题 - 它将less列表反转,同时将其添加到more列表中,这会导致垃圾邮件。

答案 2 :(得分:-1)

如果应用快速排序,最佳做法是始终采用FLOOR(n / 2)As pivot