排序算法笔记

来源:互联网 发布:桌面日历备忘录软件 编辑:程序博客网 时间:2024/04/30 00:03
/***************************************************************************
                          排序算法笔记

                                          Leo,2006/10/4
                                    stefzeus@163.com
    当列表长度n增加适时,插入排序和选择排序的时间需求随n^2增长,但如果它们接近正确的顺序,插入排序将非常高效(如果列表是完全按顺序排好的,则插
入排序能够以所获得的最快速度验证这种情况),当他们原先的顺序比较糟糕时,
选择排序则更有效,它的性能比较平衡。
    希尔排序在性能上比归并排序和快速排序差不了多少,但不需要使用递归,
很容易编程实现,因此不要低估希尔排序的作用。希尔最好以单数做为增量;
    归并排序一般不用于列表(存贮空间不好掌握,一般用在链表);而快速排序
两者都适用。他们的时间需求为 ○(n*logn) ,但快速排序在最差的情形下,时间需
求随着n^2增长。
    堆排序是一个保证策列。它通常更接近于快速排序,但避免了出现少量性能严重
下降的可能性;但由于堆排序需要随机地访问列表中的所有部分,因此堆排序仅适合
连续列表。

注意事项:
    1.许多计算机系统都有一个通用目的的排序实用程序。如果能够访问这些实用程
序,并且对于你的应用来说,该实用程序能够满足需要,则使用这个实用程序;若不
需要,则重新编写一个排序程序。
    2.在选择排序方法时,需要考虑:排序前键通常的组合方式,应用程序的大小,
可利用的变成时间量,节省计算机时间和空间的需求,数据结构的实现方式,移动数
据的开销和比较键的开销。
    3.“分而治之”的方法对于设计算法来说,是一种应用性,最广且最强大的方法。
当面对一个编程问题时,查看是否能够通过解决两个(或多个)相同形式但尺寸较小
的问题,来解决整个问题。如果能,就可以构建一个算法,使用“分而治之”的方法,
并使用递归来进行编程。
    4.归并排序,快速排序和堆排序是强大的排序方法,在变成方面,虽然比简单的
排序方法更难一些,但当应用于大列表是,非常高效。仔细考虑你的应用程序,判断
实现这些复杂的算法是否需要额外的工作。
    5.对于很多应用来说,优先级队列是很重要的,堆提供了优先级队列的一个很好
的实现方法。
    6.堆排序如同一种保险策列;与快速排序相比,它通常比较慢,但能够保证排序
在 ○(n*logn) 次键比较内完成,而且快速排序并不能总是快速地完成排序。

**************************************************************************/

/*
    以下程序只体现C语言的排序算法,并不保证能运行
                                                                        */


/**************************************************************************/

/*InsertionSort: Sort contiguous list by the insertion sort method.
    pre: The contiguous list has been creat.Each of list contain a key
    post:The entries of list have been rearanged so that the keys in
         all the entries are sorted into nondecresing order.            */
void InsertionSort(List *list)
{
    Position    fu;  /* position of first unsorted entry       */
    Position    place;        /* searches sorted part of list         */
    ListElem    current;      /* holds entry temporarily removed form list */

    for (fu=1; fu < list->count; fu++)
        if( list->elem[fu] < list->elem[fu-1] )
            {
             current=list->elem[fu];
             for(place=fu-1;place=>0;place--)
                {
                 list->elem[place+1]=list->elem[place];
                 if( place==0 || list->elem[place-1].key < current.key )
                    break;
                }
             list->elem[place]=current;
            }

}



/****************************************************************************/

/*SelectionSort: sort contiguous list by the selection sort method
    pre: The contiguous list list has been created.Each entry of list contains
          a key.
    post:The entries of list have been rearranged so that the keys in all the
          entries are sorted into nondecreasing order.
    uses: MaxKey(),Swap().                                                    */
void SelectionSort(List *list)
{
    Position    current;   /* position of place being correctly filled    */
    Position    max;
    for(current=list->count-1;current>0;current--)
        {
         max=MaxKey(0,current,list);
         Swap(max,current,list);
        }
}


/*Maxkey: find the max key from low to high,retrun it position          */
Position MaxKey(Position low,Position high, List *list)
{
    Position    largest;
    Position    current;
    for(largest=low,current=low+1;current<=high;current++)
        if(list->elem[current].key>list->elem[largest].key)
            largest=current;
    return largest;
}


/*Swap: swap list->elem[first] with list->elem[second] in the *list     */
void Swap(Position first,Position second,List *list)
{
    ListElem    temp=list->elem[first];
    list->elem[first]=list->elem[second];
    list->elem[second]=temp;
}


/****************************************************************************/

/*ShellSort:sort contiguous list by the Shell sort method
    pre:The contiguous list list has been created.Each entry of list contains
        a key.
    post:The entries of list have been rearranged so that the keys in all
         the entries are sorted into nondecreasing order.
    uses:SortInserval()                                              */
void ShellSort(List *list)
{
    Position    increment;
    Position    star;
    increment=list->count;
    do  {
         increment=increment/3+1;
         for(star=0;star<increment;star++)
            SortInserval(star,increment,list);     /* modified insert sort  */
        }while(increment>1);


}


/****************************************************************************/

/*MergeSort:sort contiguous list by the merge sort method
    pre: The linked list bas been created.Each entry of list contains a key
    post:The enteries of list have been rearranged so that the keys in
         all the entries are sorted into nondecreasing order.
    uses:Divide(),Merge()                                                */
