• 63.如何对单链表进行快排?和数组快排的分析与对比[quicksort of array and linked list]


    【本文链接】

    http://www.cnblogs.com/hellogiser/p/quick-sort-of-array-and-linked-list.html

    【题目】

    单链表的特点是:单向。设头结点位head,则最后一个节点的next指向NULL。如果只知道头结点head,请问怎么将该链表排序?

    【分析】

    对于数组的快排:有2种方式。

    (1)指针相向移动:一个指针i指向头,一个指针j指向尾,然后两个指针相向运动并按一定规律交换值,最后找到一个支点p使得支点左边的值小于支点,支点右边的值大于支点。由于单链表只有next指针,没有前驱指针,因此这种方法行不通。

    (2)指针同向移动:两个指针i和j,这两个指针均往数组的右方移动,移动的过程中保持i之前的值都小于选定的key,i和j之间的值都大于选定的key,那么当j走到末尾的时候便完成了一次支点的寻找。这个思路非常适合单链表。

    对于数组,我们很容易写出下面的代码。

    【代码1】

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
     
    /*
        version: 1.0
        author: hellogiser
        blog: http://www.cnblogs.com/hellogiser
        date: 2014/5/30
    */


    // i from left,j from right
    // i------------>p<-----------------j
    int Partition(int a[], int left, int right)
    {
        
    // partition so that a[left..p-1]<=a[p] and a[p+1..right]>a[p]
        int pivot = a[left], i = left , j = right;
        
    while (i < j)
        {
            
    while (a[i] <= pivot) i++;
            
    while (a[j] > pivot) j--;
            
    if (i < j)
                myswap(a[i], a[j]);
        }
        myswap(a[left], a[j]);
        
    return j;
    }

    void QuickSort(int a[], int left, int right)
    {
        
    if(left < right) // less
        {
            
    int p = Partition(a, left, right);
            QuickSort(a, left, p - 
    1);
            QuickSort(a, p + 
    1, right);
        }
    }

    void  QuickSort(int a[], int n)
    {
        QuickSort(a, 
    0, n - 1);
    }

    【代码2】

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
     
    /*
        version: 1.0
        author: hellogiser
        blog: http://www.cnblogs.com/hellogiser
        date: 2014/5/30
    */


    // i and j both from left
    // i,j---------------->
    int Partition2(int a[], int left, int right)
    {
        
    // partition so that a[left..p-1]<=a[p] and a[p+1..right]>a[p]
        // left----i<=pivot, i----j>=pivot
        int pivot = a[left], i = left , j = left + 1;
        
    while (j <= right)
        {
            
    if (a[j] < pivot)
            {
                i++;
                myswap(a[i], a[j]);
            }
            j++;
        }
        myswap(a[left], a[i]);
        
    return i;
    }

    void QuickSort2(int a[], int left, int right)
    {
        
    if(left < right) // less
        {
            
    int p = Partition2(a, left, right);
            QuickSort2(a, left, p - 
    1);
            QuickSort2(a, p + 
    1, right);
        }
    }

    void  QuickSort2(int a[], int n)
    {
        QuickSort2(a, 
    0, n - 1);
    }

    对于链表而言,借鉴(2)指针同向移动的思想容易改成如下代码。

    【代码】

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
     
    /*
        version: 1.0
        author: hellogiser
        blog: http://www.cnblogs.com/hellogiser
        date: 2014/5/30
    */


    // i and j both from left
    // i,j---------------->
    node *Partition2_List(node *left, node *right)
    {
        
    // partition so that a[left..p-1]<=a[p] and a[p+1..right]>a[p]
        // left----i<=pivot, i----j>=pivot
        node *pivot = left, *i = left , *j = left->next;
        
    while (j != right)
        {
            
    if (j->value < pivot->value)
            {
                i = i->next;
                myswap(i->value, j->value);
            }
            j = j->next;
        }
        myswap(left->value, i->value);
        
    return i;
    }

    void QuickSort2_List(node *left, node *right)
    {
        
    if(left != right) // less
        {
            node *p = Partition2_List(left, right);
            QuickSort2_List(left, p);
            QuickSort2_List(p->next, right);
        }
    }

    void  QuickSort2_List(node *head)
    {
        QuickSort2_List(head, 
    NULL);
    }

    【参考】

    http://blog.csdn.net/wumuzi520/article/details/8078322

    【本文链接】

    http://www.cnblogs.com/hellogiser/p/quick-sort-of-array-and-linked-list.html

    个人学习笔记,欢迎拍砖!---by hellogiser

    Author: hellogiser
    Warning: 本文版权归作者和博客园共有,欢迎转载,但请保留此段声明,且在文章页面明显位置给出原文连接。Thanks!
    Me: 如果觉得本文对你有帮助的话,那么【推荐】给大家吧,希望今后能够为大家带来更好的技术文章!敬请【关注】
  • 相关阅读:
    《模糊测试--强制发掘安全漏洞的利器》阅读笔记(一)
    BrickerBot
    这些写的很好的PCA文章
    决策树(挖坑待填)
    线性回归
    关于给定DNA序列,如何找到合理的切割位点使得其退火温度保持相对一致
    生成全排列
    AVL树学习笔记
    二叉搜索树
    堆排序
  • 原文地址:https://www.cnblogs.com/hellogiser/p/quick-sort-of-array-and-linked-list.html
Copyright © 2020-2023  润新知