`
beefcow
  • 浏览: 44113 次
  • 性别: 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
分享到:
评论

相关推荐

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

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

    数据结构实验报告1-线性表-两个有序表的归并-实验内容及要求.docx

    从键盘输入数据,建立两个有序线性表(每个...其中链表实现时,要求利用两个升序链表的结点实现归并,即归并时不能新建结点,归并后原来两个升序链表的存储空间不在存在。 实验目的:掌握两个有序线性表的归并算法。

    数据结构课设 各种排序

    1、链表排序 [问题描述] 建立一个单链表,排序输出、再倒序输出。[基本要求] (1) 从文件读入30个无序整数,建立一个单链表,输出。(2) 排序,输出 (3) 倒序,输出 2、二叉树的应用 任务 :编程实现二叉树...

    数据结构课程设计_综合排序问题

    1) 分别采用的方法有插入排序、希尔排序、起泡排序、快速排序、选择排序、堆排序、归并排序,实现这批数据的排序,并把排序后的结果保存在不同的文件中。 2) 统计每一种排序方法的性能(以上机运行程序所花费的时间...

    【swjtu】数据结构一_两个有序线性表的归并算法.zip

    从键盘输入数据,建立两个有序线性表(每个线性表的输入数据按由小到大次序输入来建立...其中链表实现时,要求利用两个升序链表的结点实现归并,即归并时不能新建结点,归并后原来两个升序链表的存储空间不在存在。

    数据结构实验报告-线性表-两个有序线性表的归并算法

    实验内容及要求: 从键盘输入数据,建立两个...其中链表实现时,要求利用两个升序链表的结点实现归并,即归并时不能新建结点,归并后原来两个升序链表的存储空间不在存在。 实验目的:掌握两个有序线性表的归并算法。

    2020西南交通大学数据结构实验报告两个有序线性表的归并算法.doxc

    从键盘输入数据,建立两个有序线性表(每个...其中链表实现时,要求利用两个升序链表的结点实现归并,即归并时不能新建结点,归并后原来两个升序链表的存储空间不再存在。 实验目的:掌握两个有序线性表的归并算法。

    数据结构实验1线性表归并及附加题详解

    其中链表实现时,要求利用两个升序链表的结点实现归并,即归并时不能新建结点,归并后原来两个升序链表的存储空间不在存在。 附加题: 实验题目:建立双向循环链表并且删除其中满足条件的元素 实验内容及要求: 已知...

    数据结构实验报告--多关键字排序.doc

    直接插入排序,希尔排序,简单选择排序,冒泡排序,快速排序,堆排序,归并排序主要通过某种策略移动,选择或交换关键字来实现,关键字选择上,为了简便起见,都是整形数据。关键字间的比较,也都是直观的大小比较。...

    华南 数据结构上机实验代码 完整代码

    目录按以下顺序排列: 顺序线性表的基本操作 合并顺序表 顺序表逆置 链式线性表的基本操作 合并链表 线性链表逆置 ...利用递归实现查找中序遍历序列中第i个结点 删除线性表中所有值小于x的元素

    《数据结构》实验

    3、假设有两个按元素值递增有序的线性表A和B,均以单链表作存储结构,试编写算法将A表和B表归并成一个按元素值递减有序的线性表C,并要求利用原表的空间存放C。 要求:熟练掌握线性表的单链式链接存储结构及在其上...

    数据结构专周

    1.综合应用 有N名学生,每名学生含有如下信息:学号、姓名、某四门课的成绩,... 要求:存储结构利用二叉链表 4. 快速排序 实现对任意一组数据的快速排序。 5. 2路-归并排序 实现对任意一组数据的2路-归并排序。

    基于Python实现的数据结构与算法完整源代码+超详细注释(包含46个作业项目).zip

    12_python实现ADT 链表 13_递归-转换任意进制 14_递归-分形树 15_递归-谢尔宾斯基三角形 16_递归-汉诺塔问题 17_递归-零钱找零问题 18_递归-博物馆大盗问题 19_顺序查找 20_二分查找 21_冒泡排序和选择排序 22_插入...

    java算法大全源码包.zip

    在Java中,ArrayList是通过数组实现,而LinkedList则通过链表实现。一个简单的链表类如下: 2.二叉树 二叉树是n(n&gt;=0)个结点的有序集合。每个结点最多有2个子节点,即左结点和右结点,且左右结点顺序不能更改。...

    数据结构与算法.xmind

    当递归到规模足够小时,利用插入排序 归并前判断一下是否还有必要归并 只在排序前开辟一次空间 基数(桶)排序 思想 分配,回收(分配到不同的位置上,然后回收)..不断分配..回收来...

    数据结构实验.rar

    1、(必做题)假设二叉树中数据元素类型是字符型,请采用二叉链表实现二叉树的以下基本操作: (1)根据二叉树的先序序列和中序序列构造二叉树; (2)根据先序遍历二叉树; (3)根据中序遍历二叉树; (4)根据...

    JAVA单链表的简单操作(递增单链表插入数据,链表逆置,链表逆序合成)

    3、假设有两个按元素值递增有序的线性表 A 和 B,均以单链表作存储结构, 试编写算法将 A 表和 B 表归并成一个按元素值递减有序的线性表性表 C,并要求 利用原表的空间存放 C,并要求用尽可能少的时间完成。...

    严蔚敏:数据结构题集(C语言版)

    后半部分主要讨论查找和排序的各种实现方法及其综合分析比较。其内容和章节编排与1992年4月出版的《数据结构》(第二版)基本一致,但在本书中更突出了抽象数据类型的概念。全书采用类C语言作为数据结构和算法的描述...

    谭浩强C语言程序设计,C++程序设计,严蔚敏数据结构,高一凡数据结构算法分析与实现.rar

    11.9 链表的概念 182 11.10 枚举类型 184 11.10.1 枚举类型的定义和枚举变量的说明 184 11.10.2 枚举类型变量的赋值和使用 185 11.11 类型定义符typedef 12 位运算 12.1 位运算符C语言提供了六种位运算符: 189 ...

Global site tag (gtag.js) - Google Analytics