代码参考吴明杰老师的《手把手教你学C语言》,对于新手来说真的是一本特别特别的好书!这一段代码想了两天,下面记录一下自己的思考过程(从大到小排序)
记:需要插入到前面的节点为disorder 前面要与disorder比较的数字为order
链表内部的插入思路:链表的插入排序类似数组的插入排序但不完全一样,把一个链表中的节点插入到其他地方需要知道四个信息:disorder的前一个节点和后一个节点(因为disorder被插入到前面了,这个位置空了所以它前后节点需要连接到一起),order和order前一个节点的地址(因为disorder需要插到他们之间)
步骤:
1.同数组的插入排序,第一个节点是已经视作排序好的,故从第二个节点开始往后遍历,直到遍历到最后一个节点为止
2.每一轮排序中,disorder左边的节点与disorder比较,也就是说order必须在disorder左边,所以得到限制条件:order->next!=disorder
3.如果满足disorder大于order,则disorder节点插入到order节点之前(参照插入思路中的插入方法),插入完毕后,就结束掉这一轮比较。因为disorder左边的节点实际都是已经排序好的,即该序列中右边一定大于左边,所以没必要再与后面的数字比较
4.一轮结束后,disorder向前移动一个节点,order移回头节点,开始下一轮比较
代码如下(其他函数的代码已省略):
#include <stdio.h>
#include <stdlib.h>
struct STUDENT{
char name[20];
int score;
};
struct NODE{
struct STUDENT data;
struct NODE * next;
};
struct NODE * CreateLink(void);
void Init(struct NODE * head);
void OutputLink(struct NODE * head);
void InsertBack(struct NODE * head);
void InsertFront(struct NODE * head);
void BubbleSort(struct NODE * head);
void InsertSort(struct NODE * head);
int main(void){
struct NODE * head = NULL;
head = CreateLink();
Init(head);
OutputLink(head);
printf("\n排序中:");
//BubbleSort(head);
//InsertBack(head);
//InsertFront(head);
InsertSort(head);
OutputLink(head);
return 0;
}
void InsertSort(struct NODE * head){
struct NODE * disorder = head->next->next;
struct NODE * order = head;
struct NODE * front = head->next;
struct NODE * back = NULL;
while(disorder != NULL){
while(order->next != disorder){
if(disorder->data.score > order->next->data.score){
back = disorder->next;
disorder->next = order->next;
order->next = disorder;
front->next = back;
disorder = front;
break;
}
order = order->next;
}
front = disorder;
disorder = disorder->next;
order = head;
}
}