博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
常见内部排序算法以及简要分析
阅读量:5448 次
发布时间:2019-06-15

本文共 3887 字,大约阅读时间需要 12 分钟。

常见内部排序算法以及简要分析

插入排序

插入排序由N-1趟排序组成。对于P=1趟到P=N-1趟,插入排序保证从位置0到位置P上的元素是已排序状态。插入排序基于这样的事实:位置0到位置P-1上的元素是已经排过序的。

void InsertSort( int A[], int N ){    int i,j;    for( i = 1; i < N; i++ )    {        int tmp = A[i];        for( j = i; j >= 1 && A[j-1] > tmp; j--)            A[j] = A[j-1];        A[j] = tmp;    }}

插入排序的平均运行时间是O(N^2)。如果输入数据已经预先排序则运行时间为O(N).

堆排序

堆排序中利用二叉堆,建立N个元素的二叉堆需要花费O(N)的时间,然后执行N次DeleteMin操作。由于每个DeleteMin花费O(logN)时间,因此总的运行时间为O(NlogN).

基本想法是建立一个二叉堆,然后做N次DeleteMin操作

#define LeftChild( i ) (2 * ( i ) + 1 )static void Swap ( int *x,int *y ){    int tmp = *x;    *x = *y;    *y = tmp;    }static void PercDown( int A[], int i, int N ){    int Child;    int Tmp;        for( Tmp = A[i]; LeftChild(i) < N; i = Child )    {        Child = LeftChild(i);        if( Child != N - 1 && A[Child + 1 ] > A[ Child ])            Child ++;        if( Tmp < A[Child])            A[ i ] = A[Child];        else            break;    }        A[i]  = Tmp;}void HeapSort( int A[], int N ){    int  i;        for( i = N/2; i >= 0; i-- )        PercDown(A, i, N);    for (i = N-1; i > 0; i--)    {        Swap(&A[0], &A[i]);        PercDown(A, 0, i);    }}
归并排序

归并排序以O(NlogN)最坏的运行时间运行,而且所使用的比较次数几乎是最优的。

算法的基本操作是:合并两个已排序的表。因为这两个表是已经排序的,所以若将输出放到第三个表中时则该算法可以通过对输入数据一趟排序来完成。

static void Merge( int A[], int TmpArray[], int Lpos,int Rpos,int RightEnd ){    int i, LeftEnd, NumInt, TmpPos;        LeftEnd = Rpos-1;    TmpPos = Lpos;    NumInt = RightEnd-Lpos+1;        while( Lpos <= LeftEnd && Rpos <= RightEnd )    {        if( A[Lpos] <= A[Rpos])            TmpArray[TmpPos++] = A[Lpos++];        else            TmpArray[TmpPos++] = A[Rpos++];    }        while( Lpos <= LeftEnd )        TmpArray[TmpPos++] = A[Lpos++];    while( Rpos <= RightEnd )        TmpArray[TmpPos++] = A[Rpos++];        for(i = 0; i < NumInt; i++,RightEnd--)        A[RightEnd] = TmpArray[RightEnd];}static void MSort( int A[], int TmpArray[], int Left, int Right ){    int Center;        if( Left < Right )    {        Center = (Left+Right)/2;        MSort(A, TmpArray, Left, Center);        MSort(A, TmpArray, Center+1, Right);        Merge(A, TmpArray, Left, Center+1, Right);    }}void MergeSort( int A[], int N ){    int *TmpArray;        TmpArray = malloc(sizeof(int)*N);    if( TmpArray != NULL)    {        MSort(A ,TmpArray, 0, N-1);        free(TmpArray);    }    else        printf("No Space of TmpArray!\n");}

虽然归并排序的运行时间是O(NlogN),但是它很难用于主存排序,主要问题在于合并两个排血的表需要线性附加内存,在整个算法中还需要花费将数据拷贝到临时数组再拷贝回来这样的操作中,其结果严重的放慢了排序的速度。然而,合并的例程是大多数外部排序算法的基石。

快速排序

快速排序是实践中最快的已知排序算法,平均运行时间是O(NlogN)。基本算法由以下简单的四步组成:

1.如果S中元素个数是0或者1,则返回。

2.取S中任一元素v,称之为枢纽元(pivot)
3.将S-{v}(S中的其余元素)分成两个不相交的集合:S1中包含的是小于v的元素,S2中包含的是大于v的元素
4.返回{quicksort(S1)}后,继而quicksort(S2)

#define Cutoff (3)static void InsertionSort(int* NewStart ,int N){    }static void Swap ( int *x,int *y ){    int tmp = *x;    *x = *y;    *y = tmp;    }static int Median3( int A[], int Left, int Right ){    int Center = (Left+Right)/2;        if( A[Left] > A[Center])        Swap(&A[Left], &A[Center]);    if( A[Left] > A[Right] )        Swap(&A[Left], &A[Right]);    if( A[Center] > A[Right])        Swap(&A[Center], &A[Right]);        Swap(&A[Center], &A[Right - 1]);    return A[Right - 1];}static void Qsort( int A[], int Left, int Right ){    int i,j;    int Pivot;    if( Left + Cutoff <= Right )    {        Pivot = Median3(A, Left, Right);        i = Left;        j = Right-1;                for( ;;)        {            while(A[++i] < Pivot){};            while(A[++j] > Pivot){};            if(i < j )                Swap(&A[i], &A[j]);            else                break;        }        Swap(&A[i], &A[Right-1]);                Qsort(A, Left, i-1);        Qsort(A, i+1, Right);    }    else    {        InsertionSort(A + Left, Right - Left + 1);    }    }void QuickSort( int A[], int N ){    Qsort(A, 0, N-1);}

转载于:https://www.cnblogs.com/evansyang/p/5954343.html

你可能感兴趣的文章
【杂谈】用了几千年的就是有用的吗?
查看>>
比酒量|2012年蓝桥杯B组题解析第三题-fishers
查看>>
linux 初识
查看>>
Eclipse 修改项目名称
查看>>
d3基础图形模板笔记
查看>>
《凉州曲》——吴践道
查看>>
第03次作业-栈和队列
查看>>
[SDOI2015]约数个数和
查看>>
关于简单的gridview学习笔记
查看>>
ES6学习--搭建环境
查看>>
技术网站收藏
查看>>
插上翅膀,让Excel飞起来——xlwings(四)
查看>>
【Python】排列组合itertools & 集合set
查看>>
优秀的JavaScript开发框架
查看>>
“机器人”来了,你可能没有时间思考变与不变了
查看>>
22 广播小小总结
查看>>
android 之 Dialog
查看>>
127 Word Ladder
查看>>
js获取倒计时
查看>>
loadrunner安装过程中的,注册表问题
查看>>