草庐IT

常用排序算法简介

crossoverpptx 2023-03-28 原文

本文介绍几种常用的排序算法:冒泡排序、选择排序、插入排序、希尔排序、归并排序。


冒泡排序

冒泡排序(Bubble Sort):它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序(如从大到小、首字母从A到Z)错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。

实例:

#include <stdio.h>
void bubble_sort(int [],int);

int main()
{
	int i;
	int arr[]={22,34,3,32,82,55,89,50,37,5,64,35,9,70};
    int len=(int)sizeof(arr)/sizeof(*arr);
    bubble_sort(arr,len);
    for(i=0;i<len;i++)
        printf("%d ",arr[i]);

    return 0;
}

void bubble_sort(int arr[],int len)
{
    int i,j,temp;
    for(i=0;i<len-1;i++)
        for(j=0;j<len-1-i;j++)
            if(arr[j]>arr[j+1])
			{
                temp=arr[j];
                arr[j]=arr[j+1];
                arr[j+1]=temp;
            }
}

运行结果:

3 5 9 22 32 34 35 37 50 55 64 70 82 89

选择排序

选择排序(Selection Sort):首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

实例:

#include <stdio.h>
void selection_sort(int [],int);

int main()
{
	int i;
	int arr[]={22,34,3,32,82,55,89,50,37,5,64,35,9,70};
    int len=(int)sizeof(arr)/sizeof(*arr);
    selection_sort(arr,len);
    for(i=0;i<len;i++)
        printf("%d ",arr[i]);

    return 0;
}

void selection_sort(int a[],int len) 
{
    int i,j,temp;
    for(i=0;i<len-1;i++) 
    {
        int min=i;                  // 记录最小值,第一个元素默认最小
        for(j=i+1;j<len;j++)		// 访问未排序的元素
        {
            if(a[j]<a[min])			// 找到目前最小值
                min=j;				// 记录最小值
        }
        if(min!=i)
        {
            temp=a[min];			// 交换两个变量
            a[min]=a[i];
            a[i]=temp;
        }
    }
}

运行结果:

3 5 9 22 32 34 35 37 50 55 64 70 82 89

插入排序

插入排序(英语:Insertion Sort):通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序,因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。

实例:

#include <stdio.h>
void insertion_sort(int [],int);

int main()
{
	int i;
	int arr[]={22,34,3,32,82,55,89,50,37,5,64,35,9,70};
    int len=(int)sizeof(arr)/sizeof(*arr);
    insertion_sort(arr,len);
    for(i=0;i<len;i++)
        printf("%d ",arr[i]);

    return 0;
}

void insertion_sort(int arr[],int len)
{
    int i,j,temp;
    for(i=1;i<len;i++)
	{
        temp=arr[i];
        for(j=i;j>0&&arr[j-1]>temp;j--)
                arr[j]=arr[j-1];
        arr[j]=temp;
    }
}

运行结果:

3 5 9 22 32 34 35 37 50 55 64 70 82 89

希尔排序

希尔排序(Shell Sort):也称递减增量排序算法,是插入排序的一种更高效的改进版本。希尔排序是非稳定排序算法。
希尔排序是基于插入排序的以下两点性质而提出改进方法的:

  • 插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率
  • 但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位

实例

#include <stdio.h>
void shell_sort(int [],int);

int main()
{
	int i;
	int arr[]={22,34,3,32,82,55,89,50,37,5,64,35,9,70};
    int len=(int)sizeof(arr)/sizeof(*arr);
    shell_sort(arr,len);
    for(i=0;i<len;i++)
        printf("%d ",arr[i]);

    return 0;
}

void shell_sort(int arr[],int len)
{
    int gap,i,j;
    int temp;
    for(gap=len>>1;gap>0;gap=gap>>1)
        for(i=gap;i<len;i++)
		{
            temp=arr[i];
            for(j=i-gap;j>=0&&arr[j]>temp;j-=gap)
                arr[j+gap]=arr[j];
            arr[j+gap]=temp;
        }
}

运行结果:

3 5 9 22 32 34 35 37 50 55 64 70 82 89

归并排序

归并排序(Merge Sort):把数据分为两段,从两段中逐个选最小的元素移入新数据段的末尾。
可从上到下或从下到上进行。

实例

迭代法

#include <stdio.h>
#include <stdlib.h>
int mini(int,int);
void merge_sort(int [],int);

