节点值交换法:
设置两个链表指针p、q,第一个用来指向头结点后一个(head->next)(每次内层循环结束,则往后移动),第二个用来继承当前p节点后一个(p ->next),在内层循环中不断往后移动,期间满足交换条件则交换,直至排序完毕。实际上与用指针做冒泡排序时一样。
下图几个大步骤展示了排序过程,这里用数组(5、4、3、2、1)做为例子(图中p、q 是链表指针):
综上所述,我们可以写出冒泡排序代码:
struct bubbleSort { int data; struct bubbleSort * next; }; /* * 初始条件:已创建链表bubbleSort * 设置两个链表指针 bubbleSort *p, *q */ void BubbleSort(bubbleSort * head) { for(p = head -> next; p != NULL; p = p -> next) for(q = p -> next; q != NULL; q = q -> next) if((p -> data) > (q -> data)) int s = q -> data, q -> data = p -> data, p -> data = s; }
# 2017 10.7 16:55:54
交换节点法:
最近看到有关链表的冒泡排序除了交换值的方法还有一种交换节点的方法...实际上,感觉和链表的反转有几分相似,于是想了一会写了一下,但还是有问题,于是还是借鉴了别人的实现方法。
先解释一下实现交换节点的重要代码部分:
比如,排序5个数:{5,4,3,2,1}。
p = head;
q = head -> next;
p->next = q->next;
q->next = q->next->next;
p->next->next = q;
q = p->next;
从上面第5行开始解释:
第5行:把头节点的后一个(数据5节点)指向数据5节点的后一个(数据4节点)。
第6行:接着把数据5节点的后一个指向数据4节点的后一个(数据3节点)。
第7行:再把数据5的节点接到数据4节点的后面,上一行已经把数据3节点接到了数据5节点的后面了,所以,这样数据5节点就插进了数据4节点和数据3节点之间,数据3节点的位置又回到了原来的位置。
第8行:最后q = p->next;是什么意思呢?我们看一下第5行知道p->next已经变为了q->next; 中间p->next也没有其他的变化,所以我们可以理解为最开始的数据5的节点变为了数据4的节点,向后移动了一个。实际上是重新将指针指向第一个节点,向前移动了一个。
这里链表中的节点就变为了 4->5->3->2->1.
然后判断完后面还有两句:
q = q->next;
p = p->next;
这两句的意思是使链表往后移动,不管前一个和后一个是否进行了交换都应该往后移动,以使后面需要的交换的节点也能正常进行。
然后给一个别人的节点交换的正确代码地址:点击(•̀ᴗ•́)و ̑̑。
这篇也就解释一下具体实现的思路和原理,解释不对还请指出错误,解释太长也不好,太短如果看不懂,还是看代码多理解吧(•̀ᴗ•́)و ̑̑。
# 2017 10.8 00:06:10
code:
void BubbleSort(struct Node * head)
{
struct Node * p, * q, * tail;
tail = NULL;
while((head->next->next) != tail)
{
p = head;
q = head->next;
while(q->next != tail)
{
if((q->val) > (q->next->val))
{
p->next = q->next;
q->next = q->next->next;
p->next->next = q;
q = p->next;
}
q = q->next;
p = p->next;
}
tail = q;
}
}