单链表进行归并排序

来源:互联网 发布:剑三明教脸型数据 编辑:程序博客网 时间:2024/04/27 22:43
    对单链表进行归并排序:首先设置两个指针slow和fast,slow指针每次走一步,fast指针每次走两步,当fast指向末尾元素或者指向空时,slow指针刚好走到链表的中间位置,此时slow指针恰好把链表分为左右两部分,slow->next指针指向第二部分的首部,然后我们递归的对两部分进行划分操作,最后划分到两部分都只有一个元素时,我们对其进行合并操作,然后依次递归的向上进行归并操作。时间复杂度为o(nlogn)。
//对单向链表进行归并排序#include<iostream>#include<random>using namespace std;//链表数据结构struct ListNode{int val;ListNode *next;ListNode(int v) :val(v){}ListNode(){}};//在链表末尾追加元素void appendTail(ListNode **pHead, int val){ListNode *pNew = new ListNode;pNew->next = NULL;pNew->val = val;if (*pHead == NULL){*pHead = pNew;}else{ListNode *tmp = *pHead;while (tmp->next){tmp = tmp->next;}tmp->next = pNew;}}//正序输出链表void show(ListNode *pHead){int num = 0;while (pHead){if ((num % 10) == 0 && num != 0)cout << endl;cout << pHead->val << " ";pHead = pHead->next;num++;}cout << endl;}//合并两个有序的链表ListNode *merge(ListNode *h1, ListNode *h2){//设置一个头指针ListNode *head = new ListNode(INT_MIN);ListNode *p = head;//两个链表都不为空while (h1 != NULL && h2 != NULL){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;}return head->next;}//归并排序链表ListNode* sortList(ListNode* head) {if (head == NULL || head->next == NULL)return head;ListNode *slow = head;//指向链表的中间位置ListNode *fast = head->next;while (fast != NULL && fast->next != NULL){slow = slow->next;fast = fast->next->next;}//对链表的后半部分进行归并排序ListNode *h1 = sortList(slow->next);slow->next = NULL;//对链表的前半部分进行归并排序return merge(sortList(head), h1);}int main(){ListNode *pHead = NULL;for (int i = 1; i <= 100; ++i){appendTail(&pHead, rand() % 90 + 10);}ListNode *p = sortList(pHead);show(p);system("pause");return 0;}
对10到99之间的100个数进行归并排序的结果如下:
0 0