C 双向链表的简单排序实现

今天偶尔看到了C结构体的单项链表。

于是重新温习了下双向链表,重写了下双向链表的简单排序实现,当做温习总结吧。

先定义双向链表

1 struct Student{
2     int studentId;
3     char * name;
4     Student *next, *last;
5 };

然后就是关键的排序方法:

int sortByName(Student *p){
    Student *head = p;
    //从链表头部开始排序(也可以去掉,去掉的话就是从传入的节点开始排序)
    while(head->last != NULL){
        head = head->last;
    }
    while(head != NULL){
        Student *headNext = head->next;
        while(headNext != NULL){
            if(strcmp(head->name, headNext->name) > 0){
                swapStudent(head, headNext);
                //注意这里一定要交换下,因为改了链表节点的位置
                Student *tmp = head;
                head = headNext;
                headNext = tmp;
            }
            headNext = headNext->next;
        }
        head = head->next;
    }
    return 1;
}

里面又涉及到一个swapStudent方法,这个方法实现交换两个节点的功能

代码如下:

void swapStudent(Student *s1, Student *s2){
    if(s1->next == s2){
        if(s2->next != NULL){
            s2->next->last = s1;
        }
        if(s1->last != NULL){
            s1->last->next = s2;
        }
        s1->next = s2->next;
        s2->last = s1->last;
        s1->last = s2;
        s2->next = s1;
    }else if(s1->last == s2){
        if(s1->next != NULL){
            s1->next->last = s2;
        }
        if(s2->last != NULL){
            s2->last->next = s1;
        }
        s2->next = s1->next;
        s1->last = s2->last;
        s2->last = s1;
        s1->next = s2;
    }else{
        //这里面一定要注意更新节点相邻节点里面的上下节点的值
        //我被坑在这,查了好久才查出来
        //上面两个循环体也一样需要注意
        if(s1->next != NULL){
            s1->next->last = s2;
        }
        if(s1->last != NULL){
            s1->last->next = s2;
        }
        if(s2->next != NULL){
            s2->next->last = s1;
        }
        if(s2->last != NULL){
            s2->last->next = s1;
        }
        Student *s1Next = s1->next;
        Student *s1last = s1->last;
        s1->next = s2->next;
        s1->last = s2->last;
        s2->next = s1Next;
        s2->last = s1last;
    }
}

上面就是简单排序实现的核心实现。

如果仔细看了的话,会注意一个问题。

如果使用冒泡排序,上面的swap方法可以实现的简单一点,因为只会交换相邻的两个节点。

我这样写就是要更一般化,对节点操作要求更高,利于自己理解。

原文地址:https://www.cnblogs.com/bokezhilu/p/7620181.html