C:快速排序链表
我应该写一个程序,从一个文件中读取密码和数字,例如,C:快速排序链表,c,quicksort,C,Quicksort,我应该写一个程序,从一个文件中读取密码和数字,例如,jskskfj128938,将它们放在一个链表中,并使用快速排序对它们进行排序。该文件包含100个条目。我已经把它读到了一个链表中,效果很好。然而,我在使用快速排序和分区函数时遇到了问题,因为大多数在线教程使用交换而不是移动,但是我应该将小于轴的数字移动到一个新列表中,与较大的数字相同,并在最后将它们连接起来。到目前为止,我的努力如下: 主要内容: 好的,这是一个任务,所以您必须在列表上实现快速排序。 查看您的代码,有一些问题妨碍了正确的行为:
jskskfj128938
,将它们放在一个链表中,并使用快速排序对它们进行排序。该文件包含100个条目。我已经把它读到了一个链表中,效果很好。然而,我在使用快速排序和分区函数时遇到了问题,因为大多数在线教程使用交换而不是移动,但是我应该将小于轴的数字移动到一个新列表中,与较大的数字相同,并在最后将它们连接起来。到目前为止,我的努力如下:
主要内容:
好的,这是一个任务,所以您必须在列表上实现快速排序。 查看您的代码,有一些问题妨碍了正确的行为:
- 在
函数中,为partition
分配一个虚拟pivot
,没有明显的目的,也永远不会释放它,除非它是您没有发布的list\u元素
的副作用串联
- 在
函数中,使用partition
,但是tmp=tmp->next迭代到下一项
被插入到一个子列表的前面,因此它的下一个元素不是您所期望的tmp
- 在
中,使用未初始化的列表指针调用qsortlist
init\u list
的语义不明显,是否应该分配它返回的concatenate
?你什么时候能放出来列表
删除列表的第一个元素并返回它list\u take\u first(list)
将list\u append(list,element)
list\u元素及其所有链推送到列表末尾
concatenate
合并到qsort\u list
函数中
代码非常简单,不分配内存,但对于列表已经排序的病态情况,它会深入递归。通过选择列表中间的轴心,或随机选择轴心,或检查已排序的子列表,可以很容易地对其进行改进。您还可以尝试避免在较大的子列表上递归,就像在数组qsort
中一样,但这有点棘手。您还可以将比较函数传递给qsortlist
和partition
,以实现不同的排序顺序
list_element *list_take_first(list *mylist) {
list_element *le = mylist->first;
if (le != NULL) {
mylist->first = le->next;
le->next = NULL;
if (mylist->first == NULL) {
mylist->last = NULL;
}
}
return le;
}
void list_append(list *mylist, list_element *le) {
if (le) {
if (mylist->first == NULL) {
mylist->first = le;
} else {
mylist->last->next = le;
}
while (le->next) {
le = le->next;
}
mylist->last = le;
}
}
list_element *partition(list *input, list *left, list *right) {
/* simplistic partitioning: use first element as pivot */
list_element *pivot = list_take_first(input);
if (pivot != NULL) {
list_element *tmp;
while ((tmp = list_take_first(input)) != NULL) {
if (tmp->data.anzahl >= pivot->data.anzahl) {
list_append(right, tmp);
} else {
list_append(left, tmp);
}
}
}
return pivot;
}
void qsort_list(list *mylist) {
if (mylist->first != mylist->last) {
list left, right;
init_list(&left);
init_list(&right);
list_element *pivot = partition(mylist, &left, &right);
qsort_list(&left);
qsort_list(&right);
list_append(mylist, left.first);
list_append(mylist, pivot);
list_append(mylist, right.first);
}
}
试图编写对列表有效的快速排序是自找麻烦。。。除非你必须这样做,否则不要这样做。你有问题吗?链表和合并排序是天造地设的婚姻。使用快速排序对链表排序是邪恶的!链表意味着使用合并排序进行排序,您可以在没有空间开销的情况下获得
N.log(N)
时间复杂度,这接近最优。为什么要使用快速排序?如果需要,请分配一个指针数组,将列表元素地址存储到其中,使用C库qsort()
并按数组顺序重新链接元素。顺便说一下,一些C库使用合并排序算法实现qsort
,以避免病态情况。打开编译器警告。此外,您的问题不在于快速排序。它们只是链表问题。在尝试建立链接列表之前,请确保您首先对链接列表有很好的了解。非常感谢!我不得不对代码进行一些调整,以便严格的在线测试能够接受它,但最终还是成功了:)
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef struct passwort passwort;
struct passwort {
char name[100];
int anzahl;
};
typedef struct list_element list_element;
struct list_element {
passwort data;
list_element *next;
};
typedef struct list list;
struct list {
list_element *first;
list_element *last;
};
void init_list(list *mylist);
void insert_front(list_element *le, list *mylist);
void free_list(list *mylist);
void read_data(char *filename, list *mylist);
list_element *partition(list *input, list *left, list *right);
void qsort_list(list *mylist);
void print_list(list *mylist);
void init_list(list *mylist) {
mylist->first = NULL;
mylist->last = NULL;
}
void insert_front(list_element *le, list *mylist) {
if (mylist->first == NULL) {
mylist->first = le;
mylist->last = le;
} else {
le->next = mylist->first;
mylist->first = le;
}
}
list_element *partition(list *input, list *left, list *right) {
list_element *pivot = malloc(sizeof(list_element));
pivot->next = NULL;
if (input->first != NULL) {
input->first = pivot;
} else {
printf("Liste leer!\n");
}
if (input->first == input->last) {
return (input->first);
}
list_element *tmp = input->first;
while (tmp != NULL) {
if (tmp->data.anzahl >= pivot->data.anzahl) {
insert_front(tmp, right);
printf("%s\n", tmp->data.name);
} else {
insert_front(tmp, left);
}
tmp = tmp->next;
}
return (pivot);
}
void qsort_list(list *mylist) {
int length = 100;
if (length > 1) {
list *A;
init_list(A);
list *B;
init_list(B);
list_element *pivot;
pivot = partition(mylist, A, B);
qsort_list(A);
qsort_list(B);
mylist = concatenate(A, pivot, B);
}
}
list_element *list_take_first(list *mylist) {
list_element *le = mylist->first;
if (le != NULL) {
mylist->first = le->next;
le->next = NULL;
if (mylist->first == NULL) {
mylist->last = NULL;
}
}
return le;
}
void list_append(list *mylist, list_element *le) {
if (le) {
if (mylist->first == NULL) {
mylist->first = le;
} else {
mylist->last->next = le;
}
while (le->next) {
le = le->next;
}
mylist->last = le;
}
}
list_element *partition(list *input, list *left, list *right) {
/* simplistic partitioning: use first element as pivot */
list_element *pivot = list_take_first(input);
if (pivot != NULL) {
list_element *tmp;
while ((tmp = list_take_first(input)) != NULL) {
if (tmp->data.anzahl >= pivot->data.anzahl) {
list_append(right, tmp);
} else {
list_append(left, tmp);
}
}
}
return pivot;
}
void qsort_list(list *mylist) {
if (mylist->first != mylist->last) {
list left, right;
init_list(&left);
init_list(&right);
list_element *pivot = partition(mylist, &left, &right);
qsort_list(&left);
qsort_list(&right);
list_append(mylist, left.first);
list_append(mylist, pivot);
list_append(mylist, right.first);
}
}