单链表的冒泡排序
设置三个指针tail,p,cur;p和tail用于控制外循环的次数,cur用于内循环。
- 排序开始前遍历一次单链表将tail指向尾结点的指针域,即NULL。cur和p均指向头结点。
- 比较cur->data与cur->next->data的大小,若前者大于后者则交换;否则不交换,之后cur指针右移,继续比较cur->data与cur->next->data的大小,直至cur->next==tail。
- 一次循环之后,将tail指向cur的位置,即相当于tail前移。将cur重新指向头结点,重复步骤2。
- 直至p->next==tail结束整个循环。
由于需要被冒泡排序的链表不一定十分杂乱无序,有可能经过s少量几次循环后就会有序,不需要经过大量的循环,所以为了减少循环次数,设置一个变量flag,flag初始值为0,若在某一次循环中有元素与元素间的交换,flag变为1,如果没有元素的交换,证明这次循环单链表已经有序,flag不变,依旧为0。没经历一次循环判断flag的大小是否为0,若为0,直接跳出整个循环。
#define DataType int
typedef struct Node{
DataType data;
struct Node* next;
}linklist;
void LinkListBubblesort(linklist *head)
{
linklist *cur = head;
linklist *tail = head;
linklist *p = head;
DataType node = 0;
int length = 0;
int flag = 0;
//尾结点,tail指向空
while (tail != NULL)
{
tail = tail->next;
}
//外循环,循环链表长度-1次
while (p->next!=tail)
{
flag = 0;
cur = head;
while (cur->next != tail)
{
if (cur->data > cur->next->data)
{
//前后交换
node = cur->data;
cur->data = cur->next->data;
cur->next->data = node;
flag = 1;
}
cur = cur->next;
}
//尾指针向前移动
tail = cur;
//若为1,则证明链表已经有序
if (flag == 0)
{
return;
}
}
}