gpt4 book ai didi

C Quicksort(链表)段错误

转载 作者:太空宇宙 更新时间:2023-11-04 08:07:11 25 4
gpt4 key购买 nike

我必须在链表上创建一个快速排序(在 C 中)。我的第一个和最后一个指针是一个枢轴(在此代码中,它是列表的第一个元素)。我必须使用的结构:

typedef struct list_element list_element;

struct list_element {
char *password;
int count;
list_element* next;
};

typedef struct list list;

struct list {
list_element* first;
list_element* last;
};

我有一个包含 100 个密码和计数的文件。像这样:password1 123 (下一行) password2 435 (下一行) password3 133 ...必须在该程序末尾对密码进行排序(根据它们的数量)。左右列表不需要任何额外的内存分配,因为我只需要使用 next 指针。 (这就是练习中的提示。)

给定的主函数:

int main(int argc, char** args)
{
if (argc != 2)
{
printf("Nutzung: %s <Dateiname>\n",args[0]);
return 1;
}
list mylist;
init_list(&mylist);
read_data(args[1],&mylist);
qsort_list(&mylist);
printf("Sortierte Liste:\n");
print_list(&mylist);
free_list(&mylist);
return 0;
}

我已经初始化了我的列表:

void init_list(list* mylist)
{
mylist->first = NULL;
mylist->last = NULL;
}

并在末尾插入一个新元素(passwort = 文件中的密码,hauefigkeit = 文件中的计数):

void insert_list(list_element* le, list* mylist)
{
if (mylist->first != NULL) {
le->next = mylist->last;
mylist->last = le;
le->next= NULL;
}
else {
mylist->last->next = le;
mylist->last = le;
mylist->last->next = NULL;
}
}

从文件中读取数据:

void read_data(char* filename, list* mylist)
{
FILE *file_in = fopen(filename, "r");

if (file_in == NULL) {
perror("Could not open input file!");
exit(1);
}

char buffer[999] = "0";

char *passwort = (char*) calloc(1,sizeof(passwort));
int haeufigkeit = 0;

while (fgets(buffer, sizeof(buffer), file_in) != NULL) {
sscanf(buffer, "%s %d", passwort, &haeufigkeit);

list_element* le = (list_element*)calloc(1,sizeof(list_element));

for(int i = 0; i <=100; i++) {
le->password[i] = passwort[i];
}
le->count = haeufigkeit;
le->next = NULL;

insert_list(le, mylist);
}
fclose(file_in);
}

列表的划分:

list_element* partition( list* input, list* left, list* right )
{
list_element* pivot = NULL;
if (input->first != NULL) {
list_element* temp;
pivot = input->first;
input->first = input->first->next;
pivot->next = NULL;
left->first = NULL;
right->first = NULL;

while (input->first != NULL) {
if((pivot->count)>(input->first->count)){
temp=input->first->next;
insert_list(input->first, left);
input->first=temp;
}
else {
temp = input->first->next;
insert_list(input->first, right);
input->first = temp;
}
}
}
return pivot;
}

实际的快速排序:

void qsort_list(list* mylist)
{
if(mylist->first == mylist->last){
}

else{
list* left = calloc(1,sizeof(list));
list* right= calloc(1,sizeof(list));
list_element* pivot = partition(mylist, left, right);

qsort_list(left);
qsort_list(right);

if(left->first == NULL){
mylist->first = pivot;
}
else{
mylist->first = left->first;
left->last->next = pivot;
}

if(right->first == NULL){
pivot->next = NULL;
mylist->last = pivot;
}
else{
pivot->next = right->first;
mylist->last = right->last;
}

free(right);
free(left);

}
}

最后打印列表:

void print_list(list* mylist)
{
list_element *elem = mylist->first;
while (elem != NULL) {
printf("%s %d\n", elem->password, elem->count);
elem = elem->next;
}
}

和空闲列表:

void free_list(list* mylist)
{
list_element *current;
list_element *second;
current = mylist->first;
while (current != NULL) {
second = current->next;
free(current);
current = second;
}
}

语法应该没问题。 GCC (c99, Wall) 编译没有任何问题。

但是存在段错误。我已经搜索了几个小时,但我不知道问题出在哪里。也许你可以帮我解决这个问题。


在前两个答案之后没有任何段错误。但是 read_data 函数仍然有问题。程序无法正确读取密码。也许我误解了你关于阅读功能的回答。这是当前的功能:

void read_data(char* filename, list* mylist)
{
FILE *file_in = fopen(filename, "r");

if (file_in == NULL) {
perror("Could not open input file!");
exit(1);
}

char buffer[999] = "0";

int haeufigkeit = 0;

while (fgets(buffer, sizeof(buffer), file_in) != NULL) {

char passwort[100];

sscanf(buffer, "%s %d", passwort, &haeufigkeit);

list_element* le = (list_element*)

calloc(1,sizeof(list_element));


le->password = passwort;
le->count = haeufigkeit;
le->next = NULL;

insert_list(le, mylist);
}
fclose(file_in);
}

最佳答案

正如 Leonardo Alves Machado 指出的那样,在使用 C/C++ 程序时遇到问题时的第一个 react 是使用像 gdb 这样的调试器来运行它。 .这是基础知识:

gcc -g main.c -o main
gdb main
(gdb) run

注意 -g 编译标志:这将向可执行文件添加调试信息。


read_data中,行

for(int i = 0; i <=100; i++) {
le->password[i] = passwort[i];
}

真的很烦我。您为 passwort 分配空间(顺便说一下,您永远不会释放它)并尝试将其复制到 le->password,这是一个简单的指针(没有分配空间)。你真正需要的是让le->password 指向 passwort,即

le->password = passwort;

free_list 中,不要忘记在释放 list_element 空间之前释放 passwort 空间:

while (current != NULL) {
second = current->next;
free(current->password);
free(current);
current = second;
}

关于C Quicksort(链表)段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41943496/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com