我正在尝试使用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
答案 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);
您为first
和last
传入的值代表第一个和最后一个元素的索引。从使用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--;
此处,由于j
以last
开头,因此您可以在数组外部阅读。
一种可能的补救措施是先向后移动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