zoukankan      html  css  js  c++  java
  • 指针实现时间复杂度为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

  • 相关阅读:
    cpu降频问题
    配置 logrotate 指导
    Ubuntu 和 Ros 对应版本关系
    Git 文件管理
    Win10(UEFI启动) 安装Ubuntu16.04双系统
    Clion ROS开发环境设置
    clion 创建快捷方式和配置ros开发环境
    Ubuntu 16.04安装 CastXML
    eigen3 版本信息查看
    ubunutu eigen3包的查找
  • 原文地址:https://www.cnblogs.com/timesdaughter/p/5512700.html
Copyright © 2011-2022 走看看