冒泡排序在单链表中的使用详解

冒泡排序是一种基础而又简单的排序方法,它能够很好地锻炼新手思维能力,同样地,在链表的冒泡排序中,它能够锻炼我们链表的熟悉使用和对链表数据的处理方法。

在对单链表进行冒泡排序之前,我们得先掌握三个基础知识。

冒泡排序

冒泡排序的基本方法是通过两两比较,每一趟比较中都会把一个较大的数往后移。

例如:一组数:5,4,3,2,1 从小到大排序

    第一趟比较中:先对第一个数5和4对比,然后5>4,那么数据交换,然后对第二个数5对第三个数3进行对比,5>3,数据交换,一直这样对比下去,直到这组数据中

    5移到了最后一位,即这组数变为:4,3,2,1,5;

    然后我们在重复第一趟的步骤,依次比较,然后就把4移到了5的前面;变成3,2,1,4,5;

    依次重复(5-1)次

    ....................

    最后变为了:1,2,3,4,5;

    循环分析:对于i个数,我们要进行(i-1)趟比较,然后每一趟循环中,我们实际只需要进行(j-i-1)次比较,因为我们第一趟把5移到最后,我们知道了5是这组数据中的

    最大值,然后第二趟循环中我们就不用和5进行比较,依次类推下去。

    具体的代码不是本文的重点,网上有很多相关的案例,可以去搜搜。


链表节点的交换

冒泡排序的过程,实际上也是交换的过程,只不过在链表中我们交换的不是数据而是节点,虽然同样可以通过交换数据的方式达到冒泡的结果,但如果节点中的数据非

多时,效率就会变得非常低,况且这种实现方式并不能带给我们知识上的帮助。所以我们来看看链表节点的交换。

NODE* swap(NODE* head){
	NODE *p,*q;
	int data;
	scanf("%d",&data);
	p=q=head;
	while(p->next!=NULL){
		if(p->data==data){
			if(p==head)head=p->next; //头指针变为下一个节点 
			else q->next=p->next; //(1)
			q=q->next;//(2)
			p->next=q->next;//(3)
			q->next=p;
			break;
		}
		q=p;	//q指针在p指针前面 
		p=p->next; //p指针后移 
	}
	return head;
} 
具体的链表交换图如下:


当然,这个函数并没有包含输入尾节点时的交换,因为我们每一次比较的时候都是和下一个数进行对比,当我们输入倒数第二个数的时候就已经和最后一个数进行对

比交换了。如果链表不熟悉的话,建议大家画图分析。



●冒泡排序在链表中的实现

其实如果懂得上面两种知识之后,就可以很容易实现了,我们只需要获取了数据的总数量之后,然后在循环中进行节点的数据的判断并进行交换即可,实现方法如下:

NODE* maopao(NODE* head){
	NODE *p,*q;
	int num=0,j=0;
	q=head;
	//获取链表的长度 
	while(q!=NULL){
		q=q->next;
		num++;
	}
	//冒泡排序的基本思路 
	for(int i=0;i<num-1;i++)
		{
			p=q=head; 
			j=num-i-1; //减少每一趟循环中两两比较的次数 
			while(p->next!=NULL&&j!=0){
				j--;
				if(p->data>p->next->data){
					//节点的交换 
					if(p==head) head=p->next;
					else q->next=p->next;
					q->next=p->next;
					q=q->next;
					p->next=q->next;
					q->next=p;
					//执行完上面的过程后,为了能够让p顺利地执行移动到交换后的下一位 . 
					p=q; 
				}
				q=p; //为了能让q保持在p的前面 
				p=p->next; //p指针后移,即p变成了在q的前面 
			}
		}
	return head;
} 


如果有疑问或者意见欢迎大家留言提出,表诉可能不太好,望谅解。


  • 21
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值