20170514_对单链表排序

来源:互联网 发布:淘宝买东西警察还查吗 编辑:程序博客网 时间:2024/06/07 06:29

20170514_对单链表排序

归并排序算法



//148. Sort List /** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */#include<iostream>#include<vector>using namespace std;//单链表节点struct ListNode{int val;ListNode *next;ListNode(int x):val(x),next(NULL) {}};//尾插法建立一个单链表ListNode *CreatList(ListNode * &root, vector<int> &a){int n=a.size();if(n==0)return root;else{root=new ListNode(a[0]);ListNode *r=root;for(int i=1; i<n; ++i){ListNode *s=new ListNode(a[i]);r->next=s;r=s;}return root;}}//顺序输出一个单链表void OutList(ListNode *root){ListNode *p=root;while(p!=NULL){if(p->next!=NULL)cout<<p->val<<",";elsecout<<p->val;p=p->next;}cout<<endl;}//单链表逆置ListNode *ConvertList(ListNode *root){if(root==NULL || root->next==NULL)return root;else{ListNode *pcur=root;ListNode *qnext=pcur->next;pcur->next=NULL;while(qnext!=NULL){root=qnext;ListNode *qq=qnext->next;qnext->next=pcur;pcur=qnext;qnext=qq;}return root;}}//Sort a linked list in O(n log n) time using constant space complexity.class Solution{public://3、归并排序    ListNode *sortList(ListNode *head){        if (!head || !head->next)            return head;        return  mergesort(head);    }//2、一趟归并排序ListNode *mergesort(ListNode *head){        if (head == NULL || head->next == NULL)  //节点为空或者就一个节点了,直接返回            return head;        ListNode *fast=head;//快慢指针的应用!        ListNode *slow=head;        while(fast->next != NULL && fast->next->next != NULL)  //后续至少还有两个节点,则一共三个节点,再继续分割;{                                                      //否则,就意味着就剩两个节点了,直接可以排序了。            fast=fast->next->next;    //快指针每次走两步            slow=slow->next;          // 慢指针每次走一步        }                             //故:快指针到结尾处时,慢指针正好在中间位置。        ListNode *head2=slow->next;   //右侧的新序列的第一个节点        slow->next=NULL;              //截断左侧序列        ListNode *head1=head;         //左侧的新序列的第一个节点        head1=mergesort(head1);      //递归地对左半部分进行归并排序        head2=mergesort(head2);      //递归地对右半部分进行归并排序        return merge(head1,head2);   //head1 和 head2 已经是有序的了!    }//1、对已经有序的两个单链表进行 一次归并    ListNode *merge(ListNode *h1, ListNode *h2){        ListNode *temp=new ListNode(0);        ListNode *p=temp;        while(h1 && h2)     //对两个单链表进行合并{            if(h1->val <= h2->val){                p->next=h1;                h1=h1->next;            }else{                p->next=h2;                h2=h2->next;                         }            p=p->next;                      }        if (h1!=NULL) p->next=h1;        if (h2!=NULL) p->next=h2;        p=temp->next;        temp->next=NULL;        delete temp;        return p;    }};int main(){vector<int> a;int ch;cout<<"依次输入单链表节点数据:"<<endl;while(cin>>ch)a.push_back(ch);ListNode *r;ListNode *root=CreatList(r,a);cout<<"单链表建立完成."<<endl;cout<<"顺序输出单链表:"<<endl;OutList(root);cout<<"顺序输出单链表完成."<<endl;//cout<<"逆置该单链表:"<<endl;//ListNode *root2=ConvertList(root);//cout<<"输出逆置后的单链表:"<<endl;//OutList(root2);//cout<<"逆置后的单链表输出完成."<<endl;Solution example;root=example.sortList(root);OutList(root);system("pause");return 0;}// 思路://因为题目要求复杂度为O(nlogn),故可以考虑归并排序的思想。//归并排序的一般步骤为://1)将待排序数组(链表)取中点并一分为二;//2)递归地对左半部分进行归并排序;//3)递归地对右半部分进行归并排序;//4)将两个半部分进行合并(merge),得到结果。////所以对应此题目,可以划分为三个小问题://1)找到链表中点 (快慢指针思路,快指针一次走两步,慢指针一次走一步,快指针在链表末尾时,慢指针恰好在链表中点);//2)写出merge函数,即如何合并链表。 (见merge-two-sorted-lists 一题解析)//3)写出mergesort函数,实现上述步骤。 


0 0
原创粉丝点击