我试图用C语言合并排序列表。我在法语维基百科上看到了这里的代码,但它给了我一个不正确的列表(即未排序)。不过,该函数编译得很好。请注意,我并没有真正使用top,我可能很快就会把它从结构中去掉。你能帮我找出这个代码的错误吗?我必须把它从算法伪代码翻译成C代码。非常感谢。
P
是未排序的输入列表。n
是列表的长度。
typedef struct s_stack t_stack;
struct s_stack {
int nbr;
int top;
struct s_stack *previous;
struct s_stack *next;
};
typedef t_stack *Pile;
t_stack *merge_sort(Pile p, int n) {
Pile q;
int Q;
int P;
q = NULL;
Q = n / 2;
P = n - Q;
if (P >= 2) {
q = merge_sort(p, P);
if (Q >= 2)
p = merge_sort(q, Q);
} else {
q = p->next;
}
q = fusion(p, P, q, Q);
return (q);
}
t_stack *fusion(Pile p, int P, Pile q, int Q) {
t_stack *tmp;
tmp = NULL;
while (1) {
if (p->next->nbr > q->next->nbr) {
/* my input list (not sorted) is circular and
I checked it is well linked ! This is the reason
why I need to do all that stuff with the nodes
It is basically supposed to move the node q->next
after node p */
tmp = q->next;
q->next = tmp->next;
q->next->previous = q;
tmp->previous = p;
tmp->next = p->next;
p->next->previous = tmp;
p->next = tmp;
if (Q == 1)
break;
Q = Q - 1;
} else {
if (P == 1) {
while (Q >= 1) {
q = q->next;
Q = Q - 1;
}
break;
}
P = P - 1;
}
p = p->next;
}
return (q);
}
你的方法有点复杂,但问题并不简单,但你错过了一些必要的步骤:
merge\u sort应该将列表分成两半并递归,除非列表很小
这是一个带有主函数的修正版本,用于测试命令行参数。
#include <stdio.h>
#include <stdlib.h>
typedef struct s_stack t_stack;
struct s_stack {
int nbr;
int top;
struct s_stack *previous;
struct s_stack *next;
};
t_stack *fusion(t_stack *p, int P, t_stack *q, int Q) {
t_stack *s;
t_stack *e;
s = NULL;
while (P > 0 && Q > 0) {
if (p->nbr <= q->nbr) {
/* select element from p list */
e = p;
p = p->next;
P--;
} else {
/* select element from q list */
e = q;
q = q->next;
Q--;
}
/* detach e */
e->previous->next = e->next;
e->next->previous = e->previous;
e->next = e->previous = e;
if (s == NULL) {
s = e;
} else {
/* insert e after s */
e->previous = s->previous;
e->next = s;
s->previous->next = e;
s->previous = e;
}
}
if (P > 0) {
/* insert p at the end of s */
if (s == NULL) {
s = p;
} else {
/* insert p after s */
e = p->previous; /* end element of p */
p->previous = s->previous;
e->next = s;
s->previous->next = p;
s->previous = e;
}
}
if (Q > 0) {
/* insert q at the end of s */
if (s == NULL) {
s = q;
} else {
/* insert q after s */
e = q->previous; /* end element of p */
q->previous = s->previous;
e->next = s;
s->previous->next = q;
s->previous = e;
}
}
return s;
}
t_stack *merge_sort(t_stack *s, int S) {
t_stack *p;
t_stack *q;
int P;
int Q;
if (S < 2) {
/* single or no elements, already sorted */
return s;
}
/* split p in 2 halves: p[0..P] and q[0..Q] */
for (q = p = s, P = 0, Q = S; P < Q; P++, Q--) {
q = q->next;
}
p = merge_sort(p, P);
q = merge_sort(q, Q);
s = fusion(p, P, q, Q);
return s;
}
t_stack *append(t_stack *s, int value) {
t_stack *e = malloc(sizeof(*e));
e->top = 0;
e->nbr = value;
e->next = e->previous = e;
if (s == NULL) {
s = e;
} else {
/* insert e after s */
e->previous = s->previous;
e->next = s;
s->previous->next = e;
s->previous = e;
}
return s;
}
void print_stack(const char *legend, t_stack *s, int S) {
printf("%s:", legend);
while (S-- > 0) {
printf(" %d", s->nbr);
s = s->next;
}
printf("\n");
fflush(stdout);
}
int main(int argc, char *argv[]) {
t_stack *s = NULL;
int S = 0;
int i;
for (i = 1; i < argc; i++) {
s = append(s, atoi(argv[i]));
S++;
}
print_stack("original stack", s, S);
s = merge_sort(s, S);
print_stack("sorted stack", s, S);
return 0;
}
我在C语言课程考试前练习一些算法问题,我被这个问题卡住了(至少3个小时甚至4个小时),我不知道如何回答: 您有两个已排序的循环单链接列表,必须合并它们并返回新循环链接列表的标题,而不创建任何新的额外节点。返回的列表也应该进行排序。 节点结构为: 我尝试了很多方法(递归和非递归),但都没有解决问题。 谢谢你的帮助。
我试图借助单链表编写合并排序,节点定义如下, 合并排序的工作方式如下: i、 将未排序的列表划分为n个子列表,每个子列表包含1个元素(1个元素的列表被视为已排序)。 二、。重复合并子列表以生成新排序的子列表,直到只剩下1个子列表。这将是排序列表。代码如下所示。 我像这样打入会电话, 结果是,所有负值似乎都消失了。这里有什么问题?
合并排序通常是对链表排序的首选方式。链表缓慢的随机访问性能使得一些其他算法(如quicksort)表现不佳,而另一些算法(如heapsort)则完全不可能。我一直在努力在链表上做归并排序。它不断返回一个错误。我正在提供我试图执行的代码。请一定要帮我。它不断给出运行时错误。
我的任务是用java实现一个循环链表(升序),但问题是它在无限循环中运行 我创建了一个节点类,其中定义了两个元素。 现在,在列表的第二个类中,我做了一个insert函数,我在start中定义了一个节点head=null,并创建了一个新的nNode。之后,我在head部分中检查,如果head==null,那么第一个元素将是nNode。插入第一个元素后,我将比较下一个元素和head元素,如果head元
我写了一个合并两个已经排序的链表的方法。然而,由于某种原因,列表的最后一个节点没有打印出来。有什么想法吗? 下面是链接列表的合并排序方法。
NowCoder 题目描述 解题思路 递归 // java public ListNode Merge(ListNode list1, ListNode list2) { if (list1 == null) return list2; if (list2 == null) return list1; if (list1.val <= lis