考研王道大题第二章第六题,使无序的链表有序
考研 王道数据数据结构课后习题第二章第六道
6.有一个带头节点的单链表L,设计一个算法使其元素递增有序
void Sort(LinkList &L){
//本算法实现将单链表L的节点重新排序,使其递增有序
//本算法的思想如下
//定义工作指针
//LNode *p=L->next,r=p-next;
//LNode pre=L;
//p=NULL; 断链;
//p=r; p和r指向数据链表的第一个节点 pre指向被插链表的头节点(初始时被插节点只有初始链表的头节点和第一个节点)
//p为数据链表的标记及第一个节点的指针,r为p的直接后继节点的指针,防止在p进行插入操作后,数据链表的丢失
//其实在p进行插入操作后,r就是新的数据链表的头节点
//然后插入完成后将r的值赋给p,p指向新的数据链表的头节点,方便进行下一次的数据链表的头节点的插入操作
//外层循环
//外层循环判断条件 如果数据链表中的节点没被插完,就继续插节点,即执行
//{
/* 内层循环 //完成被插入链表中插入位置的判断
//当被插链表中的pre->next->data小于数据链的头节点值(p->data)时
//pre向 被插入链表 做遍历,直到找到 被插入链表中第一个比数据链头节点大的值
pre=pre->next;
//或者直到遍历完 被插入链表 即p=NULL 也没有找到比头节点的值p->data大的 被插入链表中的节点,只能插在被插入链表的最后,
//这时pre=NULL;
*/ //内存循环结束,即判断好了插入位置 若pre-next!=NULL插入位置为pre之后,pre-next之前 若pre==NULL插入位置为pre之后也就是被插入链表的末尾
//p->next=pre-next;//执行插入操作还是先右后左的原则
//pre->next=p;
//p=r; //然后插入完成后将r的值赋给p,p指向新的数据链表的头节点,方便进行下一次的数据链表的头节点的插入操作
//} //外层循环完毕
//如何保证有序?
//由于第一次向被查链表中插节点时,被插入链表中只含有头节点(不含数据)和初始链表的第一个节点,所以,
//所以第一次遍历前,被查链表中只有一个有效的节点
//在第一次执行遍历完的时候就是有序的
//然后每次执行遍历都将有序
//从而保证最后是有序的
//思想就是,方向是对的,每步都没错,那么结果肯定没错。
//算法正式开始
LNode *p = L->next,*pre;
LNode *r=p->next; //p和r为数据链表工作指针
//pre是又当爹又当妈的被插入链表的工作指针,在被插入链表中,既做插入位置的标记指针又做插入操作之前的控制比较指针
//pre相当于插入操作的p(插入操作指针) pre->next相当于插入操作的q(比较指针)
//而被插入链表和数据链表的定义在下一段的解释说明中
//在本函数的变量定义阶段,共定义了三个指针变量 分别为pre/p/r 注意回收指针,防止出现悬垂指针
p->next=NULL; //头节点和第一个节点与之后的链表进行断链操作
//现在有两个链表
//至此,头节点和第一个节点相连为被插入链, 第二个节点和剩下的节点相连为数据链
p=r;//p和r指向第二个节点
printf("本算法实现将单链表L的节点重新排序,使其递增有序");
while(p){ //当数据链不为空,则排序未完成
r=p->next;
pre=L; //注意每次循环pre都置在头节点,也就是完成一次插入后pre位置清零
//从(被插入链表)头到尾再来while循环
while(pre->next&&pre->next->data<p->data){ //在被插入链中找到pre->next->data 刚好比 数据链中第一个节点的值大时,
//将数据链的第一个节点插到pre的后边,也就是pre->next的前边
//因为pre->next->data刚好比数据链的头节点的值要大即p->data
//如果pre到了被插入链表中的最后一个节点(即pre->next==NULL),
//那么就将数据链中的头节点插入到被插入链的最后一个节点之后
//pre从数据链的头比 如果找到了比数据节点中p->data值大的节点
//就是(pre->next-data)
//就插到pre的后边
pre=pre->next;
}
//比较完成后,开始进行被插入链表的插入操作
p->next=pre->next; //还是先右后左向被插入链表的合适的位置插入数据链表的头节点
pre->next=p;
p=r; //将p再次放在被删除头节点的数据链表的头节点上
}
//回收pre/p/r指针,防止出现野指针,即悬垂指针
pre=NULL;
p=NULL;
r=NULL;
}
// void Sort(LinkList &L)函数结束
////////////////////////////