使用快慢指针对链表里按内容大小排序:源代码如下:
#include<stdio.h>
#include<stdlib.h>
typedef struct student
{
int num;
struct student *next;
}Node;
typedef struct student *Link;
Link SortedMerge(Link a, Link b);
void FrontBackSplit(Link source,Link* frontRef, Link* backRef);
void MergeSort(Link* headRef);
/* 分割一个链表为两部分,通过指针返回结果,使用快慢指针 */
void FrontBackSplit(Link source,Link* frontRef, Link* backRef)
{
Link fast = source->next;
//Link fast = source;
Link slow = source;
if(source == NULL||source->next == NULL)
{
*frontRef = source;
*backRef = NULL;
}
else
{
while(fast != NULL)
{
fast = fast->next;
if(fast != NULL)
{
fast = fast->next;
slow = slow->next;
}
}
*frontRef = source;
*backRef = slow->next;
slow->next = NULL;
}
}
/* 合并两个已排序链表 */
Link SortedMerge(Link a, Link b)
{
Link result = NULL;
if(a == NULL)
{
return b;
}
if(b == NULL)
{
return a;
}
/* 使用递归调用的方法 */
if((a->num) >= (b->num))
{
result = a;
result->next = SortedMerge(a->next,b);
}
else
{
result = b;
result->next = SortedMerge(a,b->next);
}
return result;
}
/* 通过递归实现链表排序,如(传入p:11->5->2->3->22->13的链表,第一次调用,将链表分为a:11->5->2和,b:3->22->13两个链表,
先对a再调用此函数,将a再分为a1:11,b1:5->2两个链表,a1再调用此函数直接返回11这个链表,b1调用此函数又分为a2: 5和b2: 2两个链表,
对a2,b2排序,返回到b1:2->5;再对a1,b1排序,返回到a:2->5->11,同理对b调用此函数得到返回的b:3->13->22,再对a和b排序得到返回的p:2->3->5->11->13->22)。
以上为实现思路,函数实际执行并不按上述执行。但最终效果相同 */
void MergeSort(Link* headRef)
{
Link head = *headRef;
Link a;
Link b;
if((head == NULL) || (head->next == NULL))
{
return;
}
/* 分割链表为 'a' 和 'b' 两个子链表 */
FrontBackSplit(head,&a,&b);
MergeSort(&a);
MergeSort(&b);
/* 合并两个有序链表到新链表,记下头指针 */
*headRef = SortedMerge(a,b);
}
void creat_link(Link * head)
{
*head=NULL;
}
void insert_node(Link *head,Link *new_node)
{
(*new_node)->next = *head;
*head = *new_node;
}
void display(Link *head)
{
Link temp = *head;
while(temp != NULL)
{
printf("%d\n",temp->num);
temp = temp->next;
}
}
int main()
{
Link head;
Link new_node;
int i;
srand((unsigned)time(NULL));//根据系统时间产生种子
creat_link(&head);
for(i = 7;i > 0;i --)
{
new_node = (Link)malloc(sizeof(Node));
new_node->num = rand() % 100;//获取1到99的整数
insert_node(&head,&new_node);
}
display(&head);
printf(".........\n");
MergeSort(&head);//对head进行从小到大排序
display(&head);
return 0;
}
编译及运行结果如下:
[root@bogon 0729]# gcc sort.c &&./a.out
6
20
42
22
35
87
13
.........
87
42
35
22
20
13
6