对链表进行归并排序
主要难点在于怎么寻找链表的中间结点。
一趟遍历,寻找中间结点:设置两个指针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; }