它似乎有用,但我想知道一个特定的情况是否会使我的算法崩溃。任何人都有任何隐藏的特殊情况的想法,我的程序不会涵盖? 我知道这不是排序列表的正确方法,但这是我必须要做的。
struct Student {
float medie;
char nrMatricol[10];
char *nume;
char facltate[6];
};
struct Nod{
Student stud;
Nod* next;
};
Nod* inserareNodEnd(Nod *l,Student st)
{
Nod *nou = (Nod*)malloc(sizeof(Nod));
nou->next = NULL;//NOU->NEXT=0
nou->stud = st;
if (!l) {
//lista este goala
return nou;
}
else
{
//lista contine un nod
Nod *t = l;
while (t->next) {
t = t->next;
}
t->next = nou;
return l;
}
}
Nod * interschimbare(Nod *l, Nod *pred) {
Nod *aux=l;
//Nod *auxPred = pred;
//Nod *auxPredNext =pred->next;
if (pred) {
//caz general
Nod *p, *q, *r;
pred = pred->next;
q = p->next;
r = q->next;
pred->next = q;
p->next = r;
q->next = p;
}
else {
//interschimb noduri 1 cu 2
Nod *p, *q;
p = l->next;
q = p->next;
l->next = q;
l = p;
}
return l;
}
Nod* sortareBubble(Nod* l) {
char dinNou; // flag interschimb noduri
if (!l && !l->next)
return l; //lista trebuie sa contina cel putin 2 noduri
do {
dinNou = 0; // 0 -> ipoteza fara interschimb
Nod *tmp = l, *pred = 0;
while (tmp->next) {
if (tmp->stud.medie > tmp->next->stud.medie) {
l = interschimb(l, pred);
dinNou = 1;
if (pred) {
pred = pred->next;
}
else {
pred = l;
}
}
else {
pred = tmp;
tmp = tmp->next;
}
}
} while (dinNou == 1);
return l;
}
答案 0 :(得分:1)
您再次使用dinNou
检查是否需要再次进入循环。周期为do
- while
,dinNou
初始化为0,如果发生更改,则会将其修改为1.实际上,您执行更改直到没有更改。在
while (tmp->next);
如果tmp
(已初始化为l
)恰好没有next
元素,则此内容为false。否则它将反复询问是否存在next
元素,并且由于没有变化,它将始终为真,从而导致无限循环。您认为我想要的是使用while
之后的块作为要完成的操作集while
tmp
具有next
。要实现这一点,只需删除分号:
while (tmp->next)
执行此操作后,在循环内部检查当前学生的平均分数是否大于下一分。如果是,则调用interschimbare
(交换)并将dinNou
设置为1.这似乎也是不正确的。如果必须交换两个相邻值,则应调用interschimbare
和tmp
tmp->next
。因此,您实际上不需要pred
变量,无论是否进行了交换,您都需要将tmp
设置为tmp->next
。或者甚至更好,如果发生交换,你可以打破循环。