设计思想:
相对于数据结构为数组的插入排序方法,现在要解决的是如何实现链表中的插入排序。数组的存储方式是顺序存储,而链表的存储方式是链式存储。所以,要实现针对链表的插入排序法,其关键是解决如何能够保证链表不发生断链的情况。
首先,我们先考虑在链表中只有两个结点——也就是只有头结点和尾结点的情况:
令 p1 指向头结点, p2 指向尾结点
如果 p1 指向的结点与 p2 指向的结点已经是有序(此处指的是按设计人员的设计升序或者降序排列)的,那么,则不作任何操作,排序完成。否则,则应对相对的指针进行操作,令链表变成有序的。
此时:
令 head 等于 p2
令 p2->next 等于 p1
令 p1->next 等于 NULL
下面来考虑多于两个结点的实现方式
假设现在有一个六个结点的链表,其中 p1 、 p2 所指向的节点分别为头结点以及第二个结点,而且已经是有序排列。此时,定义两个指针 p3 、 p4 用于查找结点,其中 p4 为查找用指针, p3 为 p4 的前驱,用于插入结点时连接链表用。再设置两个指针 p5 、 p6 指向 p2 的下一个结点。
现分析一下其中的作用:
p1 与 p2 用于确定头结点与尾结点的位置
p3 与 p4 用于查找有序链表中应该插入的位置
p5 用于指向所要插入结点的地址,确定 p5 插入后 p6 用于指向下一个结点以保证链表仍然能够正确的连接上。
这时候有三种情况:
如果 p5 所指向的结点应该作为头结点
令 p6 指向下一个结点
p5 指向 p1 , head 指向 p5
再令 p1 等于 p5 , p2->next=p6
此时,可以发现,在链表中其中一个结点已经进行了插入法排序,此时链表中有序的结点增加到 3 个。此时,再令 p1 等于头结点, p5 等于 p6 , p3 等于 p1 , p4 等于 p1->next 。
如果 p5 应该插入到链表中间。
那么,应该确定 p5 所指向结点要插入的位置,再令 p6 指向下一个结点
接着令 p5->next=p4 , p3-next=p5 实现插入。
最后,令 p2->next=p6 ,重新实现链表的连接。
再令 p5=p6 ,进行下一个结点的排序。
最后,当结点要作为已排序的链表的最后一个结点时,直接令 p2=p5 即可。
依次将各个结点利用插入法加入到链表中,直到 p2->next=p6=NULL 为止。