C/C++知识点之排序(C语言实现)
小标 2018-09-18 来源 : 阅读 1140 评论 0

摘要:本文主要向大家介绍了C/C++知识点之排序(C语言实现),通过具体的内容向大家展示,希望对大家学习C/C++知识点有所帮助。

本文主要向大家介绍了C/C++知识点之排序(C语言实现),通过具体的内容向大家展示,希望对大家学习C/C++知识点有所帮助。         

读数据结构与算法分析

插入排序

核心:利用的是从位置0到位置P都是已排序的


所以从位置1开始排序,如果当前位置不对,则和前面元素反复交换重新排序

实现
void InsertionSort(ElementType A[], int N)
{
    int i,P;
    ElementType Tmp ;
    for(P = 1;P < N;P++)
    {
        Tmp = A[P] ;
        for(i = P;i > 0 && A[i-1] > Tmp;i--)
            A[i] = A[i-1] ;
        A[i] = Tmp ;
    }
}

希尔排序

使用hk增量序列进行一趟排序后,对每个i都有

A[i] \leq A[i+hk]   

重要性质:一个hk排序的文件在之后的排序中将保持hk排序性

实现

ht = [N / 2]
hk = [hk+1 / 2]

void ShellSort(ElmentType A[], int N)
{
    ElementType Tmp ;
    int i,j,Increment ;
    for(Increment = N/2;Increment > 0;Increment /= 2)
        for(i = Increment;i < N;i++)
        {
            Tmp = A[i] ;
            for(j = i;j <= Increment;j -= Increment)
                if(Tmp < A[j-Increment])
                    A[j] = A[j-Increment] ;
                else 
                    break ;
            A[j] = Tmp ;
        }
}
堆排序

基于原有的二叉堆


建立二叉堆,执行DeleteMax操作,储存至数组(节省空间可以倒序储存在当前数组)

实现
#define LeftChild(i) (2 * i + 1) ;
void Percdown(ElementType A[],int i,int N)
{
    int Child ,i;
    ElementType Tmp ;
    for(Tmp = A[i]; LeftChild(i) < N-1;i = Child)
    {
        Child = LeftChild(i) ;
        if(Tmp < A[Child])
            A[i] = A[Chile] ;
        else
            break ;
    }
    A[i] = Tmp ;
}

void HeapSore(ElementType 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) ;
    }
    
}
归并排序

基本思想是合并两个已排序的表

实现

递归合并

void Msort(ElementType A[],ElementeType TmpArray[],int Left,int Right)
{
    int Center ;
    if(Left < Right)
    {
        Center = (Left + Right) /2 ;
        Msort(A,TmpArray,Left,Right) ;
        Msort(A,TmpArray,Center + 1,Right) ;
        Merge(A,TmpArray,Left,Center + 1,Right) ;
    }
}

驱动程序

void Mergesort(ElementType A[],int N)
{
    ElementType *TmpArray ;
    
    TmpArray = malloc(N * sizeof(ElementType)) ;
    if(TmpArray != NULL)
    {
        Msort(A,TmpArray,0,N-1) ;
        free(TmpArray) ;
    }
    else
        FatalError("内存不足") ;
}


合并函数

void Merge(ElementType A[],ElementType TmpArray[],int Lpos,int Rpos,int RightEnd)
{
    int i,LeftEnd,NumElements,TmpPos ;
    
    LeftEnd = Rpos - 1;
    TmpPos = Lpos ;
    NumElement = 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 < NumElement ;i++,RightEnd--)
        A[RightEnd] = TmpArray[RightEnd] ;
}
快速排序

和归并排序一样都是分治递归算法,在小数组上效率并没有插入排序好


如果S中元素个数是0或1,则返回
取S中任一元素v,称为枢纽元
将S剩余的其它元素,分为两个不相交的集合
返回quicksort(S1),继续选择v,继续quicksort(S2) ;

实现
选取枢纽元

三数中值分割方法

ElementType Median3(ElementType 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] ;
    
}
主函数
#define Cutoff(3) ;

void Qsort(ElementType A[],int Left,int Right)
{
    int i,j ;
    ElementType Pivot ;
    
    if(Left + Cutoff <= Right)
    {
        Pivot = Midian3(A,Left,Right)
        i = Left ; j = Right ;
        for(;;)
        {
            While(A[++i] < Privot){}
            While(A[--j] > Privot){}
            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(ElementType A[],int N)
{
    Qsort(A,0,N-1) ;
}
总结

对于一般的内部排序,选用的方法一般是插入排序、希尔排序和快速排序,根据输入来选择
高度优化的快速排序在对于很少的输入也可能和希尔排序一样快

对于快速排序,选取枢纽元十分关键

堆排序比希尔排序要满
插入排序一般用于较小的或接近排好序的输入
归并排序在主存排序中不如快速排序那么好,但是合并时外部排序的中心思想

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标编程语言C/C+频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 1 不喜欢 | 0
看完这篇文章有何感觉?已经有1人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程