考研王道大题第二章第六题,使无序的链表有序

考研 王道数据数据结构课后习题第二章第六道
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->datadata){		//在被插入链中找到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)函数结束
	

考研王道大题第二章第六题,使无序的链表有序_第1张图片

你可能感兴趣的:(数据结构)