Chinaunix首页 | 论坛 | 博客
  • 博客访问: 340535
  • 博文数量: 88
  • 博客积分: 2011
  • 博客等级: 大尉
  • 技术积分: 885
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-21 14:50
文章分类

全部博文(88)

文章存档

2010年(88)

我的朋友

分类: C/C++

2010-09-21 15:29:01

链表排序有很多种方法,数组排序的方法一般都可行,但是鉴于链表和数组的不同点,个人认为插入排序和归并排序更方便点。

插入排序类似于链表反转的做法,只不过在反转插入结点的时候加一段比较的代码即可。

链表归并排序排序和数组归并排序相比的有点是可以省去额外空间的开销,可以用两个指针,一快一慢将链表从中间分成两块,递归下去,最后的结果就两个子链表的合并操作(保持有序)即可。(归并的代码没有自己写,网上转了一个过来http://mmliu.javaeye.com/blog/686646

#include
#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");
}

阅读(2009) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~