void MergeSort(List *list)
{
    List second;
    if(Listsize(list)>1)
        {
         second=Divide(list);
         MergeSort(list);
         MergeSort(second);
         list=Merge(list,second);
        }
}

/*Divide:divide the list into two parts.
    pre:The linked list list has been created.
    post:List list has been reduced to its first half ,and the second
         half of the entries from list are in the linked list second.
         If list has an odd number of entries. then its first half will
         be one entry larger than its second.       */
List *Divide(List *list)
{
    List        second;
    ListNode    *current,*mid;
    if(mid=list->head==NULL)
        return list;
    for(current=mid->next;current;current=curren->next)
        {
         current=current->next;
         if(current)
            mid=mid->next;
        }
    second->head=mid->next;
    mid->next=NULL;
    return second;
}


/*Merge:merge list second to list first
    pre:Link-list first and link-list second have been created.
    post:List first is an order linked list containing all entries that
         were in frist and second .The original lists second have been
         destroyed.                                            */
List *Merge(List *first,List *second)
{
    ListNode    *p1,*p2;     /* pointers to traverse first and second list */
    ListNode    *lastsorted;  /* always points to last node of sorted list */
    if(first->head==NULL)
        return second;
    else if (second->head==NULL)
        return first;
    p1=first->head;
    p2=second->head;
    if(p1->key < p2->key)
        {
         first->head=p1;
         p1=p1->next;
        }
    else{
         first->head=p2;
         p2=p2->next;
        }
    lastsorted=first->head;
    while(p1 && p2)           /* lastsorted gives last entry of merged list */
        {
         if(p1->key < p2->key)
            {
             lastsorted->next=p1;
             lastsorted=p1;
             p1=p1->next;
            }
         else{
              lastsorted->next=p2;
              lastsorted=p2;
              p2=p2->next;
             }
        }
    if(p1)                       /* Attach the remaining list.   */
        lastsorted->next=p1;
    else
        lastsorted->next=p2;
    return first;
}


/****************************************************************************/

/*RecQuickSort:use recursive method to sort list
    pre:The contiguous list-list have been created.Each entry of list
        contains a key.low and high are valid positions on the list-list.
    post:The entries of list have been rearranged so that the keys in all
         the entries are sorted into nondecreasing order.
    uses:RecQuickSort(),Partition();                              */
void RecQuickSort(Position low,Position high,List *list)
{
    Position    pivotpos;  /* position of the pivot after partitioning  */
    if(low<high)
        {
         pivotpos=Partition(low,high,list);
         RecQuickSort(low,pivotpos-1,list);
         RecQuickSort(pivotpos+1,high,list);
        }
}

/*Partition:partition a list.
    pre:    The contiguous list have been create;low and high are vail
            position on the list.
    post:   The center(or left center)entry of list has been chosen as a
            pivot and moved to index pivotpos.All enteries of list between
            indices low and high,inclusive,have been rearranged so that those
            with keys less than the pivot come before pivotpos and the
            remaining enrties come after pivotpos.
    uses:   Swap()                                              */
Position Partition(Position low,Position high,List *list)
{
    ListElem    pivot;
    Position    i,firstlarge;
    Swap(low,(low+high)/2,list);
    pivot=list->elem[low].key;
    for(i=firstlarger=low+1;i<=high;i++)
        if(list->elem[i].key < pivot.key)
            {
             Swap(i,firstlarge,list);  /* Move large entry to right and
                                          small to left.                */
             firstlarge++;
            }
    Swap(low,firstlarge-1,list);
    return firstlarge-1;
}



/****************************************************************************/

/*HeapSort:sort contiguous list by the heap sort method
    Pre:    The contiguous list has been created.Each entry of list contains
            a key.
    post:   The entries of list have been rearranged so that the keys in all
            the entries are sorted into nondecreasing order.
    uses:   BuilHeap(),InsertHeap()                                      */

void HeapSort(List *list)
{
    Position    lu;        /*Entries beyoud lu have been sorted  */
    ListElem    current;   /*hold entry temporarily removed from list */
    BuilHeap(list);
    for(lu=list->count-1;lu>0;lu--)
        {
         current=list->elem[lu];     /* Extract last element from list  */
         list->elem[lu]=list->elem[0];  /*Move top of heap to end of list */
         InsertHeap(current,0,lu-1,list);
        }
}

/*InsertHeap: insert an entry into the heap
    pre:    The entries of contiguous list-list between indices low+1 and
            high,inclusive, form a heap.The entry in position low will be
            discarded.
    post:   The entrycurrent has been inserted into list and the entries
            rearranged so that the entries between indices low and high,
            inclusive,form a heap.                                   */
void InsertHeap(ListElem current,Position low,Position high,List *list)
{
    Position    large;/* position of child of list->elem[low] with the
                         larger key    */
    large=low*2+1;        /*large is now the lefr child of low  */
    while(large<=high)
        {
         if((large < high) && (list->elem[large].key < list->elem[large].key))
            large++;
         if(list->elem[large].key < current.key)
            break;
         else{
              list->elem[low]=list->elem[large];
              low=large;
              large=low*2+1;
             }
        }
    list->elem[low]=current;
}


/*BuildHeap:build a heap from a random contiguous list.
    pre:    The contiguous list-list has been created.Each entry of list
            contains a key.
    post:   The entires of list have been rearranged so that list becomes
            a heap.
    uses:   InsertHeap()                */
void BuildHeap(List *list)
{
    Position    low;    /* Entries beyond low from a heap  */
    for(low=list->count/2-1;low>=0;low--)
        InsertHeap(list->elem[low],low,list->count,list);
}


/*
    end....
    好累啊!!!
*/                                           

原创粉丝点击