对链表进行归并排序

主要难点在于怎么寻找链表的中间结点。

一趟遍历,寻找中间结点:设置两个指针p,q。初始时,p为第一个链表,q=L->next->next,之后的每次,p只移动一个链表,q移动两个。这就意味着,q走过的链表数是p走过的链表数的两倍。

/***Sort a linked list in O(n log n) time
 using constant space complexity.**/
#include<iostream>
#include<cstdio>
#include<cstdlib>
#define N 10
using namespace std;
typedef struct LNode
{
    int data;
    struct LNode *next;
} LinkList;
void CreateLinkList(LinkList *&L)
{
    FILE *fp;
    fp = fopen("2.txt","r");
    LinkList *s;
    L = (LinkList *)malloc(sizeof(LinkList));
    L = NULL;
    int a ;
    for(int i=0; i<N; i++)
    {
        fscanf(fp,"%d",&a);
        s=(LinkList*)malloc(sizeof(LinkList));
        s->data = a;
        s->next = L;
        L = s;
        //printf("%d\n",s->data);
    }
}
LinkList *GetMid(LinkList *L)
{
    if (L == NULL)
        return NULL;
    LinkList *p = L->next;
    LinkList *q = L;
    while(p!=NULL)
    {
        p=p->next;
        if(p!=NULL)
        {
            p=p->next;
            q = q->next;
        }
    }
    return q;
}
LinkList *MergeAll(LinkList *p1,LinkList *p2)
{
    if(p1 == NULL)
        return p2;
    if (p2==NULL)
        return p1;
    LinkList *q1 = p1;
    LinkList *q2 = p2;
    LinkList *temp=NULL;
    if(q1->data <=q2->data)
    {
        temp= q1;
        q1 = q1->next;
    }
    else
    {
        temp = q2;
        q2 = q2->next;
    }
    LinkList *newL=temp;
    while(q1&&q2)
    {
        if(q1->data<=q2->data)
        {
            temp->next = q1;
            temp = q1;
            q1 = q1->next;
        }
        else
        {
            temp->next = q2;
            temp = q2;
            q2 = q2->next;
        }
    }
    if (q1)
        temp->next = q1;
    else
        temp->next = q2;
    return newL;

}
LinkList *Merge(LinkList *L)
{
    if (L==NULL ||L->next == NULL)
        return L;
    LinkList *mid = GetMid(L);
    LinkList *low = L;
    LinkList *high = mid->next;
    mid->next = NULL;
    low = Merge(low);
    high = Merge(high);
    return MergeAll(low,high);
}
void print(LinkList *L)
{
    //L = L->next;
    while(L!=NULL)
    {
        printf("%d ",L->data);
        L = L->next;
    }
    printf("\n");
}
int main()
{
    LinkList* L;
    LinkList *newL;
    CreateLinkList(L);
    print(L);
    newL = Merge(L);
    print(newL);
    return 0;
}

 

posted @ 2018-03-21 16:59  Cheney_1016  阅读(1694)  评论(0编辑  收藏  举报