`
beefcow
  • 浏览: 44693 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
最近访客 更多访客>>
社区版块
存档分类
最新评论

利用归并实现 链表排序

阅读更多

   

    之前就听说可以用归并来实现链表的排序,刚听到还楞了一下,觉得主要问题是归并数组时需要不断地对数组进行二分,这种操作对于数组直接利用下标即可定位,可是链表定位元素就很麻烦了,不知道怎么实现,后来看了一下,二分的操作果然,当然还是得利用循环,不过相当巧妙,是使用两个步长一快一慢的指针进行,也算奇思妙想,代码如下,重点部位有注释(英文是因为代码里注释习惯写英文,避免之后因为编码问题,辛辛苦苦的注释全部变成圈圈框框,见谅):

 

#include <stdio.h>
#include "tool.c"
#define NULL ((void *)0)

struct LinkList{
    struct LinkList *next;
    int value;
} *linkList,node;

/*
  try to mergeSort a linkList
*/
int main(){
    void printLinkList(struct LinkList *list);
    struct LinkList *mergeSort(struct LinkList *head);
    
    //build a linkList,end with an NULL node
    struct LinkList *list=(struct LinkList *)malloc(sizeof(node));
    struct LinkList *current=list;
    int i;
    for(i=0;i<20;i++){
        struct LinkList *temp=(struct LinkList *)malloc(sizeof(node));
        temp->value=getRandom();
        
        current->next=temp;
        current=current->next;
    }
    current->next=NULL;
    printf("Before sort:\n");
    printLinkList(list->next);
    
    //mergeSort the list.
    resList=mergeSort(list->next);
    printf("After sort:\n");
    printLinkList(list->next);
    getchar();
    return 0;
}

/*
  Mergesort the linkList.
*/
struct LinkList *mergeSort(struct LinkList *head){
   struct LinkList *merge(struct LinkList *first,struct LinkList *second);    
       
   struct LinkList *first;
   struct LinkList *second;
   first=head;
   second=head;
   if(first==NULL||first->next==NULL){
       //Note here is the place that can jump out of the recursion.
       return first;
   }
   
   //cut the LinkList into 2 list,one lead by "first",the other lead by "second".
   while(second->next!=NULL && second->next->next!=NULL){
       first=first->next;
       second=second->next->next;
   }
   if(first->next!=NULL){
       second=first->next;
       first->next=NULL;
       first=head;
   } 
   
   //merge the List.
   return merge(mergeSort(first),mergeSort(second));
}

/*
  Merge the list.
  It is quite similar with the operation of the merge of Array,
  but note that because of the linklist,we avoid the large space expence of the 
  usual merge of array.
*/
struct LinkList *merge(struct LinkList *first,struct LinkList *second){    
    struct LinkList *resList=(struct LinkList *)malloc(sizeof(node));
    struct LinkList *current;
    current=resList;
    
    while(first!=NULL && second!=NULL){
        if(first->value<=second->value){
            current->next=first;
            current=current->next;                            
            first=first->next;
        }else{
            current->next=second;
            current=current->next;                             
            second=second->next;          
        }
    }
    
    while(first!=NULL){
        current->next=first; 
        current=current->next;                            
        first=first->next;
    }
    while(second!=NULL){
        current->next=second;  
        current=current->next;                           
        second=second->next;                  
    }
    
    return resList->next;
}

/*
  Print the LinkList.
*/
void printLinkList(struct LinkList *list){
    while(list!=NULL){
        printf("%d ",list->value);
        list=list->next;
    }
    printf("\n");
}

 

 

    值得一提的是,链表排序和归并比较天作之合的一点是,归并在保留了nLg(n)的时间复杂度的同时,还避开了一般比如数组归并时的的额外空间开销,注意merge() 函数的操作.

    数组归并时,在合并子数组时,需要先开出额外空间,存储两个子数组的合并结果,然后再写到原数组中.

    而这里呢,链表的合并只需开一个头结点,然后让它随着两个子链表不断修改指向即可.

    所以说是天作之合,毫不夸张.

 

    ps1.关于数组的归并实现,可以参考这里:http://mmliu.iteye.com/blog/683375

    ps2.至于链表的归并实现,参考了这里,可以看看:http://topic.csdn.net/u/20071210/13/673b1e16-d788-402f-a06d-84c4808434ef.html

 

 

 

1
3
分享到:
评论

相关推荐

    用单链表和队列实现归并排序

    在标题“用单链表和队列实现归并排序”中,我们可以理解到这个实现是利用了链表和队列的数据结构。链表是一种线性数据结构,其中的元素在内存中不是顺序存储的,而是通过指针链接。队列则是一种先进先出(FIFO)的...

    一个基于链表的归并排序程序

    1.编写一个基于链表的归并排序程序。 1)随机生成两个链表,利用随机数进行初始化 2)要求给出链表的结构,链表的初始化等排序中用到的基本操作函数 3)显示相关的输出信息 编程环境:Linux C

    基于vc++6.0用链表实现归并排序

    本教程将深入探讨如何在VC++6.0环境下,利用链表数据结构实现归并排序。 链表是一种非连续、非顺序的存储结构,每个元素称为节点,包含数据域和指针域。节点通过指针域连接成链,使得数据可以在内存中任意位置存储...

    顺序表和链表的归并排序

    本文将深入探讨两种数据结构——顺序表和链表,并讲解如何使用面向对象的思想实现它们的归并排序。 首先,让我们了解顺序表和链表。顺序表是一种线性数据结构,它的特点是元素在内存中是连续存储的,可以通过索引来...

    快速排序与归并排序比较(C++).rar_c++paixusuanfa_归并_归并排序_归并排序算法

    C++中实现快速排序和归并排序,可以利用STL中的`std::sort`函数,但为了深入理解算法,通常会自定义实现。快速排序可以采用递归或非递归方式,而归并排序则通常使用递归。在“快速排序与归并排序比较(C++)”的程序中...

    ORDERLIST链表排序程序代码

    在这个名为“ORDERLIST”的链表排序程序中,我们将探讨如何利用链表来实现数字的统计、插入、删除以及显示当前顺序的功能。 链表是一种非连续的数据结构,其中每个节点包含数据和指向下一个节点的引用。与数组不同...

    单链表为存储结构, 实现二路归并排序的算法

    二路归并排序是一种高效的排序算法,...总结来说,二路归并排序利用单链表的特性,通过分而治之和巧妙的合并策略,实现了高效且节省空间的排序方法。在实际应用中,这种排序方式对于动态数据结构,如链表,尤为适用。

    简单的单链表排序 —— 学生管理程序

    在链表排序中,我们通常采用两种主要的排序算法:插入排序和归并排序。这里我们将以简单的插入排序为例,介绍如何对单链表进行排序。 **插入排序**的基本思想是将未排序的元素逐个插入到已排序的部分,从而保持已...

    按照百十个位分拆链表,然后组合排序

    3. **分组排序:** 对每个分组内的链表进行排序,这里可以采用任何适合链表排序的方法。 4. **合并链表:** 将排序后的各个分组链表按顺序合并成一个有序链表。 #### 具体实现 在代码示例中,可以看到作者使用了...

    C++版本将两个有序链表合并为一个新的有序链表并返回原理及代码实现

    本文将详细介绍如何使用C++语言来实现一个功能,即合并两个已经排序的链表,并返回一个新的有序链表。这个过程不仅涉及到对链表的理解,还需要掌握一定的算法设计技巧。 #### 链表基础 链表是由一系列节点组成的...

    c#代码有查找,二叉树,链表,各种排序

    在C#中,可以利用数组、List等数据结构实现这些查找算法。 接下来是“二叉树”。二叉树是一种非线性的数据结构,每个节点最多有两个子节点,通常分为左子节点和右子节点。二叉树的主要类型有完全二叉树和平衡二叉树...

    链表、树、排序问题c++程序.zip

    本压缩包"链表、树、排序问题c++程序.zip"提供了一系列与这些主题相关的C++实现,包括链表、栈、排序、查找和二叉树等经典数据结构和算法,下面将详细阐述这些知识点。 1. 链表:链表是一种线性数据结构,不同于...

    归并排序_排序_

    归并排序(Merge Sort)...总结来说,归并排序是一种高效的排序算法,利用了分治策略,通过递归将数组分割、排序和合并来实现整体的有序状态。C#语言提供了强大的工具支持,使得实现归并排序成为一件简单而高效的事情。

    链式归并排序c++语言

    在C++编程语言中,我们可以利用链表这种数据结构来实现归并排序。下面我们将详细介绍链式归并排序的原理、步骤以及如何在VS2005环境下编写C++代码来实现这一算法。 **归并排序的基本概念:** 归并排序是一种稳定的...

    用面向对象程序设计对单链表进行归并排序

    6. **链表排序的优化**: - 避免频繁的动态内存分配,可以使用预分配的缓冲区或者尾递归优化减少函数调用的开销。 - 在链表长度较小时,可以考虑使用插入排序,因为对于小规模数据,插入排序的效率可能更高。 综...

    归并排序 基数排序 算法讲解

    这段代码展示了归并排序的核心逻辑,通过`Mergesort`函数控制整个排序过程,`Mergepass`负责两两合并操作,而`Merge`则实现了具体的合并排序逻辑。 #### 基数排序详解 基数排序(Radix Sort)是一种非比较型的整数...

    链表的智能排序与索引算法.pptx

    - **逆序链表排序**:归并排序算法在处理逆序链表时表现优异。 **3.2 优化策略** - **归并排序变体**:如归并插入排序,可提高小链表的排序效率。 - **多线程并行化**:利用多核处理器提高排序速度。 - **分布式...

    C语言演示对归并排序算法的优化实现

    在C语言中,我们可以用如上所示的代码来实现归并排序。`integer_timsort`函数是整个排序的核心,它首先检查数组的大小,如果大小为1或更小,那么数组已经有序,无需排序。否则,它将数组一分为二,对每一半分别进行...

    C 使用双链表 读文件并排序 Linux底下

    这里假设数据是整型,可以使用插入排序实现: ```c void sortList(Node **head) { Node *current = *head, *temp, *previous; while (current != NULL) { previous = current-&gt;prev; temp = current; while ...

Global site tag (gtag.js) - Google Analytics