Merge sorting a struct

我的梦境 提交于 2019-12-20 07:23:27

问题


#include<stdio.h>
#include<stdlib.h>
typedef struct points{
        float axis[2];
        int id;
}Points;

typedef enum{
        SortById,
        SortByXAxis
}SortType;

Points* fill_Array(char* filename, int* length);
void Print_set(Points* set, int number_of_points);
void mergesort(Points* set, int low, int high, int number_of_points,SortType sort);
void merge(Points* set, int low, int middle, int high, int number_of_points,SortType sort);

int main(int argc, char* argv[])
{
    int length;
    Points *array;
    array=fill_Array(argv[1],&length);
    Print_set(array,length);
    printf("\n\n");
    mergesort(array,0,length,length,SortById);
    Print_set(array,length);
    return 0;
}
Points* fill_Array(char* filename,int* length)
{
    int i;
    Points* array;
    FILE* file=fopen(filename,"r");

    if(file == NULL)
    {
        return NULL;
    }

    fscanf(file,"%d",length);
    array=malloc(sizeof(Points)* *length);

    for(i = 0; i < *length; i++)
    {
        fscanf(file,"%d %f %f", &(array+i)->id,&(array+i)->axis[0],&(array+i)->axis[1]);
    }
    fclose(file);

    return array;
}

void Print_set(Points *set, int number_of_points)
{
    int i;

    for(i = 0; i < number_of_points; i++)
    {
        printf("%d %f %f\n",(set+i)->id,(set+i)->axis[0],(set+i)->axis[1]);
    }
}

void mergesort(Points* set,int low,int high,int number_of_points, SortType sort)
{
    int mid1;

    if((high-low)>=1)
    {
        mid1 = (low+high)/2;

        mergesort(set, low, mid1, number_of_points, sort);
        mergesort(set, mid1+1, high, number_of_points, sort);
        merge(set, low, mid1, high, number_of_points, sort);

    }

}
void merge(Points* set, int low, int middle, int high, int number_of_points, SortType sort)
{
        int leftIndex=low;
        int rightIndex=middle;
        int combinedIndex = low;
        Points tempArray[number_of_points];
        int i;

        while(leftIndex <= middle && rightIndex<= high)
        {
            if(set[leftIndex].id <= set[rightIndex].id)
            {
                tempArray[combinedIndex++] = set[leftIndex++];
            }
            else
                tempArray[combinedIndex++] = set[rightIndex++];
        }

        if(leftIndex == middle+1)
        {
            while(rightIndex <= high)
            {
                tempArray[combinedIndex++] = set[rightIndex++];
            }
        }
        else
        {
            while(leftIndex <= middle)
            {
                tempArray[combinedIndex++] = set[leftIndex++];
            }
        }

        for( i = low; i < high; i++)
        {
            set[i] = tempArray[i];
        }
}

I am trying to perform a merge sort on an input file using a custom merge sort function. The merge sort functions however are not working and print out down below, the first block being the actual input file printed out to make sure fscanf is reading in everything correctly and the second being the printing after the merge functions are run. The functions are duplicating some of the values and are not sorting them either and I cannot find the mistake in the code. Note that the enum will be used to sort either the ids or the first float values I am just trying to get the merge sort to work before I use it to sort either the ids or those values.

1 13.000000 7.000000
13 14.000000 6.000000
95 7.000000 13.000000
39 0.000000 20.000000
78 10.000000 10.000000
68 3.000000 17.000000
32 6.000000 14.000000
10 19.000000 1.000000
0 18.000000 2.000000
45 17.000000 3.000000
92 4.000000 16.000000
29 5.000000 15.000000
85 8.000000 12.000000
79 15.000000 5.000000
12 16.000000 4.000000
32 1.000000 19.000000
77 9.000000 11.000000
52 12.000000 8.000000
80 11.000000 9.000000
31 2.000000 18.000000


1 13.000000 7.000000
13 14.000000 6.000000
68 3.000000 17.000000
0 18.000000 2.000000
10 19.000000 1.000000
0 18.000000 2.000000
0 18.000000 2.000000
92 4.000000 16.000000
92 4.000000 16.000000
29 5.000000 15.000000
32 1.000000 19.000000
52 12.000000 8.000000
77 9.000000 11.000000
79 15.000000 5.000000
12 16.000000 4.000000
32 1.000000 19.000000
32 1.000000 19.000000
80 11.000000 9.000000
95 7.000000 13.000000
95 7.000000 13.000000

回答1:


You appear to have gotten confused about the meaning of your boundary indices. Consider the initial call to function mergesort():

    mergesort(array,0,length,length,SortById);

You pass the same value for arguments high and number_of_points, which is fine, but it implies that high represents an exclusive upper bound on the indices of the sort range. The mergesort() implementation, however, seems geared for argument high to represent an inclusive bound.

The confusion continues with your merge() function, which is probably the main culprit here. By taking the passed midpoint value as the start index of the right sub-array, it seems to be expecting the midpoint as an exclusive upper bound of the left sub-array, but the current mergesort() implementation passes an inclusive upper bound. On the other hand, some of the index comparisons performed by merge() are appropriate only if middle is an inclusive upper bound of the subarray.

In short, you have a muddle. The basic outline of the algorithm looks fine, but you need to decide (and document for yourself) what your function parameters represent, and reconcile your implementation details with that. Were I you, I would adopt half-open representation for all intervals, so that lower bounds are always inclusive, and upper bounds always exclusive. Among other things, that has the advantage that each midpoint value can be interpreted equally correctly as the (exclusive) upper bound of the left half of its subarray or as the (inclusive) lower bound of the right half.




回答2:


    void mergesort(Points* set,int low,int high,int number_of_points, SortType sort)
    {
        int mid1;

        if((high-low)>1)
        {
            mid1 = (low+high)/2;

            mergesort(set, low, mid1, number_of_points, sort);
            mergesort(set, mid1, high, number_of_points, sort);
            merge(set, low, mid1, high, number_of_points, sort);

        }

    }
    void merge(Points* set, int low, int middle, int high, int number_of_points, SortType sort)
    {
            int leftIndex=low;
            int rightIndex=middle;
            int combinedIndex = low;
            Points tempArray[number_of_points];
            int i;

            while(leftIndex <= middle && rightIndex < high)
            {
                if(set[leftIndex].id <= set[rightIndex].id)
                {
                    tempArray[combinedIndex++] = set[leftIndex++];
                }
                else
                    tempArray[combinedIndex++] = set[rightIndex++];
            }

            if(leftIndex == middle+1)
            {
                while(rightIndex < high)
                {
                    tempArray[combinedIndex++] = set[rightIndex++];
                }
            }
            else
            {
                while(leftIndex < middle)
                {
                    tempArray[combinedIndex++] = set[leftIndex++];
                }
            }

            for( i = low; i < high; i++)
            {
                set[i] = tempArray[i];
            }
    }

0 18.000000 2.000000
1 13.000000 7.000000
10 19.000000 1.000000
0 18.000000 2.000000
12 16.000000 4.000000
13 14.000000 6.000000
29 5.000000 15.000000
31 2.000000 18.000000
32 6.000000 14.000000
32 1.000000 19.000000
39 0.000000 20.000000
39 0.000000 20.000000
52 12.000000 8.000000
31 2.000000 18.000000
68 3.000000 17.000000
77 9.000000 11.000000
78 10.000000 10.000000
12 16.000000 4.000000
79 15.000000 5.000000
85 8.000000 12.000000


来源:https://stackoverflow.com/questions/29039888/merge-sorting-a-struct

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!