指针实现时间复杂度为O(n*logN)的排序算法(归并排序算法)

Posted 时间的女儿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了指针实现时间复杂度为O(n*logN)的排序算法(归并排序算法)相关的知识,希望对你有一定的参考价值。

归并排序

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     ListNode* sortList(ListNode* head) {
12         //排序算法 空间复杂度N*logN
13         //归并排序
14         if(!head||!(head->next)){
15             return head;
16         }
17         ListNode* slow = head;
18         //让slow比最终的位置慢一步
19         ListNode* fast = head->next;
20         ListNode* temp;
21         while(fast&&(fast->next)){
22             if(fast->next->next){
23                 slow = slow->next;
24                 fast = fast->next->next;
25             }else{
26                 //slow = slow->next;
27                 fast = fast->next;
28             }
29             
30         }
31         //将前半段的与后半段分开
32         temp = slow;
33         slow = slow->next;
34         temp->next = NULL;
35        // return head;
36         return Merge(sortList(head),sortList(slow));
37     }
38     ListNode* Merge(ListNode* L1,ListNode* L2){
39         ListNode cur(0);
40         ListNode* temp = &cur;
41         while(L1&&L2){
42             if((L1->val)<=(L2->val)){
43                 temp->next = L1;
44                 L1 = L1->next;
45             }else if((L1->val)>(L2->val)){
46                 temp->next = L2;
47                 L2 = L2->next;
48             }
49             temp = temp->next;
50         }
51         if(L1){
52             temp->next = L1;
53         }else{
54             temp->next = L2;
55         }
56         return cur.next;
57     }
58 };

 

实现过程

    归并排序算法:

1、首先将链表进行切分。在我们的算法中,使用两个指针fast和slow,fast的遍历速度是slow指针的两倍。所以当fast遍历到链表的末尾时,slow恰好找到了链表的最中间位置,(这是使用链表存储相对于数组比较麻烦的地方,没办法直接选取最中间的值)。

2、使用head和slow将链表分成两个子链表,然后继续1中操作,将子链表再分成两部分。直到每个子链表只含有一个元素为止

3、然后我们将两个子链表进行合并,生成含有2个元素排好序的链表,再将含有2个元素的子链表合并生成4个元素的链表。。。以此类推直到生成一个排好序的新链表。

注意:合并两个都排好序的链表时,我们只需要遍历一遍,时间复杂度为O(N)。

例如:

7   ->  3   ->   9   ->   6    ->   2   ->   8   ->   4   ->   1   -> null

\    /                 \     /                 \      /              \    /

3->7->null    6->9->null        2->8->null        1->4->null

        \           /                                 \               /

3->6->7->9->null                          1->2->4->8->null

                \                                    /

              1->2->3->4->6->7->8->9->null

以上是关于指针实现时间复杂度为O(n*logN)的排序算法(归并排序算法)的主要内容,如果未能解决你的问题,请参考以下文章

算法:排序

挖掘算法中的数据结构:O(n*logn)排序算法之 快速排序(随机化二路三路排序) 及衍生算法

经典排序算法学习笔记七——堆排序

常用的排序算法和时间复杂度

算法 基础

挖掘算法中的数据结构:O(n*logn)排序算法之 归并排序(自顶向下自底向上) 及 算法优化