int main()
{
	int i;
	int arr[]={22,34,3,32,82,55,89,50,37,5,64,35,9,70};
    int len=(int)sizeof(arr)/sizeof(*arr);
    merge_sort(arr,len);
    for(i=0;i<len;i++)
        printf("%d ",arr[i]);

    return 0;
}

int mini(int x,int y) 
{
    return x<y?x:y;
}

void merge_sort(int arr[],int len)
{
    int *a=arr;
    int *b=(int*)malloc(len*sizeof(int));
	int *temp,seg,start;
    for(seg=1;seg<len;seg+=seg)
	{
        for(start=0;start<len;start+=seg+seg)
		{
            int low=start;
			int mid=mini(start+seg,len);
			int high=mini(start+seg+seg,len);
            int k=low;
            int start1=low;
			int end1=mid;
            int start2=mid;
			int end2=high;
            while(start1<end1&&start2<end2)
                b[k++]=a[start1]<a[start2]?a[start1++]:a[start2++];
            while(start1<end1)
                b[k++]=a[start1++];
            while(start2<end2)
                b[k++]=a[start2++];
        }
        temp=a;
        a=b;
        b=temp;
    }
    if(a!=arr)
	{
        int i;
        for(i=0;i<len;i++)
            b[i]=a[i];
        b=a;
    }
    free(b);
}

递归法

#include <stdio.h>
#include <stdlib.h>
#define N 14
void merge_sort_recursive(int [],int [],int,int);
void merge_sort(int [],const int);

int main()
{
	int i;
	int arr[]={22,34,3,32,82,55,89,50,37,5,64,35,9,70};
    int len=(int)sizeof(arr)/sizeof(*arr);
    merge_sort(arr,len);
    for(i=0;i<len;i++)
        printf("%d ",arr[i]);

    return 0;
}

void merge_sort_recursive(int arr[],int reg[],int start,int end)
{
	int k,len,mid,start1,start2,end1,end2;
    if(start>=end)
        return;
    len=end-start;
	mid=(len>>1)+start;
    start1=start;
	end1=mid;
    start2=mid+1;
	end2=end;
    merge_sort_recursive(arr,reg,start1,end1);
    merge_sort_recursive(arr,reg,start2,end2);
    k=start;
    while(start1<=end1&&start2<=end2)
        reg[k++]=arr[start1]<arr[start2]?arr[start1++]:arr[start2++];
    while(start1<=end1)
        reg[k++]=arr[start1++];
    while(start2<=end2)
        reg[k++]=arr[start2++];
    for(k=start;k<=end;k++)
        arr[k]=reg[k];
}

void merge_sort(int arr[], const int len)
{
    int reg[N];
    merge_sort_recursive(arr,reg,0,len-1);
}

运行结果:

3 5 9 22 32 34 35 37 50 55 64 70 82 89

备注:常用排序算法的时间复杂度和空间复杂度

