快慢指针应用(二)——链表排序

使用快慢指针对链表里按内容大小排序:源代码如下:

#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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值