利用归并法可以对链表进行排序,而且不需要占用额外空间.对于一个无序链表,先利用循环找到链表的中值,再利用递归先将一个链表分成两个链表,逐步递归,递归停止的条件是链表中只有一个元素或是没有元素的情况,然后完成链表的有序.
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <stack>
#include <queue>
#include <malloc.h>
using namespace std;
#define OK 1
#define ERROR -1
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef struct node *link;
struct node{
int data;//值域
link next;//指针域
};
//输出链表的函数
void Print(link head)
{
while(head != NULL)
{
printf("%d ", head->data);
head = head->next;
}
printf("\n");
}
//合并链表的函数
link Merge(link a, link b)
{
link head = (link)malloc(sizeof(struct node));
link c = head;
//如果链表a,b均不为空时,
while((a != NULL) && (b != NULL))
{
//比较大小,将小的一个连入c中
if(a->data < b->data)
{
c->next = a, c = a, a = a->next;
}
else
{
c->next = b, c = b, b = b->next;
}
}
//当其中一个链表为空时,将另一个不为空的链表整体连入c中
c->next = (a == NULL) ? b : a;
//将链表c的头结点返回
return head->next;
}
//归并排序函数
link mergeSort(link c)
{
link a = c, b = c->next;
//当链表为空,或链表中只有一个元素时,递归停止
if(a == NULL || b == NULL)
{
return c;
}
// 循环: 为了找到待归并链表的中值位置
while((b != NULL) && (b->next != NULL))
{
c = c->next;
b = b->next->next;
}
// 将b 指向中间位置.
b = c->next;
//将链表断为两部分
c->next = NULL;
//对链表的两部分进行归并
Merge(mergeSort(a), mergeSort(b));
}
int main()
{
//为链表的归并排序举一个例子
int i, n = 12;
link p, head;
//尾插法
for(i = 0; i < n; i++)
{
int num;
scanf("%d", &num);
if(i == 0)//该情况为输入链表的第一个元素
{
p = (link)malloc(sizeof(struct node));
head = p;
p->data = num;
p->next = NULL;
}
else//插入链表中除第一个元素的情况
{
link q = (link)malloc(sizeof(struct node));
q->data = num;
p->next = q;
q->next = NULL;
p = q;
}
}
//将头节点返回
head = mergeSort(head);
//输出函数
Print(head);
}