我正在做一个排序列表的程序。但问题是head中的元素将在第二次递归调用中被忽略。es:
input: 7->1->8->0->NULL OUTPUT: 1->0->7->8->NULL.
为什么1
被忽略了?
这是一个node struct:
struct nodo {
int elem;
struct nodo *next;
};
和功能:
struct nodo *ordinaLista(struct nodo *head) {
//in ordine crescente
if (!head)
return NULL;
else {
if ((head->next) && (head->elem >= head->next->elem)) {
int tmp = head->elem;
head->elem = head->next->elem;
head->next->elem = tmp;
}
//printList(head);
head->next = ordinaLista(head->next);
head->next = ordinaLista(head->next);
}
return head;
}
4条答案
按热度按时间fae0ux8s1#
您的函数没有正确排序列表:你只对前两个元素进行排序,然后继续对列表的其余部分进行排序:唯一保证在适当位置结束的元素是将成为最后一个元素的最大元素。
递归地调用函数两次可能会解决这个问题,但是你需要改变操作的顺序:对于具有指数复杂度的简单实现O(n!),你应该首先对列表的其余部分进行排序,然后测试第一个元素是否需要与第二个元素交换,确保第一个元素是最小的元素,最后如果元素被交换,重新排序列表的其余部分。
以下是修改后的版本:
这种方法非常低效,但似乎与您在问题中提交的代码相对应。更有效的方法是对链表进行排序,如合并排序。
iyr7buue2#
让我们模拟排序过程:
7->1->8->0->NULL
1->7->8->0->NULL
实际上,模拟第一步就足够了。如您所见,“1”节点被交换到第一个位置,然后程序继续向后执行,“1”被忽略。事实上,你的排序算法是不正确的。你的排序算法实际上是一个“泡沫”。要完成排序,需要多次冒泡。具体算法可以参考“冒泡排序”。
dohp0rv53#
你的函数的问题是你并没有真正执行排序。你的函数只是将整数的值与下一个更大的值交换。
这样,在单个迭代中,可以保证列表中的最后一项是最大的。
为什么要递归调用函数两次?这个动作对我来说很奇怪。
vtwuwzda4#
OP的排序代码已损坏
与其对这种固有的缓慢方法进行小的修复,不如考虑一种更有效的方法。
示例: