归并排序,是一种效率较高的排序,和快速排序、希尔排序、堆排序等时间复杂度一样为O(nlog n),且它是一种稳定的排序。
大体思想是先归,把数据分组,比较之后再并。这种重复的分、和,十分适用递归的思想。
例子,4,3,6,2,8,3,0
1. 将4,3,6,2分为一组,8,3,0分为一组
2.继续分 4,3 ; 6,2 ; 8,3 ; 0
3.继续分 4 ; 3 ; 6 ; 2 ; 8 ; 3 ; 0
3,有序合并 3,4 ; 2,6 ; 3,8 ; 0
4.合并 2,3,4,6 ; 0,3,8
5.合并 0,2,3,3,4,6,8
大致的过程就是这样。
在很多笔试考试题中,有要求用链表实现归并排序。
其实也差不多。
#include<iostream>
using namespace std;
class ListNode {
public:
int val;
ListNode *next;
ListNode(int val) {
this->val = val;
this->next = NULL;
}
};
ListNode *get(ListNode *head,int i){
// 得到链表第几个元素的地址
ListNode *result=head;
for(int j=0;j<i;j++)
result=result->next;
return result;
}
int len(ListNode *head){
//得到链表的长度
int len=0;
while(head!=NULL){
len++;
head=head->next;
}
return len;
}
void print_node(ListNode *head){
//输出链表
while(head!=NULL){
cout<<head->val<<" ";
head=head->next;
}
cout<<endl;
}
ListNode *mergeList(ListNode *l1,ListNode *l2,ListNode *result){
//合并两个有序链表
if(l1==NULL) return l2;
if(l2==NULL) return l1;
if(l1->val > l2->val){
result=l2;
l2=l2->next;
}
else{
result=l1;
l1=l1->next;
}
ListNode *re=result;
while(l1!=NULL && l2!=NULL){
if(l1->val > l2->val){
re->next=l2;
re=re->next;
l2=l2->next;
}
else{
re->next=l1;
re=re->next;
l1=l1->next;
}
}
if(l1==NULL)
re->next=l2;
else
re->next=l1;
return result;
}
ListNode *mergeSort(ListNode *head,int start,int end,ListNode *result){
int mid=(start+end)/2;
if(start == end) return head;
ListNode *s=get(head,start);
ListNode *m=get(head,mid);
ListNode *e=m->next; //将第mid个节点打断
m->next=NULL;
ListNode *part1=mergeSort(s,0,len(s)-1,result);
ListNode *part2=mergeSort(e,0,len(e)-1,result);
return mergeList(part1,part2,result);
}
ListNode *sortList(ListNode *head) {
// write your code here
ListNode *p=head;
ListNode *result;
result=mergeSort(head,0,len(head)-1,result);
return result;
}
int main() {
int a[]={0,1,2,3,2,5,6,4,8,13,10};
ListNode *l1,*p;
l1=new ListNode(a[0]);
p=l1;
for(int i=1;i<(sizeof(a)/sizeof(int));i++){
ListNode *temp=new ListNode(a[i]);
p->next=temp;
p=p->next;
}
ListNode *result=sortList(l1);
print_node(result);
}