有关常用排序算法简介的更多相关文章

  1. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  2. 区块链之加解密算法&数字证书 - 2

    目录一.加解密算法数字签名对称加密DES(DataEncryptionStandard)3DES(TripleDES)AES(AdvancedEncryptionStandard)RSA加密法DSA(DigitalSignatureAlgorithm)ECC(EllipticCurvesCryptography)非对称加密签名与加密过程非对称加密的应用对称加密与非对称加密的结合二.数字证书图解一.加解密算法加密简单而言就是通过一种算法将明文信息转换成密文信息,信息的的接收方能够通过密钥对密文信息进行解密获得明文信息的过程。根据加解密的密钥是否相同,算法可以分为对称加密、非对称加密、对称加密和非

  3. HBase Region 简介和建议数量&大小 - 2

    Region是HBase数据管理的基本单位,region有一点像关系型数据的分区。region中存储这用户的真实数据,而为了管理这些数据,HBase使用了RegionSever来管理region。Region的结构hbaseregion的大小设置默认情况下,每个Table起初只有一个Region,随着数据的不断写入,Region会自动进行拆分。刚拆分时,两个子Region都位于当前的RegionServer,但处于负载均衡的考虑,HMaster有可能会将某个Region转移给其他的RegionServer。RegionSplit时机:当1个region中的某个Store下所有StoreFile

  4. ruby-on-rails - 需要帮助最大化多个相似对象中的 3 个因素并适当排序 - 2

    我需要用任何语言编写一个算法,根据3个因素对数组进行排序。我以度假村为例(如Hipmunk)。假设我想去度假。我想要最便宜的地方、最好的评论和最多的景点。但是,显然我找不到在所有3个中都排名第一的方法。Example(assumingthereare20importantattractions):ResortA:$150/night...98/100infavorablereviews...18of20attractionsResortB:$99/night...85/100infavorablereviews...12of20attractionsResortC:$120/night

  5. ruby-on-rails - 在具有 ActiveRecord 条件的相关模型中按字段排序 - 2

    我正在尝试按Rails相关模型中的字段进行排序。我研究的所有解决方案都没有解决如果相关模型被另一个参数过滤?元素模型classItem相关模型:classPriority我正在使用where子句检索项目:@items=Item.where('company_id=?andapproved=?',@company.id,true).all我需要按相关表格中的“位置”列进行排序。问题在于,在优先级模型中,一个项目可能会被多家公司列出。因此,这些职位取决于他们拥有的company_id。当我显示项目时,它是针对一个公司的,按公司内的职位排序。完成此任务的正确方法是什么?感谢您的帮助。PS-我

  6. ruby - 按数字(从大到大)然后按字母(字母顺序)对对象集合进行排序 - 2

    我正在构建一个小部件来显示奥运会的奖牌数。我有一个“国家”对象的集合,其中每个对象都有一个“名称”属性,以及奖牌计数的“金”、“银”、“铜”。列表应该排序:1.首先是奖牌总数2.如果奖牌相同,按类型分割(金>银>铜,即2金>1金+1银)3.如果奖牌和类型相同,则按字母顺序子排序我正在用ruby​​做这件事,但我想语言并不重要。我确实找到了一个解决方案,但如果感觉必须有更优雅的方法来实现它。这是我做的:使用加权奖牌总数创建一个虚拟属性。因此,如果他们有2个金牌和1个银牌,加权总数将为“3.020100”。1金1银1铜为“3.010101”由于我们希望将奖牌数排序为最高的,因此列表按降序排

  7. ruby-on-rails - 在不重新查询数据库的情况下重新排序 Rails 中的事件记录? - 2

    例如,假设我有一个名为Products的模型,并且在ProductsController中,我有以下代码用于product_listView以显示已排序的产品。@products=Product.order(params[:order_by])让我们想象一下,在product_listView中,用户可以使用下拉菜单按价格、评级、重量等进行排序。数据库中的产品不会经常更改。我很难理解的是,每次用户选择新的order_by过滤器时,rails是否必须查询,或者rails是否能够以某种方式缓存事件记录以在服务器端重新排序?有没有一种方法可以编写它,以便在用户排序时rails不会重新查询结果

  8. ruby-on-rails - 如何对对象数组进行排序? - 2

    我有一个对象如下:[{:id=>2,:fname=>"Ron",:lname=>"XXXXX",:photo=>"XXX"},{:id=>3,:fname=>"Dain",:lname=>"XXXX",:photo=>"XXXXXXX"},{:id=>1,:fname=>"Bob",:lname=>"XXXXXX",:photo=>"XXXX"}]我想按fname排序,不区分大小写,所以它会导致编号:1,3,2我该如何排序?我正在尝试:@people.sort!{|x,y|y[:fname]x[:fname]}但这没有任何效果。 最佳答案

  9. ruby - 使用自定义排序首选项对数组进行排序? - 2

    有人可以告诉我如何根据自定义字符串对嵌套数组进行排序吗?比如有没有办法排序:[['Red','Blue'],['Green','Orange'],['Purple','Yellow']]“橙色”、“黄色”,然后是“蓝色”?最终结果如下所示:[['Green','Orange'],['Purple','Yellow'],['Red','Blue']]它不是按字母顺序排序的。我很想知道我是否可以定义要排序的值以实现上述目标。 最佳答案 sort_by对于这种排序总是非常方便:a=[['Red','Blue'],['Green','Ora

  10. Ruby 将对象插入现有的已排序对象数组 - 2

    我有以下现有的Dog对象数组,它们按age属性排序:classDogattr_accessor:agedefinitialize(age)@age=ageendenddogs=[Dog.new(1),Dog.new(4),Dog.new(10)]我现在想插入一条新的狗记录,并将它放在数组中的正确位置。假设我想插入这个对象:another_dog=Dog.new(8)我想把它插入到数组中,让它成为数组中的第三项。这是一个人为的示例,旨在演示我特别想如何将一个项目插入到现有的有序数组中。我意识到我可以创建一个全新的数组并重新对所有对象进行排序,但这不是我的目标。谢谢!

随机推荐