快速排序功能仅在最后一个值最大时才有效

时间:2016-07-07 23:43:47

标签: c arrays sorting struct

我正在尝试使用C中的快速排序练习。我的程序是一个简单的结构数组,它接受命令行参数(name1 age 1 name2 age2 ...等)并按降序输出所述年龄。

仅在输入的最后一个年龄最大时才能正常工作。除此之外我要么没有输出或Seg Fault 11.有没有人有任何想法?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NameLen 80
void print_struct();

struct people
{
char name [NameLen + 1];
int age;
}; //defining a structure//

typedef struct people PERSON;
void quicksort(struct people list[],int,int);
int main(int argc, const char * argv[])

{
int i,j;
j = 0;
int l = ((argc/2)-1);


struct people list[l]; //maximum size of array of structs


   if (argc %2 == 0) //if the number of arguments is an even number
{

printf("Invalid Arguments!\n");
printf("Usage : ./hw5 name1 age1 name2 age2 ... "); //print error message and correct program usage
    exit(0);
}

printf("You have entered %d persons(s) into the program \n",(argc/2));

for (i=1; i < argc; i+=2)

{
    strcpy(list[j].name, argv[i]);
    list[j].age = atoi(argv[i+1]);
    if(list[j].age == 0)
    {
        printf("...Invalid age <=0. Try again.\n");

        exit(0);
    }
    j++;

}
   printf("Unsorted Names: \n");
    print_struct(&list,argc);

printf ("Sorted by Age: \n");
quicksort(list,0 ,j);
for(i=0;i<j;i++){
  printf("Name : %s| Age : %d\n", list[i].name, list[i].age);}//possible error here?

//Quicksort Function

5 个答案:

答案 0 :(得分:2)

也许问题是j的价值。 j是列表的长度吗?或列表的长度 - 1?

看起来这就是你想要的: j =列表长度

printf ("Sorted by Age: \n");
quicksort(list,0 ,j-1);
for(i=0;i<j;i++){
  printf("Name : %s| Age : %d\n", list[i].name, list[i].age);}

答案 1 :(得分:0)

快速排序功能很好。问题是你说错了:

quicksort(list,0 ,j);

您为firstlast传入的值代表第一个和最后一个元素的索引。从使用j循环元素的方式可以看出,j是元素的数量。这意味着最后一个元素具有索引j-1

所以你传递的值last是一个超出数组末尾的元素。当您尝试读取/写入此伪造元素时,您调用undefined behavior,在您的情况下(幸运的是)会导致段错误。

传入最后一个元素的实际索引(即小于大小的元素)并成功运行。

quicksort(list,0 ,j - 1);

答案 2 :(得分:0)

你的循环不正确:

    while(list[i].age<=list[pivot].age&&i<last)
        i++;

此循环可能以i == last结束,这是不好的,因为您尝试交换该值,这将超出数组的范围。

    while(list[j].age>list[pivot].age)
        j--;

此处,由于jlast开头,因此您可以在数组外部阅读。

一种可能的补救措施是先向后移动j,然后再向下移动do - while样式。然后,递增i,针对递减的j进行测试。

    do --j; while(list[j].age>list[pivot].age);
    do ++i; while(list[i].age<=list[pivot].age&&i<j);

答案 3 :(得分:0)

我使代码变得有点简单(将字符数组更改为char,使其尽可能简单)。 我的想法是,当你打电话时:

quicksort(list,0 ,j);

你应该叫什么:

quicksort(list,0 ,j-1);

因为最后一个参数必须是数组长度减1,最后一个位置。

我没有遇到段错误,在运行你的代码或我修改过的代码时,如果可能,请仔细检查你用作输入的字符串。

这是代码的“我的”版本。

希望它有所帮助。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NameLen 80
void print_struct();

struct people
{
    char name;
    int age;
}; //defining a structure//

typedef struct people PERSON;
void quicksort(struct people list[],int,int);

int main(int argc, const char * argv[])
{
    int i,j;
    j = 10;
    struct people list[10]; //maximum size of array of structs

    for (i=0; i < 10; i++)
    {
        list[i].name = 'a';
        list[i].age = 10-i;
    }

    printf("Unsorted Names: \n");
    for(i=0;i<j;i++){
        printf("Name : %c| Age : %d\n", list[i].name, list[i].age);}//possible error here?

    printf ("Sorted by Age: \n");
    quicksort(list,0 ,j-1);
    for(i=0;i<j;i++){
        printf("Name : %c| Age : %d\n", list[i].name, list[i].age);}//possible error here?
}

void quicksort(struct people list[],int first,int last)
{
  struct people temp;
  int i,j,pivot;

  if(first<last){
        pivot=first;
        i=first;
        j=last;

        while(i<j)
        {
            while(list[i].age<=list[pivot].age&&i<last)
                i++;
            while(list[j].age>list[pivot].age)
                j--;
            if(i<j){
                temp=list[i];
                list[i]=list[j];
                list[j]=temp;
            }
        }

    temp=list[pivot];
    list[pivot]=list[j];
    list[j]=temp;
    quicksort(list,first,j-1);
    quicksort(list,j+1,last);
  }
}

答案 4 :(得分:0)

应用所有注释后,这是生成的代码,它干净地编译,但由于缺少两个函数而不会链接:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define NAME_LEN (80)


struct people
{
    char name [NAME_LEN + 1];
    int age;
}; //defining a structure//

typedef struct people PERSON;

// print_struct( ptrToList, numElements )
void print_struct( PERSON *, int );

// quicksort( ptrToList, firstOffset, numElements )
void quicksort(struct people list[],int,int);


int main(int argc, const char * argv[])
{
    //int i,j;
    //j = 0;
    //int l = ((argc/2)-1);
    int l = argc/2;

    struct people list[l]; //maximum size of array of structs

    if (argc %2 == 0) //if the number of arguments is an even number
    {
        //printf("Invalid Arguments!\n");
        fprintf( stderr, "Invalid Arguments!\n" );

        //printf("Usage : ./hw5 name1 age1 name2 age2 ... "); //print error message and correct program usage
        fprintf( stderr, "Usage : %s name1 age1 name2 age2 ... ", argv[0]);

        // exit(0);
        exit( EXIT_FAILURE );
    }

    //printf("You have entered %d persons(s) into the program \n",(argc/2));
    printf("You have entered %d persons(s) into the program \n", l);

    //for (int i=1; i < argc; i+=2)
    for (int i=1, j=0; j < l; i+=2, j++)
    {
        //strcpy(list[j].name, argv[i]);
        memset( list[i].name, '\0', NAME_LEN+1);
        strncpy( list[j].name, argv[i], NAME_LEN );
        list[j].age = atoi(argv[i+1]);

        if(list[j].age == 0)
        {
            fprintf( stderr, "...Invalid age <=0. Try again.\n");

            //exit(0);
            exit( EXIT_FAILURE );
        }
        //j++;
    }

    printf("Unsorted Names: \n");
    //print_struct(&list,argc);
    print_struct( list, l );

    //printf ("Sorted by Age: \n");
    //quicksort(list,0 ,j);
    quicksort( list, 0, l ); 

    printf ("Sorted by Age: \n");
    // //for(i=0;i<j;i++)
    //for( int i=0; i<l; i++ )
    //{
    //  printf("Name : %s| Age : %d\n", list[i].name, list[i].age);
    //}//possible error here?
    //}
    print_struct( list, l);
} // end function: main


//Quicksort Function