• Sort_List@LeetCode


    1.规定了时间复杂度o(nlogn):采用归并排序,在归并过程:采用分合思想,递归将链表分为两段之后再将merge

    分两段方法使用 fast-slow法,用两个指针P1,P2,p1指针每一次走两步,p2指针每一次走一步;当P1指针走到末尾时候,P2指针刚好在中间位置,直到将N序列分成最小子序列单个链表

    merge方法:单个链表对合并成有序父链表,比较表头的值,一个P指针指向表头较小值,p指针向后移动,合并至连接到Temp连接表中

    1. 采用fast-slow过程中注意 fast=head slow=head

    2.在归并merge算法中 使用倆个指针 headTemp指针指向其链表首地址,Rear指针遍历之后节点(将其他位置上的节点连接已有地址上来)

     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         /*拆分最小单子序列 与 单子序列进行合并*/
    13         
    14         if(head==NULL || head->next==NULL) return head;
    15         
    16         /*定义fast-slow将链表进行分割*/
    17        ListNode *slow=head,*fast=head;
    18         //找的中间点从中分为right 与 left
    19         while(fast->next && fast->next->next)
    20           {
    21                 slow=slow->next;
    22                 fast=fast->next->next;
    23           }
    24         
    25         ListNode *H1=head,*H2=slow->next;
    26         slow->next=NULL;//将分割成俩块
    27         
    28         H1=sortList(H1);H2=sortList(H2);
    29         
    30         return merge(H1,H2);
    31         
    32     }
    33     
    34     ListNode *merge(ListNode * Left, ListNode * right)
    35     
    36     {
    37         
    38         ListNode *headTemp ;/*使用两个指针一个记录开始地址,另外一个地址所有后续节点*/
    39         /*必须headTemp指针指向大的值作为开始*/
    40         if(Left->val < right->val)
    41             {
    42                 headTemp=Left;
    43                 Left=Left->next;
    44             }
    45         else
    46            {
    47                 headTemp=right;
    48                 right=right->next;
    49            }
    50             
    51         ListNode *p=headTemp;
    52         while(Left!=NULL && right!=NULL)
    53           {
    54             
    55                 if(Left->val<right->val)
    56                      {
    57                         p->next=Left;
    58                         p=p->next;//往后移动指向下一个指针,P失去前一个节点但是
    59                                     //headTemp记录前一个节点p=p->next,将其他地址链接到当前地址后面
    60                         Left=Left->next;
    61                      }
    62                     else
    63                      {
    64                      
    65                        p->next=right;
    66                         p=p->next;//往后移动指向下一个指针
    67                         right=right->next;
    68                  }
    69           }
    70         
    71         if(Left==NULL)
    72             {
    73             p->next=right;
    74             }
    75         if(right==NULL)
    76             {
    77             p->next=Left;
    78         }
    79         
    80         return headTemp;
    81     }
    82    
    83 };

     此算法用了测试 如何建立链表:建立链表中 new 开辟地址,在输入过程中新的链表链接到此上,最后将开始无用链表进行删除

     1 /*从尾部向头部打印*/
     2 #include<iostream>
     3 #include<stack>
     4 using namespace std;
     5 struct ListNode
     6 {
     7     int m_nKey;
     8     ListNode *m_pNext;
     9 };
    10 
    11 class Solution
    12 {
    13 public:
    14     void PrintListReverse(ListNode * pHead)
    15     {
    16         /*使用堆栈--后进先出特性*/
    17         std::stack<ListNode *> nodes;
    18         ListNode *PNode=pHead;
    19 
    20         while(PNode!=NULL )
    21         {
    22             nodes.push(PNode);    
    23             PNode=PNode->m_pNext;
    24         }
    25 
    26         while(!nodes.empty())
    27         {
    28             PNode=nodes.top();
    29             std::cout<<PNode->m_nKey<<" ";
    30             nodes.pop();
    31         }
    32     }
    33 
    34 };
    35 
    36 int main()
    37 {
    38     ListNode *List=new ListNode();List->m_pNext=NULL;
    39 
    40     ListNode *pList=List; int m_value;
    41     
    42     while(true)
    43     {
    44         cin>>m_value;
    45         if(m_value==-1)
    46         {
    47             
    48             pList=NULL;
    49             break;
    50 
    51         }
    52         /*开辟新的链表节点,将新的链表节点连接到已有节点上,最后将Head无用节点删除*/
    53         ListNode *Rear=new ListNode;
    54         Rear->m_nKey=m_value; Rear->m_pNext=NULL;
    55         pList->m_pNext=Rear;
    56         /*pList指向此新节点*/
    57         pList=pList->m_pNext;
    58     }
    59     /*开始时候多了一个节点*/
    60     List=List->m_pNext;
    61 
    62     Solution S;
    63     S.PrintListReverse(List);
    64     return 0;
    65 }
    View Code

     快速排序 链表方式

    单向链表采用快速排序:不同于数组的快速排序,单向链表没有前驱指针,但是其还可以借助 快速排序的思想:两个指针prev1=phead,prev2=prev1->next, 两者指针从前遍历到尾,prev2指针先于prev1,当遇到小于基数X值,swap交换prev2->val 和 p->next->val(这样保证p往前移动,直到遇到支点返回)

     1 /*链表快速排序*/
     2 #include<iostream>
     3 using namespace std;
     4 struct ListNode
     5 {
     6     int val;
     7     ListNode *next;
     8     
     9 };
    10 
    11 ListNode *GetPartion(ListNode *Head,ListNode*end)
    12 {
    13     ListNode *prev1=Head;
    14     ListNode * prev2=prev1->next;
    15     int Key=Head->val;
    16     /*利用俩个指针从前往后遍历,最后找到一个支点,支点之前小于基数,支点之后大于基数*/
    17     while(prev2!=NULL && prev2!=end)
    18     {
    19         if(prev2->val<Key )
    20         {
    21             prev1=prev1->next;
    22             swap(prev1->val,prev2->val);
    23         }
    24         prev2=prev2->next;
    25     }
    26 
    27     /*prev1就是支点位置*/
    28     swap(prev1->val,Head->val);
    29     return prev1;
    30 }
    31 void QuickSort(ListNode *pHead,ListNode *pEnd)
    32 {
    33     /*使用两个不同指针从前往后遍历*/
    34     if(pHead==NULL || pHead->next==NULL)
    35         return;
    36     if(pHead!=pEnd)
    37     {
    38         ListNode * partion=GetPartion(pHead,pEnd);
    39         QuickSort(pHead,partion);
    40         /*注意在这里必须要partion->next,不然出现明显的死循环问题*/
    41         QuickSort(partion->next,pEnd);
    42     }
    43 
    44 }
    45 void printQuickSort(ListNode *head)
    46 {
    47     if(head==NULL)
    48     {    cout<<"输入空节点"<<endl;
    49     
    50 
    51         return ;
    52     }
    53 
    54     ListNode *pHead=head;
    55     
    56     while(pHead!=NULL)
    57     {
    58         cout<<pHead->val<<" ";
    59         pHead=pHead->next;
    60     }
    61 }
    62 int main()
    63 {
    64     ListNode *List=new ListNode();List->next=NULL;
    65 
    66     ListNode *pList=List; int m_value;
    67     while(true)
    68     {
    69         cin>>m_value;
    70         if(m_value==-1)
    71         {
    72             
    73             pList=NULL;
    74             break;
    75 
    76         }
    77         /*开辟新的链表节点,将新的链表节点连接到已有节点上,最后将Head无用节点删除*/
    78         ListNode *Rear=new ListNode;
    79         Rear->val=m_value; Rear->next=NULL;
    80         pList->next=Rear;
    81         /*pList指向此新节点*/
    82         pList=pList->next;
    83     }
    84     /*删除开始时候多了一个节点,只有先有地址链表才能够运行*/
    85     List=List->next;
    86     QuickSort(List,NULL);
    87     printQuickSort(List);
    88     return 0;
    89 }

    输入空节点时候,程序并没有崩溃

  • 相关阅读:
    [国家集训队]数颜色 / 维护队列
    【模板】二逼平衡树(线段树+平衡树)
    jenkins实现接口自动化持续集成(python+pytest+ Allure+git)
    Locust快速上手指南
    缓解多分类的样本不均衡问题
    PlayStation@4功能介绍及测试应用
    APP专项测试-弱网测试
    游戏自动化测试-局内战斗
    Windows下JMeter分布式压测环境搭建
    基于simhash的文本去重原理
  • 原文地址:https://www.cnblogs.com/woainifanfan/p/6486763.html
Copyright © 2020-2023  润新知