我对c中的列表进行了冒泡排序,我想知道我是否犯了任何特殊错误

时间:2017-04-01 10:42:27

标签: c sorting linked-list bubble-sort

它似乎有用,但我想知道一个特定的情况是否会使我的算法崩溃。任何人都有任何隐藏的特殊情况的想法,我的程序不会涵盖? 我知道这不是排序列表的正确方法,但这是我必须要做的。

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;

}

1 个答案:

答案 0 :(得分:1)

您再次使用dinNou检查是否需要再次进入循环。周期为do - whiledinNou初始化为0,如果发生更改,则会将其修改为1.实际上,您执行更改直到没有更改。在

处导致一个inifite循环时出错
while (tmp->next);

如果tmp(已初始化为l)恰好没有next元素,则此内容为false。否则它将反复询问是否存在next元素,并且由于没有变化,它将始终为真,从而导致无限循环。您认为我想要的是使用while之后的块作为要完成的操作集while tmp具有next。要实现这一点,只需删除分号:

while (tmp->next)

执行此操作后,在循环内部检查当前学生的平均分数是否大于下一分。如果是,则调用interschimbare(交换)并将dinNou设置为1.这似乎也是不正确的。如果必须交换两个相邻值,则应调用interschimbaretmp tmp->next。因此,您实际上不需要pred变量,无论是否进行了交换,您都需要将tmp设置为tmp->next。或者甚至更好,如果发生交换,你可以打破循环。