[数据结构]排序的基本概念与基本实现(十一种排序)

本文详细介绍了排序算法的基本概念和分类,包括稳定排序与不稳定排序、内部排序和外部排序。接着详细阐述了11种排序算法:直接插入排序、折半插入排序、冒泡排序、简单选择排序、希尔排序、快速排序、堆排序、二路归并排序、桶排序、基数排序和计数排序,分析了每种排序的基本思想、核心代码实现,并探讨了它们的时间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、排序概念

排序称为分类,就是把一批任意序列的数据记录,按关键字重新排成一个有序的序列。
排序一般又分为以下几种:
(1)稳定排序和不稳定排序
稳定排序:两个相等的数排序前的位置顺序与排序后位置的顺序不变。比如排序前:5,2,5。排序后:2,5,5。
不稳定排序:两个相等的数排序前的位置顺序与排序后位置的顺序颠倒。比如5,8,5,2,9。选择排序中:第一个5先跟2发生了交换。
(2)根据存储设备的不同,分为内部排序和外部排序
内部排序:数据全部存放在计算机的内存储器中进行的排序过程,在此期间没有进行内、外存储器的数据对象。
外部排序:指待排序记录的数量很大,以致内存不能依次容纳全部记录,所以排序的过程中,数据的主要部分存在外存储器上,借助与内存储器逐步调整记录之间的相对位置。在这个过程中,需要不断地在内、外存储器之间进行数据地交换。
稳定排序:直接插入排序、基数排序、归并排序、冒泡排序…
不稳定排序:快速排序、希尔排序、简单选择排序、堆排序…

二、排序的分类


1、直接插入排序:

基本思想:每一个待排序的记录按其排序码关键字的大小插到前面已经排好序的序列。直接插入过程可以理解为:不断建立监察哨,不断更新监察哨的位置
假设一组关键字序列为{48,35,18,45,12,68,33},一共7个记录

在这里插入图片描述
其上就是监察哨地位置变化结果。不断与监察范围的元素比较,范围内的数比监察哨大,就交换。

核心代码实现:

void insertsort(int a[],int n){
   ///从小到大排序
    for(int i=2;i<=n;i++){
   
        a[0]=a[i];///监察哨
        int j=i-1;///监察范围最大值
        while(a[0]<a[j]){
   
            a[j+1]=a[j];
            j--;
        }
        a[j+1]=a[0];
    }
}///时间复杂度:O(n的平方/2)

2、折半插入排序(二分插入排序):

基本思想:类似二分查找,先取一个序列的中间关键字与当前关健字比较,如果相等则查找成功,否则就改变查找区间。但是排序通过查找元素的插入。注意:运用此算法的前提就是一个有序的序列,所以在直接插入排序的基础上再插入。

在这里插入图片描述
核心代码实现:

void insertsort(int a[],int n){
   ///从小到大排序
    int low,high;
    for(int i=2;i<=n;i++){
   
        a[0]=a[i];///暂存a[i]
        low=1;
        high=i-1;
        while(low<=high){
   
            int mid=(low+high)/2;
            if(a[0]<a[mid]) high=mid-1;
            else low=mid+1;
        }
        for(int j=i-1;j>=high+1;j--) a[j+1]=a[j];
        a[high+1]=a[0];
    }
}

3、冒泡排序

基本思想:依次比较两个相邻的元素,如果(从小到大或从大到小)顺序相反就把它们交换。冒泡排序可以理解为,不断交换找最大数(冒泡)、缩小范围继续找次最小,直到所有元素排序完毕。

比如一个无序序列:45 15 68 2.其冒泡排序的简易图如下:
在这里插入图片描述
核心代码实现:

void bubblesort(int a[],int n){
   
    for(int i=1;i<=n-1;i++)///不用遍历到n,因为j+1已经访问了
      for(int j=1;j<=n-i;j++)///缩小范围
        if(a[j+1]<a[j]){
   
           int temp=a[j];
           a[j]=a[j+1];
           a[j+1]=temp;
    }
}///时间复杂度O(n的平方),

4、简单选择排序

基本思想:不断地找出序列中最小的数,然后与当前比较的数进行交换

核心代码实现:

void selectsort(int a[],int n){
   
    for(int i=1;i<=n;i++)
      {
   
          int t=i;
          
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值