• 单链表快排 改变节点位置


    快速排序2(算法交换链表节点,平均时间复杂度O(nlogn),不考虑递归栈空间的话空间复杂度是O(1))
    这里的partition,我们选取第一个节点作为枢纽元,然后把小于枢纽的节点放到一个链中,把不小于枢纽的及节点放到另一个链中,最后把两条链以及枢纽连接成一条链。
    这里我们需要注意的是,1.在对一条子链进行partition时,由于节点的顺序都打乱了,所以得保正重新组合成一条新链表时,要和该子链表的前后部分连接起来,因此我们的partition传入三个参数,除了子链表的范围(也是前闭后开区间),还要传入子链表头结点的前驱;2.partition后链表的头结点可能已经改变
    class Solution {
    public:
        ListNode *quickSortList(ListNode *head) {
            // IMPORTANT: Please reset any member data you declared, as
            // the same Solution instance will be reused for each test case.
            //链表快速排序
            if(head == NULL || head->next == NULL)return head;
            ListNode tmpHead(0); tmpHead.next = head;
            qsortList(&tmpHead, head, NULL);
            return tmpHead.next;
        }
        void qsortList(ListNode *headPre, ListNode*head, ListNode*tail)
        {
            //链表范围是[low, high)
            if(head != tail && head->next != tail)
            {
                ListNode* mid = partitionList(headPre, head, tail);//注意这里head可能不再指向链表头了
                qsortList(headPre, headPre->next, mid);
                qsortList(mid, mid->next, tail);
            }
        }
        ListNode* partitionList(ListNode* lowPre, ListNode* low, ListNode* high)
        {
            //链表范围是[low, high)
            int key = low->val;
            ListNode node1(0), node2(0);//比key小的链的头结点,比key大的链的头结点
            ListNode* little = &node1, *big = &node2;
            for(ListNode*i = low->next; i != high; i = i->next)
                if(i->val < key)
                {
                    little->next = i;
                    little = i;
                }
                else
                {
                    big->next = i;
                    big = i;
                }
            big->next = high;//保证子链表[low,high)和后面的部分连接
            little->next = low;          //负责把中枢纽的元素,插入到我们自己划分的little和big两个链表中间,此负责上部分,即little和pivot之间的连接
            low->next = node2.next;      //同上,负责big链表和pivot之间的连接 
            lowPre->next = node1.next;//为了保证子链表[low,high)和前面的部分连接
            return low;
        }
    };

    这个方法中little和big所组成的两个不同链表是有头节点的,分别是node1,和node2.

    快速排序2(算法交换链表节点,平均时间复杂度O(nlogn),不考虑递归栈空间的话空间复杂度是O(1))

    这里的partition,我们选取第一个节点作为枢纽元,然后把小于枢纽的节点放到一个链中,把不小于枢纽的及节点放到另一个链中,最后把两条链以及枢纽连接成一条链。

    这里我们需要注意的是:

    1.在对一条子链进行partition时,由于节点的顺序都打乱了,所以得保正重新组合成一条新链表时,要和该子链表的前后部分连接起来,因此我们的partition传入三个参数,除了子链表的范围(也是前闭后开区间),还要传入子链表头结点的前驱;,由于本身就是前闭后开[   )所以,只需要传入prev,不需要传入high。因为本身就有

    2.partition后链表的头结点可能已经改变,通过head的前驱,tmpHead(也可以用引用)

  • 相关阅读:
    【WPF学习】第四十八章 理解WPF动画
    【WPF学习】第四十七章 WriteableBitmap类
    【WPF学习】第四十六章 效果
    【WPF学习】第四十五章 可视化对象
    【WPF学习】第四十四章 图画
    【WPF学习】第四十三章 路径和几何图形
    【WPF学习】第四十二章 透明
    【WPF学习】第四十一章 变换
    【WPF学习】第四十章 画刷
    【WPF学习】第三十九章 理解形状
  • 原文地址:https://www.cnblogs.com/kkshaq/p/4518410.html
Copyright © 2020-2023  润新知