单链表的冒泡排序(简单易懂)

前言

大家在做需要排名的项目的时候,需要把各种数据从高到低排序,如果用的冒泡排序的话,处理数组是十分简单的,因为数组的存储空间的连续的,可以通过下标就可以简单的实现,但如果是链表的话,是随机分配的,不能像数组那样通过下标就直接实现。所以在这里给大家介绍一个简单一点的冒泡排序

冒泡排序

冒泡排序的是交换排序其中的一种,主要思想是每一个元素与后一个元素比较,若这个元素大于后一个元素,则交换这两个元素的位置(这里采用从小到大排序),第一次排序后最后一个数已经变成了最大数,再进行n-2次排序即可完成(假设有n个数据)。代码如下:

void BubbleSort(int a[],n)
{
    int i,j,temp;
    for(int i = 0;i < n - 1;i++)
    {
        for(j = i;j < n - i - 1;j++)
        {
            if(a[j] > a[j + 1])
            {
                temp = a[j];
                a[j] = a[j + 1];
                a[j + 1] = temp;
            }
        }
    }
}

但这只适用于连续存储空间,对于链表来说,不太适用,所以接下来我将介绍一个比较简单的代母来实现链表的冒泡排序,代码如下(该链表是包含有头结点的):

void BubbleSort(NODE * &L)
{
	int i,count = 0,num;//count记录链表结点的个数,num进行内层循环,
	NODE *p,*q,*tail;//创建三个指针,进行冒泡排序
	p = L;
	while(p->next != NULL)//计算出结点的个数
	{
		count++;//注释①
		p = p->next;
	}
	for(i=0;i < count - 1;i++)//外层循环,跟数组冒泡排序一样
	{
		num = count - i - 1;//记录内层循环需要的次数,跟数组冒泡排序一样,
		q=L->next;//令q指向第一个结点
		p=q->next;//令p指向后一个结点
		tail=L;//让tail始终指向q前一个结点,方便交换,也方便与进行下一步操作
		while(num--)//内层循环 次数跟数组冒泡排序一样
		{
			if(q->data > p->data)//如果该结点的值大于后一个结点,则交换
			{
				q->next=p->next;
				p->next=q;
				tail->next=p;
			}
				tail = tail->next;//注释②
				q=tail->next;//注释②
				p=q->next;//注释②
		 } 
	} 
}

注释①:
1.因为通常情况下来说,我们都不知道链表的结点个数,所以需要去计算出来做为循环的次数,如果知道的话,那也可以直接传入参数作为count。
2.为什么不直接用 p!=NULL 作为循环的次数呢,因为在交换后结点会混乱,接下来我会解释。
注释②
1.这里为什么要采用tail作为下一步操作的重要点呢,因为如果直接通过p,和q操作,很容易重复循环了,但如果通过tail进行操作的话,结点始终不会有问题
刚开始结点排序如下。
单链表的冒泡排序(简单易懂)_第1张图片
当排序完成后,进行tail = tail- >next;此时tail就是下一个结点,p和q只要按照tail的结点走,就不会出问题。
图示如下:
单链表的冒泡排序(简单易懂)_第2张图片
所以我们借用tail这个结点,就可以达到跟数组的冒泡排序一样的操作。

如果有疑问和见解,欢迎大家提出来一起分享。(新手作文,写的不太明白,见谅见谅~)

你可能感兴趣的:(单链表的冒泡排序(简单易懂))