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

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

时间: 2024-07-28 17:23:57

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

数据结构-单链表-结构体定义

单链表,用于存储逻辑关系为 "一对一" 的数据,与顺序表不同,链表不限制数据的物理存储状态,换句话说,使用链表存储的数据元素,其物理存储位置是随机的. 结点在存储器中的位置是任意的,即逻辑上相邻的数据元素在物理上不一定相邻. 例如{1,2,3}: 线性表的链式表示又称为非顺序映像或链式映像. 各结点由两个域组成: 数据域:存储元素数值数据 指针域:存储直接后继结点的存储位置 头指针是指向链表中第一个结点的指针 首元结点是指链表中存储第一个数据元素a1的结点 头结点是在链表的首元结点之前

单链表反转问题

单链表反转问题 基本问题 如何将单链表反转? 算法实现 /** * * Description: 单链表反转. * * @param head * @return ListNode */ public static ListNode reverseList(ListNode head) { if (head == null) { return head; } ListNode prev = null; ListNode current = head; ListNode next = null;

带头结点的单链表操作说明

一.单链表简介 相对于以数组为代表的"顺序表"而言,单链表虽然存储密度比较低(因为数据域才是我们真正需要的,指针域只是用来索引,我们并不真正需要它),但是却具有灵活分配存储空间.方便数据元素的删除.方便元素插入等优点 单链表是线性表链式存储的一种,其储存不连续.单链表的数据结构中包含两个变量:数据和指向下一结点的指针.一个结点只知道下一个结点的地址.一个单链表必须有一个头指针,指向单链表中的第一个结点.否则链表会在内存中丢失. 一般的链表可以不带头结点,头指针直接指向第一个节点,如下图

一起talk C栗子吧(第十二回:C语言实例--单链表一)

各位看官们,大家好,从今天开始,我们讲大型章回体科技小说 :C栗子,也就是C语言实例.闲话休提, 言归正转.让我们一起talk C栗子吧! 看官们,上一回中咱们没有说具体的例子,而且是说了例子中的文件组织结构.这一回咱们继续说C例子, 说的例子是链表,更准确的说法叫作单链表.咱们不但要说C例子,而且会在例子中使用上一回中说过的 文件组织结构,就当作是举例说明文件组织结构的使用方法. 有点一石二鸟的感觉,哈哈. 链表定义 看官们,所谓的链表其实就是一组元素通过一定的方式链接在一起.比如我们坐的火车

【LeetCode-面试算法经典-Java实现】【021-Merge Two Sorted Lists(合并两个排好序的单链表)】

[021-Merge Two Sorted Lists(合并两个排好序的单链表)] [LeetCode-面试算法经典-Java实现][所有题目目录索引] 原题 Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists. 题目大意 合并两个排序链表并返回一个新的列表.新的链表的

【LeetCode-面试算法经典-Java实现】【023-Merge k Sorted Lists(合并k个排好的的单链表)】

[023-Merge k Sorted Lists(合并k个排好的的单链表)] [LeetCode-面试算法经典-Java实现][所有题目目录索引] 原题 Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 题目大意 合并k个排好的的单链表.分析和描述它的复杂性. 解题思路 使用小顶堆来实现,先将K个链表的头结点入堆,取堆顶元素,这个结点就是最小的,接

【LeetCode】 sort list 单链表的归并排序

题目:Sort a linked list in O(n log n) time using constant space complexity. 思路:要求时间复杂度O(nlogn) 知识点:归并排序,链表找到中点的方法 存在的缺点:边界条件多考虑!!! /** * LeetCode Sort List Sort a linked list in O(n log n) time using constant space complexity. * 题目:将一个单链表进行排序,时间复杂度要求为o

单链表快速排序

根据普通快排的思路,选择1个点为中心点,保证中心点左边比中心点小,中心点右边比中心点大即可. 单链表的实现为: 1.使第一个节点为中心点. 2.创建2个指针(p,q),p指向头结点,q指向p的下一个节点. 3.q开始遍历,如果发现q的值比中心点的值小,则此时p=p->next,并且执行当前p的值和q的值交换,q遍历到链表尾即可. 4.把头结点的值和p的值执行交换.此时p节点为中心点,并且完成1轮快排 5.使用递归的方法即可完成排序 #include<iostream> #include

7_1判断一个单链表是否有环

转载请注明出处:http://www.cnblogs.com/wuzetiandaren/p/4251303.html 声明:现大部分文章为寻找问题时在网上相互转载,此博是为自己做个记录记录,方便自己也方便有类似问题的朋友,本文的思想也许有所借鉴,但源码均为本人实现,如有侵权,请发邮件表明文章和原出处地址,我一定在文章中注明.谢谢. 题目:判断一个单链表是否有环,如果有环,求出环的入口节点. 题目分析: 建一个待头节点的单链表,有两个指针p,q最开始都指向第一个真正节点,p,诶次走1步,q每次走