链表冒泡排序总结(两种方法,第二种更简单)

在大一上学期,我们学了冒泡排序,选择排序,插入排序等等,而今天主要详解一下链表的冒泡排序的问题。(边看代码,边讲解)
首先,回顾一下,什么叫做冒泡排序。冒泡排序是一种时间复杂度在n的平方下的排序;每次循环都是比较前后两项,要么以从小到大排序,要么从大到小排序。

第一种:

 struct node *bubblesort(struct node *headptr)//接受头指针,链表的开端,首节点不为空的链表
	struct node *pre=NULL,*flag=NULL,*head=*headptr,*temp;//pre代表前一个指针,flag用作循环变量,很重要
	int num;//循环变量
	while(*head!=flag)
	{
		num=0;
		while(*(head->nextptr)!=flag){
		if(*head->num<*(head->nextptr)->num{//循环比较相邻两个的大小,按从大到小的排序
			*temp=*(head->nextptr);//将所指向的第二指针头存储
			*(head->nextptr)=*(head->nextptr->nextptr);//将第三指针头接在第一指针头的后面
			*temp->nextptr=*head;//将第一指针头放在第二指针的后面
			if(num>0)//便于将pre时候是空指针给分开
			*pre->nextptr=*temp;
			*pre=*temp;//移动pre,向后移一位
			if(num==0)//若是头指针,将改变headptr,链表的头指针
			*headptr=*temp;
		}
		else{//若不满足大小关系。两者都往移一位
			*pre=*head;
			*head=*(head->nextptr);
			}
			num++;//方便pre的问题
		}
		*flag=*head;将flag每次都往前移一位,使次数尽量保证少
		*head=*headptr;//将head重新改为headptr链表头
	}
return *headptr;//返回排好序的链表

第二种

struct node *bubblesort(struct node *head)//首节点为空的链表
{
	struct node *pre,p,*tail,*headptr=*head;;
	*tail=NULL;//循环变量
	while(*headptr!=*tail)//控制循环变量
	{
		*pre=*headptr;//前指针的赋值
		*p=*(headptr->nextptr);
		while(*(p->nextptr)!=*tail)
		{
			if(p->num<p->nextptr->num){//前一个小于后一个
				pre->nextptr=p->nextptr;
				p->nextptr=p->nextptr->nextptr;
				pre->nextptr->nextptr=p;//这个地方我觉得很好
			}
			else{
				*p=*(p->nextptr);
				*pre=*(pre->nextptr);
			}
		}
		*tail=*p;//将结束指针往前移一位
}
return *headptr;//返回排好序的链表

总结:两者稍有不同,但是最关键的地方都是循环的条件的控制;第一种在head!=flag的条件下运行,而第二个其实是一样的,认识清楚链表的指针改变很为重要,不然很可能出现
运行时的的错误。在本代码中,我觉得pre->nextptr-nextptr是一个非常好的地方,毕竟链表是一个类似于许多长条磁体连在一起的模型,抓住一个节点,可以往前或者往后表示其他的节点。

猜你喜欢

转载自blog.csdn.net/qq_44116998/article/details/89040448