链表的归并排序

归并排序,是一种效率较高的排序,和快速排序、希尔排序、堆排序等时间复杂度一样为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);	
}
  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值